From 7200de3c29add5971ae2029411ec6dba8a3bdadc Mon Sep 17 00:00:00 2001 From: Jing Yu Date: Tue, 22 Feb 2011 19:55:38 -0800 Subject: [PATCH] Add mpeg4 benchmark Change-Id: Id8241159b686f014e4c6c378efe2f69a2ef8b240 --- mpeg4/bench.mk | 134 + mpeg4/data/dance_100frame.avi | Bin 0 -> 2747986 bytes mpeg4/src/COPYING | 504 + mpeg4/src/CREDITS | 45 + mpeg4/src/Changelog | 368 + mpeg4/src/Doxyfile | 1038 +++ mpeg4/src/INSTALL | 14 + mpeg4/src/MAINTAINERS | 220 + mpeg4/src/Makefile | 217 + mpeg4/src/README | 19 + mpeg4/src/berrno.h | 44 + mpeg4/src/build_avopt | 9 + mpeg4/src/clean-diff | 11 + mpeg4/src/cmdutils.c | 135 + mpeg4/src/cmdutils.h | 34 + mpeg4/src/common.mak | 101 + mpeg4/src/config.h | 190 + mpeg4/src/config.mak | 213 + mpeg4/src/configure | 2097 +++++ mpeg4/src/cws2fws.c | 126 + mpeg4/src/doc/.cvsignore | 8 + mpeg4/src/doc/Makefile | 18 + mpeg4/src/doc/TODO | 74 + mpeg4/src/doc/faq.texi | 220 + mpeg4/src/doc/ffmpeg-doc.texi | 1370 +++ ...g_powerpc_performance_evaluation_howto.txt | 163 + mpeg4/src/doc/ffplay-doc.texi | 110 + mpeg4/src/doc/ffserver-doc.texi | 224 + mpeg4/src/doc/ffserver.conf | 349 + mpeg4/src/doc/hooks.texi | 49 + mpeg4/src/doc/optimization.txt | 158 + mpeg4/src/doc/texi2pod.pl | 427 + mpeg4/src/ffinstall.nsi | 75 + mpeg4/src/ffmpeg.c | 4221 +++++++++ mpeg4/src/ffplay.c | 2489 +++++ mpeg4/src/ffserver.c | 4599 ++++++++++ mpeg4/src/ffserver.h | 8 + mpeg4/src/libavcodec/.cvsignore | 6 + mpeg4/src/libavcodec/4xm.c | 753 ++ mpeg4/src/libavcodec/8bps.c | 234 + mpeg4/src/libavcodec/Makefile | 476 + mpeg4/src/libavcodec/a52dec.c | 255 + mpeg4/src/libavcodec/aasc.c | 174 + mpeg4/src/libavcodec/ac3.h | 63 + mpeg4/src/libavcodec/ac3dec.c | 182 + mpeg4/src/libavcodec/ac3enc.c | 1602 ++++ mpeg4/src/libavcodec/ac3tab.h | 149 + mpeg4/src/libavcodec/adpcm.c | 1193 +++ mpeg4/src/libavcodec/adx.c | 410 + mpeg4/src/libavcodec/alac.c | 849 ++ mpeg4/src/libavcodec/allcodecs.c | 655 ++ mpeg4/src/libavcodec/alpha/asm.h | 189 + mpeg4/src/libavcodec/alpha/dsputil_alpha.c | 360 + .../src/libavcodec/alpha/dsputil_alpha_asm.S | 283 + mpeg4/src/libavcodec/alpha/motion_est_alpha.c | 343 + .../src/libavcodec/alpha/motion_est_mvi_asm.S | 183 + mpeg4/src/libavcodec/alpha/mpegvideo_alpha.c | 145 + mpeg4/src/libavcodec/alpha/regdef.h | 45 + .../src/libavcodec/alpha/simple_idct_alpha.c | 306 + mpeg4/src/libavcodec/amr.c | 664 ++ mpeg4/src/libavcodec/apiexample.c | 437 + mpeg4/src/libavcodec/armv4l/dsputil_arm.c | 246 + mpeg4/src/libavcodec/armv4l/dsputil_arm_s.S | 694 ++ mpeg4/src/libavcodec/armv4l/dsputil_iwmmxt.c | 186 + .../libavcodec/armv4l/dsputil_iwmmxt_rnd.h | 1093 +++ mpeg4/src/libavcodec/armv4l/jrevdct_arm.S | 386 + mpeg4/src/libavcodec/armv4l/mpegvideo_arm.c | 31 + .../src/libavcodec/armv4l/mpegvideo_iwmmxt.c | 99 + mpeg4/src/libavcodec/armv4l/simple_idct_arm.S | 485 + mpeg4/src/libavcodec/asv1.c | 647 ++ mpeg4/src/libavcodec/avcodec.h | 2567 ++++++ mpeg4/src/libavcodec/avs.c | 158 + mpeg4/src/libavcodec/beosthread.c | 180 + mpeg4/src/libavcodec/bitstream.c | 293 + mpeg4/src/libavcodec/bitstream.h | 873 ++ mpeg4/src/libavcodec/bmp.c | 251 + mpeg4/src/libavcodec/cabac.c | 234 + mpeg4/src/libavcodec/cabac.h | 429 + mpeg4/src/libavcodec/cinepak.c | 451 + mpeg4/src/libavcodec/cljr.c | 156 + mpeg4/src/libavcodec/cook.c | 1307 +++ mpeg4/src/libavcodec/cookdata.h | 557 ++ mpeg4/src/libavcodec/cscd.c | 262 + mpeg4/src/libavcodec/cyuv.c | 188 + mpeg4/src/libavcodec/dct-test.c | 516 ++ mpeg4/src/libavcodec/dpcm.c | 333 + mpeg4/src/libavcodec/dsputil.c | 4116 +++++++++ mpeg4/src/libavcodec/dsputil.h | 638 ++ mpeg4/src/libavcodec/dtsdec.c | 320 + mpeg4/src/libavcodec/dv.c | 1147 +++ mpeg4/src/libavcodec/dvbsub.c | 443 + mpeg4/src/libavcodec/dvbsubdec.c | 1631 ++++ mpeg4/src/libavcodec/dvdata.h | 2665 ++++++ mpeg4/src/libavcodec/dvdsub.c | 478 + mpeg4/src/libavcodec/dvdsubenc.c | 248 + mpeg4/src/libavcodec/error_resilience.c | 1028 +++ mpeg4/src/libavcodec/eval.c | 226 + mpeg4/src/libavcodec/faac.c | 131 + mpeg4/src/libavcodec/faad.c | 330 + mpeg4/src/libavcodec/faandct.c | 218 + mpeg4/src/libavcodec/faandct.h | 31 + mpeg4/src/libavcodec/fdctref.c | 158 + mpeg4/src/libavcodec/fft-test.c | 277 + mpeg4/src/libavcodec/fft.c | 266 + mpeg4/src/libavcodec/ffv1.c | 1037 +++ mpeg4/src/libavcodec/flac.c | 779 ++ mpeg4/src/libavcodec/flicvideo.c | 744 ++ mpeg4/src/libavcodec/fraps.c | 248 + mpeg4/src/libavcodec/g726.c | 424 + mpeg4/src/libavcodec/golomb.c | 154 + mpeg4/src/libavcodec/golomb.h | 469 + mpeg4/src/libavcodec/h261.c | 1047 +++ mpeg4/src/libavcodec/h261data.h | 136 + mpeg4/src/libavcodec/h263.c | 6276 +++++++++++++ mpeg4/src/libavcodec/h263data.h | 285 + mpeg4/src/libavcodec/h263dec.c | 895 ++ mpeg4/src/libavcodec/h264.c | 8090 +++++++++++++++++ mpeg4/src/libavcodec/h264data.h | 1240 +++ mpeg4/src/libavcodec/h264idct.c | 166 + mpeg4/src/libavcodec/huffyuv.c | 1270 +++ mpeg4/src/libavcodec/i386/cputest.c | 131 + .../i386/dsputil_h264_template_mmx.c | 324 + mpeg4/src/libavcodec/i386/dsputil_mmx.c | 3154 +++++++ mpeg4/src/libavcodec/i386/dsputil_mmx_avg.h | 820 ++ mpeg4/src/libavcodec/i386/dsputil_mmx_rnd.h | 590 ++ mpeg4/src/libavcodec/i386/fdct_mmx.c | 562 ++ mpeg4/src/libavcodec/i386/fft_3dn.c | 136 + mpeg4/src/libavcodec/i386/fft_3dn2.c | 136 + mpeg4/src/libavcodec/i386/fft_sse.c | 140 + mpeg4/src/libavcodec/i386/h264dsp_mmx.c | 1433 +++ mpeg4/src/libavcodec/i386/idct_mmx.c | 600 ++ mpeg4/src/libavcodec/i386/idct_mmx_xvid.c | 534 ++ mpeg4/src/libavcodec/i386/mmx.h | 285 + mpeg4/src/libavcodec/i386/motion_est_mmx.c | 406 + mpeg4/src/libavcodec/i386/mpegvideo_mmx.c | 723 ++ .../libavcodec/i386/mpegvideo_mmx_template.c | 345 + mpeg4/src/libavcodec/i386/simple_idct_mmx.c | 1314 +++ mpeg4/src/libavcodec/i386/snowdsp_mmx.c | 917 ++ mpeg4/src/libavcodec/i386/vp3dsp_mmx.c | 322 + mpeg4/src/libavcodec/i386/vp3dsp_sse2.c | 825 ++ mpeg4/src/libavcodec/idcinvideo.c | 270 + mpeg4/src/libavcodec/imgconvert.c | 2592 ++++++ mpeg4/src/libavcodec/imgconvert_template.h | 857 ++ mpeg4/src/libavcodec/imgresample.c | 901 ++ mpeg4/src/libavcodec/indeo2.c | 219 + mpeg4/src/libavcodec/indeo2data.h | 113 + mpeg4/src/libavcodec/indeo3.c | 1151 +++ mpeg4/src/libavcodec/indeo3data.h | 2315 +++++ mpeg4/src/libavcodec/internal.h | 12 + mpeg4/src/libavcodec/interplayvideo.c | 962 ++ mpeg4/src/libavcodec/jfdctfst.c | 305 + mpeg4/src/libavcodec/jfdctint.c | 373 + mpeg4/src/libavcodec/jpeg_ls.c | 843 ++ mpeg4/src/libavcodec/jrevdct.c | 1126 +++ mpeg4/src/libavcodec/kmvc.c | 394 + mpeg4/src/libavcodec/lcl.c | 922 ++ mpeg4/src/libavcodec/liba52/a52.h | 73 + mpeg4/src/libavcodec/liba52/a52_internal.h | 162 + mpeg4/src/libavcodec/liba52/a52_util.h | 32 + mpeg4/src/libavcodec/liba52/bit_allocate.c | 260 + mpeg4/src/libavcodec/liba52/bitstream.c | 91 + mpeg4/src/libavcodec/liba52/bitstream.h | 77 + mpeg4/src/libavcodec/liba52/crc.c | 73 + mpeg4/src/libavcodec/liba52/downmix.c | 679 ++ mpeg4/src/libavcodec/liba52/imdct.c | 411 + mpeg4/src/libavcodec/liba52/mm_accel.h | 42 + mpeg4/src/libavcodec/liba52/parse.c | 939 ++ mpeg4/src/libavcodec/liba52/resample.c | 43 + mpeg4/src/libavcodec/liba52/resample_c.c | 183 + mpeg4/src/libavcodec/liba52/resample_mmx.c | 518 ++ mpeg4/src/libavcodec/liba52/tables.h | 246 + mpeg4/src/libavcodec/libgsm.c | 95 + mpeg4/src/libavcodec/libpostproc/Makefile | 28 + mpeg4/src/libavcodec/libpostproc/mangle.h | 30 + .../src/libavcodec/libpostproc/postprocess.c | 1158 +++ .../src/libavcodec/libpostproc/postprocess.h | 82 + .../postprocess_altivec_template.c | 1196 +++ .../libpostproc/postprocess_internal.h | 170 + .../libpostproc/postprocess_template.c | 3847 ++++++++ mpeg4/src/libavcodec/loco.c | 285 + mpeg4/src/libavcodec/lzo.c | 224 + mpeg4/src/libavcodec/lzo.h | 14 + mpeg4/src/libavcodec/mace.c | 454 + mpeg4/src/libavcodec/mdct.c | 175 + mpeg4/src/libavcodec/mdec.c | 268 + mpeg4/src/libavcodec/mem.c | 135 + mpeg4/src/libavcodec/mjpeg.c | 2448 +++++ mpeg4/src/libavcodec/mlib/dsputil_mlib.c | 462 + mpeg4/src/libavcodec/mmvideo.c | 204 + mpeg4/src/libavcodec/motion_est.c | 2115 +++++ mpeg4/src/libavcodec/motion_est_template.c | 1101 +++ mpeg4/src/libavcodec/motion_test.c | 138 + mpeg4/src/libavcodec/mp3lameaudio.c | 219 + mpeg4/src/libavcodec/mpeg12.c | 3289 +++++++ mpeg4/src/libavcodec/mpeg12data.h | 447 + mpeg4/src/libavcodec/mpeg4data.h | 401 + mpeg4/src/libavcodec/mpegaudio.c | 799 ++ mpeg4/src/libavcodec/mpegaudio.h | 86 + mpeg4/src/libavcodec/mpegaudiodec.c | 2886 ++++++ mpeg4/src/libavcodec/mpegaudiodectab.h | 774 ++ mpeg4/src/libavcodec/mpegaudiotab.h | 98 + mpeg4/src/libavcodec/mpegvideo.c | 6747 ++++++++++++++ mpeg4/src/libavcodec/mpegvideo.h | 1000 ++ mpeg4/src/libavcodec/msmpeg4.c | 2012 ++++ mpeg4/src/libavcodec/msmpeg4data.h | 2004 ++++ mpeg4/src/libavcodec/msrle.c | 307 + mpeg4/src/libavcodec/msvideo1.c | 347 + mpeg4/src/libavcodec/nuv.c | 214 + mpeg4/src/libavcodec/oggtheora.c | 133 + mpeg4/src/libavcodec/oggvorbis.c | 361 + mpeg4/src/libavcodec/opt.c | 301 + mpeg4/src/libavcodec/opt.h | 61 + mpeg4/src/libavcodec/os2thread.c | 148 + mpeg4/src/libavcodec/parser.c | 1012 +++ mpeg4/src/libavcodec/pcm.c | 546 ++ mpeg4/src/libavcodec/png.c | 949 ++ mpeg4/src/libavcodec/pnm.c | 594 ++ mpeg4/src/libavcodec/ppc/dsputil_altivec.c | 1773 ++++ mpeg4/src/libavcodec/ppc/dsputil_altivec.h | 97 + .../src/libavcodec/ppc/dsputil_h264_altivec.c | 266 + .../ppc/dsputil_h264_template_altivec.c | 639 ++ mpeg4/src/libavcodec/ppc/dsputil_ppc.c | 359 + mpeg4/src/libavcodec/ppc/dsputil_ppc.h | 164 + .../src/libavcodec/ppc/dsputil_snow_altivec.c | 807 ++ mpeg4/src/libavcodec/ppc/fdct_altivec.c | 498 + mpeg4/src/libavcodec/ppc/fft_altivec.c | 247 + mpeg4/src/libavcodec/ppc/gcc_fixes.h | 103 + mpeg4/src/libavcodec/ppc/gmc_altivec.c | 172 + mpeg4/src/libavcodec/ppc/idct_altivec.c | 249 + mpeg4/src/libavcodec/ppc/mpegvideo_altivec.c | 649 ++ mpeg4/src/libavcodec/ppc/mpegvideo_ppc.c | 89 + mpeg4/src/libavcodec/ps2/dsputil_mmi.c | 161 + mpeg4/src/libavcodec/ps2/idct_mmi.c | 348 + mpeg4/src/libavcodec/ps2/mmi.h | 152 + mpeg4/src/libavcodec/ps2/mpegvideo_mmi.c | 87 + mpeg4/src/libavcodec/pthread.c | 168 + mpeg4/src/libavcodec/qdm2.c | 2040 +++++ mpeg4/src/libavcodec/qdm2data.h | 528 ++ mpeg4/src/libavcodec/qdrw.c | 158 + mpeg4/src/libavcodec/qpeg.c | 322 + mpeg4/src/libavcodec/qtrle.c | 628 ++ mpeg4/src/libavcodec/ra144.c | 517 ++ mpeg4/src/libavcodec/ra144.h | 2426 +++++ mpeg4/src/libavcodec/ra288.c | 256 + mpeg4/src/libavcodec/ra288.h | 203 + mpeg4/src/libavcodec/rangecoder.c | 179 + mpeg4/src/libavcodec/rangecoder.h | 125 + mpeg4/src/libavcodec/ratecontrol.c | 920 ++ mpeg4/src/libavcodec/raw.c | 192 + mpeg4/src/libavcodec/resample.c | 247 + mpeg4/src/libavcodec/resample2.c | 272 + mpeg4/src/libavcodec/roqvideo.c | 472 + mpeg4/src/libavcodec/rpza.c | 290 + mpeg4/src/libavcodec/rtjpeg.c | 162 + mpeg4/src/libavcodec/rtjpeg.h | 19 + mpeg4/src/libavcodec/rv10.c | 788 ++ mpeg4/src/libavcodec/sh4/dsputil_align.c | 428 + mpeg4/src/libavcodec/sh4/dsputil_sh4.c | 118 + mpeg4/src/libavcodec/sh4/idct_sh4.c | 364 + mpeg4/src/libavcodec/sh4/qpel.c | 1649 ++++ mpeg4/src/libavcodec/shorten.c | 521 ++ mpeg4/src/libavcodec/simple_idct.c | 585 ++ mpeg4/src/libavcodec/simple_idct.h | 36 + mpeg4/src/libavcodec/smacker.c | 720 ++ mpeg4/src/libavcodec/smc.c | 491 + mpeg4/src/libavcodec/snow.c | 4567 ++++++++++ mpeg4/src/libavcodec/snow.h | 162 + mpeg4/src/libavcodec/sonic.c | 975 ++ mpeg4/src/libavcodec/sp5x.h | 330 + mpeg4/src/libavcodec/sparc/dsputil_vis.c | 4091 +++++++++ mpeg4/src/libavcodec/sparc/vis.h | 328 + mpeg4/src/libavcodec/svq1.c | 1425 +++ mpeg4/src/libavcodec/svq1_cb.h | 1578 ++++ mpeg4/src/libavcodec/svq1_vlc.h | 261 + mpeg4/src/libavcodec/svq3.c | 1012 +++ mpeg4/src/libavcodec/swscale.h | 38 + mpeg4/src/libavcodec/truemotion1.c | 921 ++ mpeg4/src/libavcodec/truemotion1data.h | 813 ++ mpeg4/src/libavcodec/truemotion2.c | 891 ++ mpeg4/src/libavcodec/truespeech.c | 377 + mpeg4/src/libavcodec/truespeech_data.h | 136 + mpeg4/src/libavcodec/tscc.c | 346 + mpeg4/src/libavcodec/tta.c | 446 + mpeg4/src/libavcodec/ulti.c | 426 + mpeg4/src/libavcodec/ulti_cb.h | 4098 +++++++++ mpeg4/src/libavcodec/utils.c | 1390 +++ mpeg4/src/libavcodec/vc9.c | 2675 ++++++ mpeg4/src/libavcodec/vc9data.h | 406 + mpeg4/src/libavcodec/vcr1.c | 188 + mpeg4/src/libavcodec/vmdav.c | 581 ++ mpeg4/src/libavcodec/vorbis.c | 1720 ++++ mpeg4/src/libavcodec/vorbis.h | 2256 +++++ mpeg4/src/libavcodec/vp3.c | 2919 ++++++ mpeg4/src/libavcodec/vp3data.h | 3158 +++++++ mpeg4/src/libavcodec/vp3dsp.c | 311 + mpeg4/src/libavcodec/vqavideo.c | 608 ++ mpeg4/src/libavcodec/w32thread.c | 134 + mpeg4/src/libavcodec/wmadata.h | 1412 +++ mpeg4/src/libavcodec/wmadec.c | 1344 +++ mpeg4/src/libavcodec/wmv2.c | 855 ++ mpeg4/src/libavcodec/wnv1.c | 144 + mpeg4/src/libavcodec/ws-snd1.c | 145 + mpeg4/src/libavcodec/x264.c | 287 + mpeg4/src/libavcodec/xan.c | 490 + mpeg4/src/libavcodec/xl.c | 138 + mpeg4/src/libavcodec/xvid_rc.c | 146 + mpeg4/src/libavcodec/xvidff.c | 764 ++ mpeg4/src/libavcodec/xvmcvideo.c | 316 + mpeg4/src/libavcodec/zmbv.c | 692 ++ mpeg4/src/libavformat/.cvsignore | 6 + mpeg4/src/libavformat/4xm.c | 335 + mpeg4/src/libavformat/Makefile | 100 + mpeg4/src/libavformat/adtsenc.c | 127 + mpeg4/src/libavformat/aiff.c | 482 + mpeg4/src/libavformat/allformats.c | 157 + mpeg4/src/libavformat/amr.c | 250 + mpeg4/src/libavformat/asf-enc.c | 861 ++ mpeg4/src/libavformat/asf.c | 869 ++ mpeg4/src/libavformat/asf.h | 280 + mpeg4/src/libavformat/au.c | 213 + mpeg4/src/libavformat/audio.c | 355 + mpeg4/src/libavformat/avformat.h | 741 ++ mpeg4/src/libavformat/avi.h | 43 + mpeg4/src/libavformat/avidec.c | 938 ++ mpeg4/src/libavformat/avienc.c | 781 ++ mpeg4/src/libavformat/avio.c | 190 + mpeg4/src/libavformat/avio.h | 182 + mpeg4/src/libavformat/aviobuf.c | 793 ++ mpeg4/src/libavformat/avs.c | 238 + mpeg4/src/libavformat/barpainet.c | 25 + mpeg4/src/libavformat/barpainet.h | 25 + mpeg4/src/libavformat/beosaudio.cpp | 463 + mpeg4/src/libavformat/crc.c | 136 + mpeg4/src/libavformat/cutils.c | 273 + mpeg4/src/libavformat/daud.c | 63 + mpeg4/src/libavformat/dc1394.c | 197 + mpeg4/src/libavformat/dv.c | 1037 +++ mpeg4/src/libavformat/dv.h | 35 + mpeg4/src/libavformat/dv1394.c | 244 + mpeg4/src/libavformat/dv1394.h | 355 + mpeg4/src/libavformat/electronicarts.c | 295 + mpeg4/src/libavformat/ffm.c | 798 ++ mpeg4/src/libavformat/file.c | 138 + mpeg4/src/libavformat/flic.c | 225 + mpeg4/src/libavformat/flvdec.c | 229 + mpeg4/src/libavformat/flvenc.c | 191 + mpeg4/src/libavformat/framehook.c | 119 + mpeg4/src/libavformat/framehook.h | 29 + mpeg4/src/libavformat/gif.c | 440 + mpeg4/src/libavformat/gifdec.c | 640 ++ mpeg4/src/libavformat/grab.c | 863 ++ mpeg4/src/libavformat/grab_bktr.c | 331 + mpeg4/src/libavformat/http.c | 332 + mpeg4/src/libavformat/idcin.c | 305 + mpeg4/src/libavformat/idroq.c | 295 + mpeg4/src/libavformat/img.c | 409 + mpeg4/src/libavformat/img2.c | 435 + mpeg4/src/libavformat/ipmovie.c | 630 ++ mpeg4/src/libavformat/jpeg.c | 238 + mpeg4/src/libavformat/matroska.c | 2657 ++++++ mpeg4/src/libavformat/mm.c | 216 + mpeg4/src/libavformat/mmf.c | 338 + mpeg4/src/libavformat/mov.c | 2182 +++++ mpeg4/src/libavformat/mov.h | 13 + mpeg4/src/libavformat/movenc.c | 1844 ++++ mpeg4/src/libavformat/mp3.c | 400 + mpeg4/src/libavformat/mpeg.c | 1797 ++++ mpeg4/src/libavformat/mpegts.c | 1530 ++++ mpeg4/src/libavformat/mpegts.h | 61 + mpeg4/src/libavformat/mpegtsenc.c | 676 ++ mpeg4/src/libavformat/mpjpeg.c | 73 + mpeg4/src/libavformat/nsvdec.c | 761 ++ mpeg4/src/libavformat/nut.c | 1468 +++ mpeg4/src/libavformat/nuv.c | 245 + mpeg4/src/libavformat/ogg.c | 276 + mpeg4/src/libavformat/ogg2.c | 658 ++ mpeg4/src/libavformat/ogg2.h | 87 + mpeg4/src/libavformat/oggparseflac.c | 77 + mpeg4/src/libavformat/oggparsetheora.c | 130 + mpeg4/src/libavformat/oggparsevorbis.c | 203 + mpeg4/src/libavformat/os_support.c | 67 + mpeg4/src/libavformat/os_support.h | 32 + mpeg4/src/libavformat/png.c | 887 ++ mpeg4/src/libavformat/pnm.c | 476 + mpeg4/src/libavformat/psxstr.c | 368 + mpeg4/src/libavformat/qtpalette.h | 295 + mpeg4/src/libavformat/raw.c | 819 ++ mpeg4/src/libavformat/rm.c | 1102 +++ mpeg4/src/libavformat/rtp.c | 879 ++ mpeg4/src/libavformat/rtp.h | 125 + mpeg4/src/libavformat/rtpproto.c | 300 + mpeg4/src/libavformat/rtsp.c | 1429 +++ mpeg4/src/libavformat/rtsp.h | 96 + mpeg4/src/libavformat/rtspcodes.h | 11 + mpeg4/src/libavformat/segafilm.c | 314 + mpeg4/src/libavformat/sgi.c | 458 + mpeg4/src/libavformat/sierravmd.c | 332 + mpeg4/src/libavformat/smacker.c | 343 + mpeg4/src/libavformat/sol.c | 163 + mpeg4/src/libavformat/swf.c | 934 ++ mpeg4/src/libavformat/tcp.c | 230 + mpeg4/src/libavformat/tta.c | 138 + mpeg4/src/libavformat/udp.c | 501 + mpeg4/src/libavformat/utils.c | 3283 +++++++ mpeg4/src/libavformat/v4l2.c | 538 ++ mpeg4/src/libavformat/voc.c | 296 + mpeg4/src/libavformat/voc.h | 32 + mpeg4/src/libavformat/wav.c | 426 + mpeg4/src/libavformat/wc3movie.c | 398 + mpeg4/src/libavformat/westwood.c | 385 + mpeg4/src/libavformat/yuv.c | 159 + mpeg4/src/libavformat/yuv4mpeg.c | 415 + mpeg4/src/libavutil/Makefile | 33 + mpeg4/src/libavutil/avutil.h | 79 + mpeg4/src/libavutil/bswap.h | 157 + mpeg4/src/libavutil/common.h | 636 ++ mpeg4/src/libavutil/crc.c | 80 + mpeg4/src/libavutil/crc.h | 15 + mpeg4/src/libavutil/eval.c | 226 + mpeg4/src/libavutil/integer.c | 221 + mpeg4/src/libavutil/integer.h | 47 + mpeg4/src/libavutil/intfloat_readwrite.c | 98 + mpeg4/src/libavutil/intfloat_readwrite.h | 19 + mpeg4/src/libavutil/mathematics.c | 132 + mpeg4/src/libavutil/mathematics.h | 31 + mpeg4/src/libavutil/rational.c | 110 + mpeg4/src/libavutil/rational.h | 69 + mpeg4/src/output_example.c | 528 ++ mpeg4/src/pktdumper.c | 97 + mpeg4/src/qt-faststart.c | 311 + mpeg4/src/tests/.cvsignore | 16 + mpeg4/src/tests/Makefile | 77 + mpeg4/src/tests/audiogen.c | 168 + mpeg4/src/tests/dsptest.c | 178 + mpeg4/src/tests/ffmpeg.regression.ref | 170 + mpeg4/src/tests/ffserver.regression.ref | 10 + mpeg4/src/tests/lena.pnm | 109 + mpeg4/src/tests/libav.regression.ref | 106 + mpeg4/src/tests/regression.sh | 757 ++ mpeg4/src/tests/rotozoom.c | 289 + mpeg4/src/tests/rotozoom.regression.ref | 170 + mpeg4/src/tests/server-regression.sh | 50 + mpeg4/src/tests/test.conf | 306 + mpeg4/src/tests/tiny_psnr.c | 148 + mpeg4/src/tests/videogen.c | 278 + mpeg4/src/unwrap-diff | 2 + mpeg4/src/vhook/Makefile | 50 + mpeg4/src/vhook/drawtext.c | 525 ++ mpeg4/src/vhook/fish.c | 356 + mpeg4/src/vhook/imlib2.c | 281 + mpeg4/src/vhook/null.c | 78 + mpeg4/src/vhook/ppm.c | 332 + mpeg4/src/vhook/watermark.c | 588 ++ mpeg4/src/xvmc_render.h | 47 + 454 files changed, 278138 insertions(+) create mode 100644 mpeg4/bench.mk create mode 100644 mpeg4/data/dance_100frame.avi create mode 100644 mpeg4/src/COPYING create mode 100644 mpeg4/src/CREDITS create mode 100644 mpeg4/src/Changelog create mode 100644 mpeg4/src/Doxyfile create mode 100644 mpeg4/src/INSTALL create mode 100644 mpeg4/src/MAINTAINERS create mode 100644 mpeg4/src/Makefile create mode 100644 mpeg4/src/README create mode 100644 mpeg4/src/berrno.h create mode 100755 mpeg4/src/build_avopt create mode 100755 mpeg4/src/clean-diff create mode 100644 mpeg4/src/cmdutils.c create mode 100644 mpeg4/src/cmdutils.h create mode 100644 mpeg4/src/common.mak create mode 100644 mpeg4/src/config.h create mode 100644 mpeg4/src/config.mak create mode 100755 mpeg4/src/configure create mode 100644 mpeg4/src/cws2fws.c create mode 100644 mpeg4/src/doc/.cvsignore create mode 100644 mpeg4/src/doc/Makefile create mode 100644 mpeg4/src/doc/TODO create mode 100644 mpeg4/src/doc/faq.texi create mode 100644 mpeg4/src/doc/ffmpeg-doc.texi create mode 100644 mpeg4/src/doc/ffmpeg_powerpc_performance_evaluation_howto.txt create mode 100644 mpeg4/src/doc/ffplay-doc.texi create mode 100644 mpeg4/src/doc/ffserver-doc.texi create mode 100644 mpeg4/src/doc/ffserver.conf create mode 100644 mpeg4/src/doc/hooks.texi create mode 100644 mpeg4/src/doc/optimization.txt create mode 100755 mpeg4/src/doc/texi2pod.pl create mode 100644 mpeg4/src/ffinstall.nsi create mode 100644 mpeg4/src/ffmpeg.c create mode 100644 mpeg4/src/ffplay.c create mode 100644 mpeg4/src/ffserver.c create mode 100644 mpeg4/src/ffserver.h create mode 100644 mpeg4/src/libavcodec/.cvsignore create mode 100644 mpeg4/src/libavcodec/4xm.c create mode 100644 mpeg4/src/libavcodec/8bps.c create mode 100644 mpeg4/src/libavcodec/Makefile create mode 100644 mpeg4/src/libavcodec/a52dec.c create mode 100644 mpeg4/src/libavcodec/aasc.c create mode 100644 mpeg4/src/libavcodec/ac3.h create mode 100644 mpeg4/src/libavcodec/ac3dec.c create mode 100644 mpeg4/src/libavcodec/ac3enc.c create mode 100644 mpeg4/src/libavcodec/ac3tab.h create mode 100644 mpeg4/src/libavcodec/adpcm.c create mode 100644 mpeg4/src/libavcodec/adx.c create mode 100644 mpeg4/src/libavcodec/alac.c create mode 100644 mpeg4/src/libavcodec/allcodecs.c create mode 100644 mpeg4/src/libavcodec/alpha/asm.h create mode 100644 mpeg4/src/libavcodec/alpha/dsputil_alpha.c create mode 100644 mpeg4/src/libavcodec/alpha/dsputil_alpha_asm.S create mode 100644 mpeg4/src/libavcodec/alpha/motion_est_alpha.c create mode 100644 mpeg4/src/libavcodec/alpha/motion_est_mvi_asm.S create mode 100644 mpeg4/src/libavcodec/alpha/mpegvideo_alpha.c create mode 100644 mpeg4/src/libavcodec/alpha/regdef.h create mode 100644 mpeg4/src/libavcodec/alpha/simple_idct_alpha.c create mode 100644 mpeg4/src/libavcodec/amr.c create mode 100644 mpeg4/src/libavcodec/apiexample.c create mode 100644 mpeg4/src/libavcodec/armv4l/dsputil_arm.c create mode 100644 mpeg4/src/libavcodec/armv4l/dsputil_arm_s.S create mode 100644 mpeg4/src/libavcodec/armv4l/dsputil_iwmmxt.c create mode 100644 mpeg4/src/libavcodec/armv4l/dsputil_iwmmxt_rnd.h create mode 100644 mpeg4/src/libavcodec/armv4l/jrevdct_arm.S create mode 100644 mpeg4/src/libavcodec/armv4l/mpegvideo_arm.c create mode 100644 mpeg4/src/libavcodec/armv4l/mpegvideo_iwmmxt.c create mode 100644 mpeg4/src/libavcodec/armv4l/simple_idct_arm.S create mode 100644 mpeg4/src/libavcodec/asv1.c create mode 100644 mpeg4/src/libavcodec/avcodec.h create mode 100644 mpeg4/src/libavcodec/avs.c create mode 100644 mpeg4/src/libavcodec/beosthread.c create mode 100644 mpeg4/src/libavcodec/bitstream.c create mode 100644 mpeg4/src/libavcodec/bitstream.h create mode 100644 mpeg4/src/libavcodec/bmp.c create mode 100644 mpeg4/src/libavcodec/cabac.c create mode 100644 mpeg4/src/libavcodec/cabac.h create mode 100644 mpeg4/src/libavcodec/cinepak.c create mode 100644 mpeg4/src/libavcodec/cljr.c create mode 100644 mpeg4/src/libavcodec/cook.c create mode 100644 mpeg4/src/libavcodec/cookdata.h create mode 100644 mpeg4/src/libavcodec/cscd.c create mode 100644 mpeg4/src/libavcodec/cyuv.c create mode 100644 mpeg4/src/libavcodec/dct-test.c create mode 100644 mpeg4/src/libavcodec/dpcm.c create mode 100644 mpeg4/src/libavcodec/dsputil.c create mode 100644 mpeg4/src/libavcodec/dsputil.h create mode 100644 mpeg4/src/libavcodec/dtsdec.c create mode 100644 mpeg4/src/libavcodec/dv.c create mode 100644 mpeg4/src/libavcodec/dvbsub.c create mode 100644 mpeg4/src/libavcodec/dvbsubdec.c create mode 100644 mpeg4/src/libavcodec/dvdata.h create mode 100644 mpeg4/src/libavcodec/dvdsub.c create mode 100644 mpeg4/src/libavcodec/dvdsubenc.c create mode 100644 mpeg4/src/libavcodec/error_resilience.c create mode 100644 mpeg4/src/libavcodec/eval.c create mode 100644 mpeg4/src/libavcodec/faac.c create mode 100644 mpeg4/src/libavcodec/faad.c create mode 100644 mpeg4/src/libavcodec/faandct.c create mode 100644 mpeg4/src/libavcodec/faandct.h create mode 100644 mpeg4/src/libavcodec/fdctref.c create mode 100644 mpeg4/src/libavcodec/fft-test.c create mode 100644 mpeg4/src/libavcodec/fft.c create mode 100644 mpeg4/src/libavcodec/ffv1.c create mode 100644 mpeg4/src/libavcodec/flac.c create mode 100644 mpeg4/src/libavcodec/flicvideo.c create mode 100644 mpeg4/src/libavcodec/fraps.c create mode 100644 mpeg4/src/libavcodec/g726.c create mode 100644 mpeg4/src/libavcodec/golomb.c create mode 100644 mpeg4/src/libavcodec/golomb.h create mode 100644 mpeg4/src/libavcodec/h261.c create mode 100644 mpeg4/src/libavcodec/h261data.h create mode 100644 mpeg4/src/libavcodec/h263.c create mode 100644 mpeg4/src/libavcodec/h263data.h create mode 100644 mpeg4/src/libavcodec/h263dec.c create mode 100644 mpeg4/src/libavcodec/h264.c create mode 100644 mpeg4/src/libavcodec/h264data.h create mode 100644 mpeg4/src/libavcodec/h264idct.c create mode 100644 mpeg4/src/libavcodec/huffyuv.c create mode 100644 mpeg4/src/libavcodec/i386/cputest.c create mode 100644 mpeg4/src/libavcodec/i386/dsputil_h264_template_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/dsputil_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/dsputil_mmx_avg.h create mode 100644 mpeg4/src/libavcodec/i386/dsputil_mmx_rnd.h create mode 100644 mpeg4/src/libavcodec/i386/fdct_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/fft_3dn.c create mode 100644 mpeg4/src/libavcodec/i386/fft_3dn2.c create mode 100644 mpeg4/src/libavcodec/i386/fft_sse.c create mode 100644 mpeg4/src/libavcodec/i386/h264dsp_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/idct_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/idct_mmx_xvid.c create mode 100644 mpeg4/src/libavcodec/i386/mmx.h create mode 100644 mpeg4/src/libavcodec/i386/motion_est_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/mpegvideo_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/mpegvideo_mmx_template.c create mode 100644 mpeg4/src/libavcodec/i386/simple_idct_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/snowdsp_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/vp3dsp_mmx.c create mode 100644 mpeg4/src/libavcodec/i386/vp3dsp_sse2.c create mode 100644 mpeg4/src/libavcodec/idcinvideo.c create mode 100644 mpeg4/src/libavcodec/imgconvert.c create mode 100644 mpeg4/src/libavcodec/imgconvert_template.h create mode 100644 mpeg4/src/libavcodec/imgresample.c create mode 100644 mpeg4/src/libavcodec/indeo2.c create mode 100644 mpeg4/src/libavcodec/indeo2data.h create mode 100644 mpeg4/src/libavcodec/indeo3.c create mode 100644 mpeg4/src/libavcodec/indeo3data.h create mode 100644 mpeg4/src/libavcodec/internal.h create mode 100644 mpeg4/src/libavcodec/interplayvideo.c create mode 100644 mpeg4/src/libavcodec/jfdctfst.c create mode 100644 mpeg4/src/libavcodec/jfdctint.c create mode 100644 mpeg4/src/libavcodec/jpeg_ls.c create mode 100644 mpeg4/src/libavcodec/jrevdct.c create mode 100644 mpeg4/src/libavcodec/kmvc.c create mode 100644 mpeg4/src/libavcodec/lcl.c create mode 100644 mpeg4/src/libavcodec/liba52/a52.h create mode 100644 mpeg4/src/libavcodec/liba52/a52_internal.h create mode 100644 mpeg4/src/libavcodec/liba52/a52_util.h create mode 100644 mpeg4/src/libavcodec/liba52/bit_allocate.c create mode 100644 mpeg4/src/libavcodec/liba52/bitstream.c create mode 100644 mpeg4/src/libavcodec/liba52/bitstream.h create mode 100644 mpeg4/src/libavcodec/liba52/crc.c create mode 100644 mpeg4/src/libavcodec/liba52/downmix.c create mode 100644 mpeg4/src/libavcodec/liba52/imdct.c create mode 100644 mpeg4/src/libavcodec/liba52/mm_accel.h create mode 100644 mpeg4/src/libavcodec/liba52/parse.c create mode 100644 mpeg4/src/libavcodec/liba52/resample.c create mode 100644 mpeg4/src/libavcodec/liba52/resample_c.c create mode 100644 mpeg4/src/libavcodec/liba52/resample_mmx.c create mode 100644 mpeg4/src/libavcodec/liba52/tables.h create mode 100644 mpeg4/src/libavcodec/libgsm.c create mode 100644 mpeg4/src/libavcodec/libpostproc/Makefile create mode 100644 mpeg4/src/libavcodec/libpostproc/mangle.h create mode 100644 mpeg4/src/libavcodec/libpostproc/postprocess.c create mode 100644 mpeg4/src/libavcodec/libpostproc/postprocess.h create mode 100644 mpeg4/src/libavcodec/libpostproc/postprocess_altivec_template.c create mode 100644 mpeg4/src/libavcodec/libpostproc/postprocess_internal.h create mode 100644 mpeg4/src/libavcodec/libpostproc/postprocess_template.c create mode 100644 mpeg4/src/libavcodec/loco.c create mode 100644 mpeg4/src/libavcodec/lzo.c create mode 100644 mpeg4/src/libavcodec/lzo.h create mode 100644 mpeg4/src/libavcodec/mace.c create mode 100644 mpeg4/src/libavcodec/mdct.c create mode 100644 mpeg4/src/libavcodec/mdec.c create mode 100644 mpeg4/src/libavcodec/mem.c create mode 100644 mpeg4/src/libavcodec/mjpeg.c create mode 100644 mpeg4/src/libavcodec/mlib/dsputil_mlib.c create mode 100644 mpeg4/src/libavcodec/mmvideo.c create mode 100644 mpeg4/src/libavcodec/motion_est.c create mode 100644 mpeg4/src/libavcodec/motion_est_template.c create mode 100644 mpeg4/src/libavcodec/motion_test.c create mode 100644 mpeg4/src/libavcodec/mp3lameaudio.c create mode 100644 mpeg4/src/libavcodec/mpeg12.c create mode 100644 mpeg4/src/libavcodec/mpeg12data.h create mode 100644 mpeg4/src/libavcodec/mpeg4data.h create mode 100644 mpeg4/src/libavcodec/mpegaudio.c create mode 100644 mpeg4/src/libavcodec/mpegaudio.h create mode 100644 mpeg4/src/libavcodec/mpegaudiodec.c create mode 100644 mpeg4/src/libavcodec/mpegaudiodectab.h create mode 100644 mpeg4/src/libavcodec/mpegaudiotab.h create mode 100644 mpeg4/src/libavcodec/mpegvideo.c create mode 100644 mpeg4/src/libavcodec/mpegvideo.h create mode 100644 mpeg4/src/libavcodec/msmpeg4.c create mode 100644 mpeg4/src/libavcodec/msmpeg4data.h create mode 100644 mpeg4/src/libavcodec/msrle.c create mode 100644 mpeg4/src/libavcodec/msvideo1.c create mode 100644 mpeg4/src/libavcodec/nuv.c create mode 100644 mpeg4/src/libavcodec/oggtheora.c create mode 100644 mpeg4/src/libavcodec/oggvorbis.c create mode 100644 mpeg4/src/libavcodec/opt.c create mode 100644 mpeg4/src/libavcodec/opt.h create mode 100644 mpeg4/src/libavcodec/os2thread.c create mode 100644 mpeg4/src/libavcodec/parser.c create mode 100644 mpeg4/src/libavcodec/pcm.c create mode 100644 mpeg4/src/libavcodec/png.c create mode 100644 mpeg4/src/libavcodec/pnm.c create mode 100644 mpeg4/src/libavcodec/ppc/dsputil_altivec.c create mode 100644 mpeg4/src/libavcodec/ppc/dsputil_altivec.h create mode 100644 mpeg4/src/libavcodec/ppc/dsputil_h264_altivec.c create mode 100644 mpeg4/src/libavcodec/ppc/dsputil_h264_template_altivec.c create mode 100644 mpeg4/src/libavcodec/ppc/dsputil_ppc.c create mode 100644 mpeg4/src/libavcodec/ppc/dsputil_ppc.h create mode 100644 mpeg4/src/libavcodec/ppc/dsputil_snow_altivec.c create mode 100644 mpeg4/src/libavcodec/ppc/fdct_altivec.c create mode 100644 mpeg4/src/libavcodec/ppc/fft_altivec.c create mode 100644 mpeg4/src/libavcodec/ppc/gcc_fixes.h create mode 100644 mpeg4/src/libavcodec/ppc/gmc_altivec.c create mode 100644 mpeg4/src/libavcodec/ppc/idct_altivec.c create mode 100644 mpeg4/src/libavcodec/ppc/mpegvideo_altivec.c create mode 100644 mpeg4/src/libavcodec/ppc/mpegvideo_ppc.c create mode 100644 mpeg4/src/libavcodec/ps2/dsputil_mmi.c create mode 100644 mpeg4/src/libavcodec/ps2/idct_mmi.c create mode 100644 mpeg4/src/libavcodec/ps2/mmi.h create mode 100644 mpeg4/src/libavcodec/ps2/mpegvideo_mmi.c create mode 100644 mpeg4/src/libavcodec/pthread.c create mode 100644 mpeg4/src/libavcodec/qdm2.c create mode 100644 mpeg4/src/libavcodec/qdm2data.h create mode 100644 mpeg4/src/libavcodec/qdrw.c create mode 100644 mpeg4/src/libavcodec/qpeg.c create mode 100644 mpeg4/src/libavcodec/qtrle.c create mode 100644 mpeg4/src/libavcodec/ra144.c create mode 100644 mpeg4/src/libavcodec/ra144.h create mode 100644 mpeg4/src/libavcodec/ra288.c create mode 100644 mpeg4/src/libavcodec/ra288.h create mode 100644 mpeg4/src/libavcodec/rangecoder.c create mode 100644 mpeg4/src/libavcodec/rangecoder.h create mode 100644 mpeg4/src/libavcodec/ratecontrol.c create mode 100644 mpeg4/src/libavcodec/raw.c create mode 100644 mpeg4/src/libavcodec/resample.c create mode 100644 mpeg4/src/libavcodec/resample2.c create mode 100644 mpeg4/src/libavcodec/roqvideo.c create mode 100644 mpeg4/src/libavcodec/rpza.c create mode 100644 mpeg4/src/libavcodec/rtjpeg.c create mode 100644 mpeg4/src/libavcodec/rtjpeg.h create mode 100644 mpeg4/src/libavcodec/rv10.c create mode 100644 mpeg4/src/libavcodec/sh4/dsputil_align.c create mode 100644 mpeg4/src/libavcodec/sh4/dsputil_sh4.c create mode 100644 mpeg4/src/libavcodec/sh4/idct_sh4.c create mode 100644 mpeg4/src/libavcodec/sh4/qpel.c create mode 100644 mpeg4/src/libavcodec/shorten.c create mode 100644 mpeg4/src/libavcodec/simple_idct.c create mode 100644 mpeg4/src/libavcodec/simple_idct.h create mode 100644 mpeg4/src/libavcodec/smacker.c create mode 100644 mpeg4/src/libavcodec/smc.c create mode 100644 mpeg4/src/libavcodec/snow.c create mode 100644 mpeg4/src/libavcodec/snow.h create mode 100644 mpeg4/src/libavcodec/sonic.c create mode 100644 mpeg4/src/libavcodec/sp5x.h create mode 100644 mpeg4/src/libavcodec/sparc/dsputil_vis.c create mode 100644 mpeg4/src/libavcodec/sparc/vis.h create mode 100644 mpeg4/src/libavcodec/svq1.c create mode 100644 mpeg4/src/libavcodec/svq1_cb.h create mode 100644 mpeg4/src/libavcodec/svq1_vlc.h create mode 100644 mpeg4/src/libavcodec/svq3.c create mode 100644 mpeg4/src/libavcodec/swscale.h create mode 100644 mpeg4/src/libavcodec/truemotion1.c create mode 100644 mpeg4/src/libavcodec/truemotion1data.h create mode 100644 mpeg4/src/libavcodec/truemotion2.c create mode 100644 mpeg4/src/libavcodec/truespeech.c create mode 100644 mpeg4/src/libavcodec/truespeech_data.h create mode 100644 mpeg4/src/libavcodec/tscc.c create mode 100644 mpeg4/src/libavcodec/tta.c create mode 100644 mpeg4/src/libavcodec/ulti.c create mode 100644 mpeg4/src/libavcodec/ulti_cb.h create mode 100644 mpeg4/src/libavcodec/utils.c create mode 100644 mpeg4/src/libavcodec/vc9.c create mode 100644 mpeg4/src/libavcodec/vc9data.h create mode 100644 mpeg4/src/libavcodec/vcr1.c create mode 100644 mpeg4/src/libavcodec/vmdav.c create mode 100644 mpeg4/src/libavcodec/vorbis.c create mode 100644 mpeg4/src/libavcodec/vorbis.h create mode 100644 mpeg4/src/libavcodec/vp3.c create mode 100644 mpeg4/src/libavcodec/vp3data.h create mode 100644 mpeg4/src/libavcodec/vp3dsp.c create mode 100644 mpeg4/src/libavcodec/vqavideo.c create mode 100644 mpeg4/src/libavcodec/w32thread.c create mode 100644 mpeg4/src/libavcodec/wmadata.h create mode 100644 mpeg4/src/libavcodec/wmadec.c create mode 100644 mpeg4/src/libavcodec/wmv2.c create mode 100644 mpeg4/src/libavcodec/wnv1.c create mode 100644 mpeg4/src/libavcodec/ws-snd1.c create mode 100644 mpeg4/src/libavcodec/x264.c create mode 100644 mpeg4/src/libavcodec/xan.c create mode 100644 mpeg4/src/libavcodec/xl.c create mode 100644 mpeg4/src/libavcodec/xvid_rc.c create mode 100644 mpeg4/src/libavcodec/xvidff.c create mode 100644 mpeg4/src/libavcodec/xvmcvideo.c create mode 100644 mpeg4/src/libavcodec/zmbv.c create mode 100644 mpeg4/src/libavformat/.cvsignore create mode 100644 mpeg4/src/libavformat/4xm.c create mode 100644 mpeg4/src/libavformat/Makefile create mode 100644 mpeg4/src/libavformat/adtsenc.c create mode 100644 mpeg4/src/libavformat/aiff.c create mode 100644 mpeg4/src/libavformat/allformats.c create mode 100644 mpeg4/src/libavformat/amr.c create mode 100644 mpeg4/src/libavformat/asf-enc.c create mode 100644 mpeg4/src/libavformat/asf.c create mode 100644 mpeg4/src/libavformat/asf.h create mode 100644 mpeg4/src/libavformat/au.c create mode 100644 mpeg4/src/libavformat/audio.c create mode 100644 mpeg4/src/libavformat/avformat.h create mode 100644 mpeg4/src/libavformat/avi.h create mode 100644 mpeg4/src/libavformat/avidec.c create mode 100644 mpeg4/src/libavformat/avienc.c create mode 100644 mpeg4/src/libavformat/avio.c create mode 100644 mpeg4/src/libavformat/avio.h create mode 100644 mpeg4/src/libavformat/aviobuf.c create mode 100644 mpeg4/src/libavformat/avs.c create mode 100644 mpeg4/src/libavformat/barpainet.c create mode 100644 mpeg4/src/libavformat/barpainet.h create mode 100644 mpeg4/src/libavformat/beosaudio.cpp create mode 100644 mpeg4/src/libavformat/crc.c create mode 100644 mpeg4/src/libavformat/cutils.c create mode 100644 mpeg4/src/libavformat/daud.c create mode 100644 mpeg4/src/libavformat/dc1394.c create mode 100644 mpeg4/src/libavformat/dv.c create mode 100644 mpeg4/src/libavformat/dv.h create mode 100644 mpeg4/src/libavformat/dv1394.c create mode 100644 mpeg4/src/libavformat/dv1394.h create mode 100644 mpeg4/src/libavformat/electronicarts.c create mode 100644 mpeg4/src/libavformat/ffm.c create mode 100644 mpeg4/src/libavformat/file.c create mode 100644 mpeg4/src/libavformat/flic.c create mode 100644 mpeg4/src/libavformat/flvdec.c create mode 100644 mpeg4/src/libavformat/flvenc.c create mode 100644 mpeg4/src/libavformat/framehook.c create mode 100644 mpeg4/src/libavformat/framehook.h create mode 100644 mpeg4/src/libavformat/gif.c create mode 100644 mpeg4/src/libavformat/gifdec.c create mode 100644 mpeg4/src/libavformat/grab.c create mode 100644 mpeg4/src/libavformat/grab_bktr.c create mode 100644 mpeg4/src/libavformat/http.c create mode 100644 mpeg4/src/libavformat/idcin.c create mode 100644 mpeg4/src/libavformat/idroq.c create mode 100644 mpeg4/src/libavformat/img.c create mode 100644 mpeg4/src/libavformat/img2.c create mode 100644 mpeg4/src/libavformat/ipmovie.c create mode 100644 mpeg4/src/libavformat/jpeg.c create mode 100644 mpeg4/src/libavformat/matroska.c create mode 100644 mpeg4/src/libavformat/mm.c create mode 100644 mpeg4/src/libavformat/mmf.c create mode 100644 mpeg4/src/libavformat/mov.c create mode 100644 mpeg4/src/libavformat/mov.h create mode 100644 mpeg4/src/libavformat/movenc.c create mode 100644 mpeg4/src/libavformat/mp3.c create mode 100644 mpeg4/src/libavformat/mpeg.c create mode 100644 mpeg4/src/libavformat/mpegts.c create mode 100644 mpeg4/src/libavformat/mpegts.h create mode 100644 mpeg4/src/libavformat/mpegtsenc.c create mode 100644 mpeg4/src/libavformat/mpjpeg.c create mode 100644 mpeg4/src/libavformat/nsvdec.c create mode 100644 mpeg4/src/libavformat/nut.c create mode 100644 mpeg4/src/libavformat/nuv.c create mode 100644 mpeg4/src/libavformat/ogg.c create mode 100644 mpeg4/src/libavformat/ogg2.c create mode 100644 mpeg4/src/libavformat/ogg2.h create mode 100644 mpeg4/src/libavformat/oggparseflac.c create mode 100644 mpeg4/src/libavformat/oggparsetheora.c create mode 100644 mpeg4/src/libavformat/oggparsevorbis.c create mode 100644 mpeg4/src/libavformat/os_support.c create mode 100644 mpeg4/src/libavformat/os_support.h create mode 100644 mpeg4/src/libavformat/png.c create mode 100644 mpeg4/src/libavformat/pnm.c create mode 100644 mpeg4/src/libavformat/psxstr.c create mode 100644 mpeg4/src/libavformat/qtpalette.h create mode 100644 mpeg4/src/libavformat/raw.c create mode 100644 mpeg4/src/libavformat/rm.c create mode 100644 mpeg4/src/libavformat/rtp.c create mode 100644 mpeg4/src/libavformat/rtp.h create mode 100644 mpeg4/src/libavformat/rtpproto.c create mode 100644 mpeg4/src/libavformat/rtsp.c create mode 100644 mpeg4/src/libavformat/rtsp.h create mode 100644 mpeg4/src/libavformat/rtspcodes.h create mode 100644 mpeg4/src/libavformat/segafilm.c create mode 100644 mpeg4/src/libavformat/sgi.c create mode 100644 mpeg4/src/libavformat/sierravmd.c create mode 100644 mpeg4/src/libavformat/smacker.c create mode 100644 mpeg4/src/libavformat/sol.c create mode 100644 mpeg4/src/libavformat/swf.c create mode 100644 mpeg4/src/libavformat/tcp.c create mode 100644 mpeg4/src/libavformat/tta.c create mode 100644 mpeg4/src/libavformat/udp.c create mode 100644 mpeg4/src/libavformat/utils.c create mode 100644 mpeg4/src/libavformat/v4l2.c create mode 100644 mpeg4/src/libavformat/voc.c create mode 100644 mpeg4/src/libavformat/voc.h create mode 100644 mpeg4/src/libavformat/wav.c create mode 100644 mpeg4/src/libavformat/wc3movie.c create mode 100644 mpeg4/src/libavformat/westwood.c create mode 100644 mpeg4/src/libavformat/yuv.c create mode 100644 mpeg4/src/libavformat/yuv4mpeg.c create mode 100644 mpeg4/src/libavutil/Makefile create mode 100644 mpeg4/src/libavutil/avutil.h create mode 100644 mpeg4/src/libavutil/bswap.h create mode 100644 mpeg4/src/libavutil/common.h create mode 100644 mpeg4/src/libavutil/crc.c create mode 100644 mpeg4/src/libavutil/crc.h create mode 100644 mpeg4/src/libavutil/eval.c create mode 100644 mpeg4/src/libavutil/integer.c create mode 100644 mpeg4/src/libavutil/integer.h create mode 100644 mpeg4/src/libavutil/intfloat_readwrite.c create mode 100644 mpeg4/src/libavutil/intfloat_readwrite.h create mode 100644 mpeg4/src/libavutil/mathematics.c create mode 100644 mpeg4/src/libavutil/mathematics.h create mode 100644 mpeg4/src/libavutil/rational.c create mode 100644 mpeg4/src/libavutil/rational.h create mode 100644 mpeg4/src/output_example.c create mode 100644 mpeg4/src/pktdumper.c create mode 100644 mpeg4/src/qt-faststart.c create mode 100644 mpeg4/src/tests/.cvsignore create mode 100644 mpeg4/src/tests/Makefile create mode 100644 mpeg4/src/tests/audiogen.c create mode 100644 mpeg4/src/tests/dsptest.c create mode 100644 mpeg4/src/tests/ffmpeg.regression.ref create mode 100644 mpeg4/src/tests/ffserver.regression.ref create mode 100644 mpeg4/src/tests/lena.pnm create mode 100644 mpeg4/src/tests/libav.regression.ref create mode 100755 mpeg4/src/tests/regression.sh create mode 100644 mpeg4/src/tests/rotozoom.c create mode 100644 mpeg4/src/tests/rotozoom.regression.ref create mode 100755 mpeg4/src/tests/server-regression.sh create mode 100644 mpeg4/src/tests/test.conf create mode 100644 mpeg4/src/tests/tiny_psnr.c create mode 100644 mpeg4/src/tests/videogen.c create mode 100755 mpeg4/src/unwrap-diff create mode 100644 mpeg4/src/vhook/Makefile create mode 100644 mpeg4/src/vhook/drawtext.c create mode 100644 mpeg4/src/vhook/fish.c create mode 100644 mpeg4/src/vhook/imlib2.c create mode 100644 mpeg4/src/vhook/null.c create mode 100644 mpeg4/src/vhook/ppm.c create mode 100644 mpeg4/src/vhook/watermark.c create mode 100644 mpeg4/src/xvmc_render.h diff --git a/mpeg4/bench.mk b/mpeg4/bench.mk new file mode 100644 index 00000000..22f693c8 --- /dev/null +++ b/mpeg4/bench.mk @@ -0,0 +1,134 @@ +#### mpeg4 #### +DIR:=$(call my-dir) + +# Which file we measure the size +get_which_size=mpeg4_bench + +# Running commands +run_cmd=${PERFLAB_PATH}/mpeg4_bench -s 1280x720 -i ${PERFLAB_INPUT}/dance_100frame.avi -benchmark -y ${PERFLAB_INPUT}/mpeg4_output/dec_dance_frame_%03d.ppm; ${PERFLAB_PATH}/mpeg4_bench -i ${PERFLAB_INPUT}/mpeg4_output/dec_dance_frame_%03d.ppm -r 30 -s 1280x720 -sameq -g 9 -bf 3 -vcodec mpeg4 -benchmark -an -y ${PERFLAB_INPUT}/enc_dance_output.avi + +ffmpeg_cflags := -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE +ffmpeg_includes := src/ src/libavutil src/libavcodec src/libavformat + +##################################### +include $(BUILD)/clear.mk +TARGET := libavutil.a +##################################### + +target_srcs := mathematics.c rational.c intfloat_readwrite.c crc.c +target_prefix := libavutil + +target_local_includes := src/ src/libavutil +target_local_cflags := -DHAVE_AV_CONFIG_H -DBUILD_AVUTIL $(ffmpeg_cflags) + +include $(BUILD)/build_library.mk + +##################################### +include $(BUILD)/clear.mk +TARGET := libavcodec.a +##################################### + +target_srcs := bitstream.c utils.c mem.c allcodecs.c \ + mpegvideo.c jrevdct.c jfdctfst.c jfdctint.c\ + mpegaudio.c ac3enc.c mjpeg.c resample.c resample2.c dsputil.c \ + motion_est.c imgconvert.c imgresample.c \ + mpeg12.c mpegaudiodec.c pcm.c simple_idct.c \ + ratecontrol.c adpcm.c eval.c error_resilience.c \ + fft.c mdct.c raw.c golomb.c cabac.c\ + dpcm.c adx.c faandct.c parser.c g726.c \ + vp3dsp.c h264idct.c rangecoder.c pnm.c h263.c msmpeg4.c h263dec.c \ + opt.c + +target_srcs += aasc.c alac.c asv1.c avs.c cinepak.c cook.c cljr.c cyuv.c \ + dvbsubdec.c dvbsub.c dvdsub.c dvdsubenc.c dv.c 8bps.c ffv1.c \ + flac.c flicvideo.c 4xm.c fraps.c h261.c h264.c huffyuv.c \ + idcinvideo.c indeo2.c indeo3.c interplayvideo.c kmvc.c lcl.c \ + loco.c mace.c msrle.c msvideo1.c png.c qdm2.c qdrw.c qpeg.c \ + qtrle.c ra144.c ra288.c roqvideo.c rpza.c rv10.c shorten.c \ + smacker.c smc.c snow.c sonic.c svq1.c truemotion1.c truemotion2.c \ + truespeech.c tta.c tscc.c cscd.c lzo.c nuv.c rtjpeg.c \ + ulti.c vc9.c vcr1.c vmdav.c vorbis.c vp3.c vqavideo.c wmadec.c \ + wnv1.c ws-snd1.c xan.c xl.c bmp.c mmvideo.c zmbv.c + + +target_prefix := libavcodec + +target_local_includes := src/ src/libavutil \ + $(android_root)/external/zlib + +target_local_cflags := -DHAVE_AV_CONFIG_H +target_local_android_shared_libs := + +include $(BUILD)/build_library.mk + +##################################### +include $(BUILD)/clear.mk +TARGET := libavformat.a +##################################### + +target_srcs := utils.c cutils.c os_support.c allformats.c \ + mpeg.c mpegts.c mpegtsenc.c ffm.c crc.c img.c img2.c raw.c rm.c \ + avienc.c avidec.c wav.c mmf.c swf.c au.c gif.c mov.c mpjpeg.c dv.c \ + yuv4mpeg.c 4xm.c flvdec.c psxstr.c idroq.c ipmovie.c \ + nut.c wc3movie.c mp3.c westwood.c segafilm.c idcin.c flic.c \ + sierravmd.c matroska.c sol.c electronicarts.c nsvdec.c asf.c \ + ogg2.c oggparsevorbis.c oggparsetheora.c oggparseflac.c daud.c aiff.c \ + voc.c tta.c mm.c avs.c smacker.c nuv.c + +# muxers +target_srcs += flvenc.c movenc.c asf-enc.c adtsenc.c + +# image formats +target_srcs += pnm.c yuv.c png.c jpeg.c gifdec.c sgi.c framehook.c + +# CONFIG_VEDEO4LINUX +target_srcs += grab.c + +# CONFIG_VIDEO4LINUX2 +target_srcs += v4l2.c + +# CONFIG_DV1394 +target_srcs += dv1394.c + +# CONFIG_AUDIO_OSS +target_srcs += audio.c + +# protocols I/O +target_srcs += avio.c aviobuf.c + +# CONFIG_PROTOCOLS +target_srcs += file.c + +# CONFIG_NETWORK +target_srcs += udp.c tcp.c http.c rtsp.c rtp.c rtpproto.c + +target_prefix := libavformat +target_local_cflags := -DHAVE_AV_CONFIG_H $(ffmpeg_cflags) +target_local_includes := $(ffmpeg_includes) \ + $(android_root)/external/zlib + +target_local_static_libs := libavutil libavcodec + +include $(BUILD)/build_library.mk + +##################################### +include $(BUILD)/clear.mk +TARGET := mpeg4_bench +##################################### + +target_srcs := ffmpeg.c cmdutils.c + +target_prefix := +target_local_cflags := $(ffmpeg_cflags) + +target_local_includes := src/ \ + src/libavutil \ + src/libavcodec \ + src/libavformat + +target_local_android_static_libs := +target_local_android_shared_libs := libz libdl +target_local_static_libs := libavformat libavcodec libavutil +target_local_shared_libs := + +include $(BUILD)/build_executable.mk diff --git a/mpeg4/data/dance_100frame.avi b/mpeg4/data/dance_100frame.avi new file mode 100644 index 0000000000000000000000000000000000000000..801a204eee581b9b957df95bf4908cb574c8b44a GIT binary patch literal 2747986 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�%Fzdq%dlQD;J1-o4@L=Y`1@9sxzofZ*urL&# z_(z`c_~rzQ@5%W)kKMk{a^I7;B}e}8|NkF$ScvoP-)896BIDXnCEA#HsBDMD><9^}+;B=Do%^Y7O`*!M8x zFL>aa{!g6!M+5Kk&xz}$J``O2GoyF+`P&Z0>`Y}6Ob@>%C)jfANh`cGvEz(P@%x5% z`u9Yd-Y48++bL#JyUu7~$MPTf9mjqIUhw(-#Z|@rn1?fy`9_H|aopF884tYpzyFkn z=79$XlqSyl+h8+&Bg5LB9|3$U?>lev?AS2-+sy?s+|MMLcV28@GJ-LTF7|K!glg{t}gPsB4GRd~3Jo%7!(m7wO`{ss{&IVn9dq6P;H-S`}| z=WYrtNZJs5@W76Qr>FQf1vzzJ@co_esHsM>`CI+JgBN7{4;nvyUwQoZ_3at9;{X3@ zST+=>eNJh35c8qPU|rd7$LdC7X?9i{xyAp#UKETIW@puXznbCWbcV`rzxdv$C3Y@t zEdMaW_x9X((!wST4`3v;F;R_H2okFMPs(^51{lcIR>K z?(-XdYf2wJwfT9~hqiM5`(GJlPwxoeUacGYQNm>kJ8NOi@AY@fkAL!up7qRt^~t1)v>+jEXU%#p1uJpymLp7_7t$&A`3bN*QiE=o| z2wW{oO1pBdy>(VkR;_`7CVNu=`vXULv$gA=zIbfv9Bq9s&xzIXL4qZV08gF~WAnBv zC6Yq3zp=5mCIuKMzH<9x#bR=`?cI6ypAE^oEA~xrJT3M>>xN9$gpXT_E)>owxDzB_ zvn^1N<5IXt_uSdOkL!9L{ak(O?R@F_n%wQ5_kY|fyzlJuEsI*kXS#jg&%UyO=exDT zyq|*GuiN)N`)5D<$M5{tInO007=!jR-hN?W%yP#hQQO(czyH}k&d1I^>h;pOf5Z||mLesE%mOiSk!Ay#|2xA)ZEs9ZWf zbH@(->IILcC~Od|@x3YiOTy#efeoyWUvT_uYf(RNQ18LN`TzfJQEB?<9GOt`<*KOR zOif?Wq$vS1&K0-w$_~ET|G#)yC*QtVn(RCm?Jqgsm(Kko&2oK)+8>?D?cXk5-am(Z zZ3E9Y32Bb`R)*}X_7yVfC1MJX=1qJj#PspQ4U5dr&kr>k*QotYW^GL3Q%rk2^BMC5 zMV9}2n5S#L6?g7o=RWDnsw?SVwb4a%!|{fV^|v1?9LZjg#J54FT92=oect~+;`S9& zWQ;UzUh<13)SY1Xr=2^o_Q9DnKCYWfJ6-W3?~NHQ=&K~D%AdNPMM(g;6cpR)&p~QWnA<+$~1o)U!yR4iLqM7VLPcs z%OrUCY9G7Ylt}x>Ct1+?Wof0W_~L~c5m`U z+;H;TVht6A1e?$7f@SL+kK~uIiwJR9c%O**JpJ1-hn)!zVm1_n96ap5O*@rYIiUTz zajMeir1{&J8!z-;IGO$>;lbQ1CQ6^SpPqI)uw|aUzthU|4h4bbXHRDd3*TG7&ZY2q zn*S+2QO9S`rO*D3k6{kpGQrFL+id|O(@*<8G`21_Nc$R~5zWrjEFEy3MQD-h6h$+) z#QH0y73P=Lh^&shtD>0mz=4JFf}{W6AhrYNuUu8)=wdnGsK_HBGI5WtY~8AR98(=q zp0GC@Si+HH6g8(rb=#%+8aJX>nQ+SKO%P!?`>>jK8++($-i)fNcLV>JIGojr?(K}# z;1++gZt2p5!(r!}R!DfWg}(mq-^FaBG}rgH@0Ikcv;IC(*Wy{>Eyt{$y2F-*@yCa~ zre|+hd%ie!Y0)-Q?<}_`iPkS|{{(Kz(0i%yamj(`o2|l)k-nVb_xXOUkg&M=Bj7tr z+`;X3GKVBW--{LBkabeITrZdVCwKdccgJ_1=e)Hj{?rxW{72hv{+~H7edhP7=-OiY z&&h98((gRJ|9%_ub&eS++~@d2-*LaNOql)nK4=w^+3g><&rf{*JvC7|gMa^a0mb;$ zi(ZO|K6juO2)&5&YTii;;w)NJ8vphj*O+FZ$hOFBI_labm&}|8IvC<3Zc5 zC;Wb8lJGd-GaF}}c5a)a?Rz$+e?kHq3jgpaWwL-pHF&01tS#C?lA z56R@nh}bo^$yk2hp&whKeoL^z^(}j0#Ri{W|Mze&t1pq^TqC3L`>y5-{m8&wjmZuV zSHH60;ocU&7oqg~fO7MS%L*>W4t&)t=eIR1SQF!6@}%N|MSEb=g9rXUBP=EuDbxxi zJJ#>}&l$))=is5|nA)vk>yywU<95SpjR9AY zK#`Gs+XwIa$8XnH++sa){&0~U-|FV+wwu;@Z1iHjUmy5N^yP*)K&w<$rf2m0sv@`5Sh9D_L-PN0N|T&qQ5;pdj~} zu-g(7|LzJ5Z2EcOjPc9kf%>_U^OITEM5zBx*uc&+@8}C1o@*i-N+cCTjFT+_b_9Pr zn9wnibL;sH5j+9&lLfsyj=pYVRKK@^X6d@oH5zrCaQ6VDc=qr7K!1MuwL*e z^ES_po(ntr4=1G=IvzeZi}AqDy-z#&ezY%o82;+?tQT&F1!N=(e7_dXu#{&#Qs3NI zaPYv6C%NxG+-B$LVvYWD#?bYO!z=9v4`K}tXq5NY{M8Sz5ZAeJM8<&YiQMe}pDNyE zHcn@iP(5}`G5D9!>F&n!iNcT8H$Ql!K5Np1c`27?-apaSDroR2^$O30aAuaz*N@x2 zJodR>I`_A#nQXq`$3#C4hDH7jQd8X1mzMP&HBg?PY`^aotLA^{o%aL|bH(j06rAC& z5I+0Izw?iC_xEo5GyCn6s#UM%t`DhSW$Ro#b@jq+mH+!et@|Ih^FBVi^Z4xk`37|- z7=E+-@7?on-t$K7*o4CWO+RFe*-I{pE7fxzjL)CAcYbbjvq7OW=Lg#qhNR_8nfKYG zwq9)R&ujWW%lf0)fd?`5tJ@U*1~BeqJn*zBkH_@K?Q;b=;V+w41b>Xq5s#Ov{kthJ z%=vIYirRt0VSE#AzjtP1xu*S=;Y8XFZ|lE2tS{X9w{k8r<5LkWklS!Ve7|)`TF$fl z-?dJBG2!q$bhIiB|0{WIVEJ87LH(|0MQ2aoLc7;AD>SUi4Y z&E|HBRbpzf!_4nCksSP@TR6lxW-gqf5;LFSlYZCthu!ccE96Z6MpUSX7bYs==eQ7x|#+(*>?1GyDjen?j z%wi}yut9YHHUqa^4|XN1ICl6PTf=_JL+$sI!s%Pm8IPAU8NnCAr*(&&3*j>t1}$`)GYyV1L)=XD9xt-}wJy{hsQ_x%-!!RnGfy zul~V2%l_-fefRf1`)79h*Y6hzlC3&ZWJC%Ij&itG%>ZqEG&?r`;Gg~ff0SHgZdP1< zxzl%+o7=y#^ZPH%elVMzbGt|UiBpaT5?u*uN=NWEO`HjT7{M-?8wZ+IAN zdphCI{ePRCRgak@3GL%KctKphF?8bgJKGPo?Feir2syT&6|^Vw$r%|#cH#fMZ{LGv z*R5t)7A{U&W+YX+;e@dhpINaKPvcQ;t`8RCIx@x_|8818Na1Fz@H%*KMgr%}HD zi*qtRexHBOEU0o4^PE>KjGfjCED{83a<_jwEZSt2TTuCe;Y8tr150|Fo2B?fYdS7$cAicTTlX!ZCdQ1$_sDfYj(f6Lx=Gw z{}jbI#sjYml>hA8!Ee^X&X!Uke~rP+SiE`Og(=Lf_MG$H*A(CTQQ4IId0UIj_bUt! zCN}@6|9_UbBfoyNvMM{%*EM`EEcz!ke?7q7THbX#nbGEX&hL^q-*0DoSos%i%Kp)t7$z=hhlN6Q3Xap8tP%y>Q)U_xtw?H*fB1 zk}W@E9TS4;K}E4}$+N=(rS=Eg<|OfP#$S0TUHInzh)YTkW2y;3~C@#O+$wcp7Khjbhc-W8WkuzPXh_p29z3njP@%?9PG%0HFg zKjZ}6=CqSP%xGO-zxq<}`xRZ57JLrc*^I_(gmo5|3WEt*S4yD|=1)qP`Nf#a_(|^ekAMCrmG8)qF)7}*=}C_KBL*{WriPe@ z6W{OI?)V~s*{pQpPu7RQ%?5Ebx!b>A=(#XSxvkSbuighRFINOBow|+^wOLAV8en(mUjcaC4`t;brT+yED+xz>uCITl8$;thDGC~PfC^tkL}=k1jQo6C23 z*7F(289%9(EQm1_y*K@r;6zV{xy^01icc!PfBbg$MM?+b!I|$9^nbIn?3V_05-j=+ zm)6vqTl~&Daqs=>HCMK7YYvuPsKUQ!+DQdHeZAsySs%;mvpVW;zhApq{7uuu1MJQG zHM7_7FK9Y1cyNnEkl~9z0tamBmU`7@OupO9yjbgq*{o>mzs(A3mUVA`;dJcUMcuFr z@$Xy-{L1&_pY`salFnFQn7Z)Yy{0*Pg%szjIa=wn#5&cDd3-a-AVmIp~A(67u?Ho1x{R8|GrdqDXZe{ znOhI3J2Q5;9;gz^yDhw-RMqYzr_1>TUnVf_etRK8Hd|=Q0=o;%yGqwI++5oKcbB&> z&zxf(XBC=iBzhQ&fAGZ$uXlGbib-gF!+xo8g3k@>IW9eFKmOe+-x1Iw?jsW*n8)KP zv*gxuyC3RSe3HAFr?U$i6d4@6U$Z8OkLAv;7r%D@u;k=sk1%Ate*2M?fu`t#QVEtb z;xQ_}pR8^=A}o=nXLC$#<-UXAtPRWGUYZag_(A^SB)+{p2M^3Rcvwk)?Fk*$Cym-{ zoR#|mN+bl&-AEDLAj20E+NRPGC^ErrF~|A}V+Ui0Z~SK&v|m^{`26znF!}u`hmW;m zJ{!}=CUd*CkihQ;4>L@it-)TJqF?J0(4bzcGFQV*@NYfyTG2FYxxqrKcDj?=3Hb|m4jvYANOI5d=hiY8=eRjEY>l8Z_&K$ z6kqKIxt$toXTRLq%q2O|;DC(dLHkGBZg_w1?K%3yN0!skuz8w7DZ>#N_wPTgL{54t zy*-b zQ)ah+`{KTHl*q@bhYeR>lz*;WYT#N5V9NX9|K)p;9QN`5|0q9^eqi7K|NVnP^Lu9ejto*l zfzgc}Nqi3$Pbn=Zde~?jb8|sN%l=y47dH%DHZeLs5pQm}%jjX@-*{}-21|kUFLM_^ zxURH(--i>Em{%EEI~nl=^mP2NH~+tu!7@)t^TqP_lO`mTmN7nfFtNGsZ~hJc9eied z6Z(5H0zb;9&p(*v?Us1p6w97liW4k)@7-KD;f##KFFwgHvYvO@9SRlY;}je(Rvmib z`|)!A!*8bNUp!RivR3->Ij`&#qv>pRo|wa|J2YyXjBLOBWuN(e8=um#gC#!#{C@DM za_rl8k}c8vp@PL{b`Jx^-w6*Qm>zyvAS1DJ4fnr|3(6S_Z>;^s@B9D9s?^UX`lSM& zs(d)!U9UWGqKj?$p?8(PttFeytW(!8`{*nay&U`M_+O^>yZ;>nnMIPe`?1bj%X{a> z#Z515a^}AFJ9C9a;O4<)k2^o#R$P;GS8}%1ru|N=(U%ivgnW^C>@)4j`Ar8eyihSZ zF=776;Cyp4ksOmRCCB^L^*XAEFf8>ExSAL**<8=6^xz!3WUf+u?drlxM-w%1Glf-| z8Hllsbig%F zCtAN&Vx)tnC}RKfMfl9KF-c@NwF4-HWGlUf1*0Z@XA|@ymj<3p^jroan}2Ai?qC z#Np(&gAeR;Sy=0POXCuXYc_h6x#-BU7=CchaMa6}o-+0N?-bU93K={%rg890Tb4IX zQ#*M}fze!LQv=O9%SUxF%cj}%w(x7PCK;?;D#@X6kIl=Dm0Rd(z*_!QR~a>TxoJ%R z9mCDqYyRw0{`%x&|6jj88~OE5wcPQki?-i5lKFLC<-El7OSg4YIcL7_um2au**nFf zM~3tL#J~H`-*@@V{QWAokv#Qvu97)RPtJPB8ouYFvKrh5p?IHsYI@4_3cnXZX1Mb`UqyJcSo? zn>*RkZOt;`lU{HbSj2MtyTK>1D~!ikVRdttqj8B$gYZ7-gn#w_pIh9{e+U|we%~E! z{&#~MU!zR(RR=b=-;M`n{c3M`qVT9mfAwNX>rz#P4WjR+IK`CMJ|Duvz%OLe^8v>Dh+o z%n_0cg+GTZlw9m0#e0jlNQn2){JjhBwQVt8@JMRG1K)b-7y2JH*-uZ9%jx`McPRGX zO$AFyr$cGXhZ#;Uxm(!s(DOO72A}fpFLF%`21nA~aWhV^2)odHt^S`@%H9V_e4>9h z9F?%VW8}oA!g*J+d4*o=)Wk_l6PCZ7&91~A=p4V4;el_Ns2&|9D+naqnJf68j7L zEev_ht@brC8`7$kB?AhM%rA-CaYE^Jcbm%P`HyeaT5l5mv-J4AXPRamfs-eE4(r|a zckTi%dG^*tYdY9}di?f^mE@aWv-$S@mX;;H6AML*-?6zY>dfc#TV3!@C-?8IQ@$og zvZu$!+)`}}>y^LB6tdXi!Qz9d>vLCSmP@d*H6L`aJD#O8A>l~`V>kay76-o6EzbRU zJu(SXk;;1zFq|QXS5& zVqR&qa^g(!BO09kGtVq$eW|0w&#;8~O$*bHdzs;GhZ-L6bC#N&S$LJJUv^2)xrHr0 zhc;|4J+P1YAa6sPU1I$DuvRTk$D$Cm(`LS>Z+tl1z9jwT_oWkC*XZVzm@0gkz}Piw z1|P?4+mCzhpFFq0@BZV;{k`A*Dd#56Wc&4%*WyUO{I8ww4<4yWP=6wpJ;87$_uCB- zB2&7GlnV@b{5QL5OPR`=x1Ds$ZjCp4#hvbWS|>;?dp0{usqZB2UM|_U7iV4>*;P`D*+ZsSn_@%a@79rGu0KRDIKEnwtO&Uh}_@3v;c`b{#>aYe;dHuizNdJJrzxk6iOMKI^h4i`p{jo zT?R8}IVvfKzH2WPC|}WA%Bzs{ui)aw@arEPcLe1$OR=-c$ZRw}9b%+(L-wHe@8dr# ze9umr&Cc~9@qq8|jAJ&7%3VJu&JWzbn0>+jKffC+WG~4tW_VX%93X7hyvw6yN%O8< z3K2ym-|xrV4_N$mwUWq_w8N@hOlDpZJWkUC6-|P&w`l(UyI95HvD31QONY694j$QZ z@lW?^<}TKH>AQdac6T}+Ht2nl&2#V?%ly0#GTe8B{xLl4uz0J-r^;^sGPh-o>fU|3 zc^nUFOE9l6@bBVnbJThNg`K(esrt;#39noZK7YV0sZ_0DX}LsYLFNDdCp~XU@7!*Qyn_e*mEVF+)|GxNI8nIF?RM>K*@WE>X8e?{{1($evPp*7o?#lFcgt+M-n;Fu>@w@4n$iv1GB;blpY-g&su2IR3*w(P zGt7&0bDCMv-BBGobIyVXGq!vz-w<2*@xX~c^PVrw6`Ncl?oqM3%IJiNUQEUOO){$M zEzTO#@kSO)osIonTJ!!Nn)cK_KitVL zFxuf^g?^`ai|!|zM_XdpZKG#> zv4r3E3!l1VmY8laJSF!(tTKQMfh|< z9G}D#!N>Eym}qoZE)qLvRJi~Cg=-ScU+e!J>u>H@AAi`5Kb%2Q@f&mBIlJ3Ge3R1W zD_^~T>~=kSUo&=S-jJzZqy78Q z;}{d+q{+@2UYcdijb?4!2a3M_>EHIdu7|f&UP;heVqHgCOKbCI2kuqRE`CVpZZtod zyP@Fn+n(v~-3r9?YF-)mCs;2Qh&Ad=iIs5u@R{-X=ikQ~56Y=nUT=8psBC{~$HgrP zU+@3l*>jf1x67L4hT4WRt$$*_zka$$Qd#nYO2!T^i8VXc$1*+?fA8D$`&IgW>;6B! zH@|;C|twTo7zRU5b zDx>p(rzaW9za6~1PAeS z-Ps3s&htDl^^Nuw?_0YR*X?oPQ~G^ujSCNFZ|ODVY=xH9Uoy3eq*b`;KJfAM8_4N1 zehB@=&FJUgwI}AL!s_?UZQe|!-j0WMEm`ocWqr$1h39|HB=EIJTxUEmv!U?#7lR_E zDK0I14UZC^SB$!iojO+8bkI#YcqpbA(eDl zH@*nr2>$mO-d_{vx)|C0TKilzuRYB9Y7dr)f9&X(s zYB!1LC&=*!`XB$?zm4Db|Ic@zGa1)5Hx@P?`Xt|UMt=AIe|$>y?(B}yX03VBtj8Yq z+J7=A&@0riXtq0d!>Z{>&<_iL>x9qu|4&G$%V3PK5Z4j54qxzm50B7?QjuC88Rwa+ zd=4fVmESh=%9Q7SP@s3iBJ0AWNi6?-c`E%Mu1r{`JjwU*t^D3?p!Uwas@xOrir+js zUGKCqte2HjMPaIXPWs}QwNi&F;>D|3&%V~stC^xSslmU$LMFgibV0=N+kt@_O;!GG zEIwg!K!0{2h)?6YV)N(tIw9&99mWr9=9F{&O$d-_(!Pm56|K$vc<=RcJY6@)9ey6IwkCEsXz3Mw( zEbPMb<1?GQ<$E5@Fxx2MZgA1yhJ+V~!CsZDs~@HWsB;9@nO*s#IA3e|;-8z|`p8JK z+OOdg-R<~m|Nq~A*yU@K?{djI)>cG(u6~yAa5cNKdaa9hIJ@P&8`g`a@hK!cQa=!1 zbB?*?e#5?mce8{uZ$Hqn;6B5D`~PpwB^O;J>|Y#anEqk@6NM*^@^@BfJUViJs=U=M zM(;;Q0ye!qRlMz|Z@_^x;eE`Vo;P&3SZh>&+|g%xzn8P%1YgtlOEyeUULYfQ zFH8JTK=BN#Aiv2*^F$m9t>umS4%xcP#vNph)4wcQ?tP8a~E5d##Qh*!@HOK;gH-zdSPTO>PH|@4KPH z)|-;d6cwcX*d#D%g3MpWLs~~QTIF+vRB9h2h}JQmcHn9Wcecuv60+edzrBS$u8`_uV^JP{*PYp>Z{vHzDdWax9$vTD$RYk$hM0i=$9@0x8$Oz; zt`K1Edr)LjTfC%uk;u0jD?zJ5y{f0I^E-de?Dk&W&2RobuH1R-K4>$q*}b3l*qQPZ zY&p&EKS=o|88Gon;)R%f%^m-4=*7e*KI2pH*;V>ynpA^@YV`?L{fgV5CA_`c{_bGq zW9~jx+i=jvnDNjIwgrbvU1h{)dQRq=Cc7rM_h5pBa6kfEm;v*_y5@+Sh82mgFY7+r zA?#rx{-Hs}L&VtO@BaVGtTruSoFK8Hw?d9lvp9>aQ2W2Rd$vrO z@W9wE2Afzh`__Py5UF39}3C`?rpd_1u9k z_y2c&SpO*Re0}f#eZ3b7Z5iG*uUPz`oGsB@t(N^`1HZEKfdV~?v`q?yWekK1@A$g3)OAoc!mfljT~@gj{4gpqB80b8pKb-!IP+<{zke=_F_! zBjb5txnGV^^d8Qc8xCkCJZgUb`0egv_lr9|vj;BwWy>y8>(acK!|#R_PehO(jMk9) zQ~CU>HAl2%Q{S1hO>aM@C~cEiyl~?4Z$Gv$KAL{SdjUI761!>Rp$~=TJcrhA+hH|v zAM+H4GdIE&>;g-b6KrJMzweObZnbZErDt>Sw8)jD_Ji{UCQYvKpUM5>+xhLs+@^CD z9hv*;p~#d{2_5Yl`@5U+kNlos7tebB)IPQy2CrvWh|3E;^l{MsT`&E|bipgrV{NJo zd+YhWO5D3QNz)~uw#V_r4zKqu2M_Gc|GRbCl6DJ=`OIGru>a!YVXXaj(!!|Y;Gt=J znv#dpj#kJpA3T1;!iclZ=Jt;u{&WV(@82)|e_`?7MD2$U`|k7)-#O)e|#Z+)&`}@UFMceE#njjt8w@elui$)xh7}SpV%ng++{W(4E!c z59BW_TdBD7K%wHl)2UbeWZguQ`rYjz4T;Qv_Q3!kAsC*^A z_t~|>E}?}!k8g{cZf?G)th4*!?4}2b9g(LOCR$tbbG9d+**1r(`>Ov8xsX%s+az5I zzw51WDRnJq5jZ3qS<+$9f8%`Sfg5{vIv)|$4tjQRCtJx4zmFk74*5SbxAsc4yy&0t zH|FKdcJK8$iyR+B74Vtx9@)8KdgJVle&IU3T^gpVF4q5l^Tp+Ju+wRI$xD}eR~$cG zEH{IXorhnKojWO~cX6KvAM0UL2bUXVX1Ax=+Cqsh)b*UMAFEHW96dgpU2uQz-hXZUz6_Ga8f6Lg zO?7dM2OgSpR;Zbz@6-F+GP&hI<-7aI=l8eYu*mv;kDclJSMVnL9Uc$=&)p?#^M0Sd z`hC{}Pfsz;<9m^0tm5MQ{m!8Gj)nIZ4b1>wfV+W{_qV zEGXcU`n&lPpF~p{`=|f^8cR=<_V4|0+wS}MIqr<{jouaJjq6zL^FOS24miF?_*19v zBq6!0vgT$V*qeTTSXln|=`po~Cjz@}SQrX#QMuK8>Hj~WTH8-D)z5RXZmfR(hJ9XM z&yoMUA0qbd-+tjx&w&EJi)#!VIt)cWoVjtPvnQ~5M^OFSFP#k^3Jx;(9X!}^KzP3E zYc`Dw4rgY+|N0}r7&Ic#dMS&Y*G}C2^RMXI80}ioxK->t9?}aQncrK)&Re(a-!X^h zRt+)%YCm@w7FdYuWV|vcJb5&S~Ddn$y=*Ir`|NkDx1ACsz$cQ{X+jKz2_1h1xAg?^m%RU#g zRVKs;Zcccj9xRtS^HOD^^X$*Pdq8dM+xfRW_|En1^C*8BC1S-=P+`G(shMp)mu_!V zSIL9P8#u)-Hn&zKq;2qM-znIK33NHQiroUyORcE_tRn2Pe6}%Ot z+czDU`sm0!UMtg+8!g{7Zk}^U7qlSbbKU)lD-wLo9IskhHK*pRU9_j-gM?zU`UeNk zZxR<$-#kxZGWeoAeVcvyo9)}n?#-28UdUtD#NPH*QX#}+f{iYJoy(0xFCJTc@2l6$ z+M2h`i5I>WxaXL@Geew^yg|)_|8HJi+4sHe!spZ*p3zG>T9p<`REkARm=j|qrxY~Fjsf;`vtr9?u51$%ED@49k3?LGPCy1KjgsyY8{Z)^%PIk4xKfmK&V z_Q(7E<@R#5=gjWS$^Bk&`}}(shX*s;6rM2bPBth|GrcB0|Hr-j_szfl|DPt_>Lb67 z!7PA}YoD<4*?Z|1&U}7h!QPT1!#&-?=fdptkK6927BPHSx~cxe?ekmr=tcbFw0E>C z`F8%}(udF7=O5RF^yW5(o3+SrpJ|cV#Qwx>;uo3X_swmx?1~D9738>=8L%tZ9(?`( zztZn)Hid^B>!rn++Y)9^V^`D=NhtKUF!@=aBX`5%_mBVi5A(XB|3_cQZ?)r!{CT9n zwBhmm{J=LNJ37Sq({tT=e@znNt&ZH@$4%`u_k+U={WY#~>|U@pZQ`evwNt*__vO-U zZ9H-A+jF_UH{&zh9Cl17x8Od<=i*=aeBPa}k1KZ`t~~qgE{}gnT5s3=1htJt3jUvR z&s~~)Vr!Qy>y71AyUx$sXFeNLi01C^fAe>bEgRFxgI#ta8nFvfcQktVt#JG=T7T?} z#tMnN8y4r{WFIU}VrY5&Wy8dq>$jY`v16ud`SqhE%InRaEjhD?^{@T5;5&yh<*V!B zu1KF-=kYY^p{Arj>w$lhCMtIQc)DFDcl(<^7i5K^gxb$;-#%+mYmX5#Qw!g>zhNTE znuUkAJp8n_GE+)sGmn|9<4orNLZ|=V+Fs$e|993=rRG<^OM;p`MP69UFiZ8WTKdRR zec`hUdZDh19!gYnCM5<;P*#fMnB%3wDQuY$remkK-qNaw?dak|FT2DzJswE39F_Q( z_9f%*!*lBdIn@$$B=Y?ir_EaRKI4X_qtH2hrPc+m9qn>fB~RNweqYo3?VngI*WFEc3)!0z~OUSaXO;X&-ZG(M}dJdMXIEPVd88LA~bvi%{sX4jGSHND%O zw*Bz9JMG|sIj1V}nCCVg4tG2fy!T+mi6u%8Y-B_~ltc<{o*~0M?{JPv{?o*{F3hKx zcBP$V_50pB@83=l6XsnBMewA-nDort**b=O3S6pPMkB;R!3p zA=?9IVh=37(J~=fTzT&o#V~Ot2e+3CD;9qd|DQ9FVUORh4HhY!Z^B+A7>N|^J9yA} z%Y=}_42#MRE6iY|uS%q0PTuWGE}FOXTr8eg3Io-_WfgtFNl^|cG%YAzOBFQI?K zi?96T?<;PNFYNzE-q3yj{>zjp!M|D-$X<+h;FDle>UDg%|G$LX?^^cn|NqWneDK84 zTB5npx_Ls=@3$+(XQ?`H_Agm+f#FkGf7?>Y52`gh(^S~)K5RUH|Mn}TiRJRAyuwUG z_AwpgIN;kX5L1)4`&V)Ld`7FieCoK5&28wI+*^zf~c4`YA#|L?aF8Nodp_}CdB!t&pR zGvYd8D)s!E-~atIDX!!a`_}cjbE@CFoSBkcoqj*&*YoQ|Kfk+We~5GbWjM8Nmhug` zeMywwaOvdn)QzBph@e%E@3yU&TWz4SI*?mQ$Uf)5_w35;i&Qz*?r%Ty zy(65{r!)0I$I;rQ>C$^&N;dy06}8;hSurV!&&O@)Z;TWgIAw=LVn*EhLC zYSE(g3a?(qN>`q`yLwN^UEXA%wBe-7Zx`x?=RRfcf-UskH({Vf7t_Moig8O z#{55Mw&}%>=a;M|{V#~wxG|i)V2RHQi=ZETEVs`byvxq=LvH#1&%GQLY0RBfZvTGn zV{Y3KcJN5dok&>;mQDA~_#U`6>q$FlB|Py^@H+b7Vf?Y*_3~%`%E*|WaHv@Np*-M& z%AVZq-+viCXLFkFc$)KuRZDC^@xLF|i`tlv9@J(RVQx7SY<+OLW5FrMqA4=C{l{(h^?M$iUS6Uh!J1pRTvG7w2RY6;6J$2YIV@)0 zm6P?0kL7>wvwt7Vb;zSq6oU(yR@Z zS&rX-88=$L7wnwr_$(+x`^T&qEB`)@eW>exU~*OaCZ?rT#umpEZ0{eg;Vn$D32F)d zT;ELO-nn`Od{1;f3B!^e=y*jd_W%*nU#yjRt z)o0t1mMvK_K}N{4({a+RxqatL3jR;lSJ|!j>}bLn7O}}IL$@q= z>9aG;{WzQ8v)8=O&faw67vwk~y;EscE&Jg+f#(;ir)ExnJ$urD0=1gxmTu+=EKMz~ zZ`HH%0tz>&SXy{&)f73H_HFBQS#8~qns1mJEpGe1j(=g%IA`lw4a4$nITj1vPWWm5 zuhrFN+ovd>OR_n6JhpJkqq~^dvs7T;ZuN#4M*=`X;xM%_M=dW80)v5i+75VpNJJR{cE^ZH~r!RLoNp=SZv7Gk3i4U#RKe)x9EI{X&xdUMJ2SG69@D1{z$O z|J>fRIO;=;mv)BW(H+ij&4lcZ-M%lK`**_uBTjSBtxVvV@Ga~g8u;HcFZ41!c-Q{m zOZ)$3A_fIXe~cF!JI*p)^n7`av76_?ncSMDf=mya*F5yPD`M3kzyAOK-fjQPXaBy_ zt)~|=d4uMWW!D#W9pRM^Y@T=U#G)5FdM<>2v`)!?&)iU8HDQ;@g9kEv#ZG)Cd>tqD zY2Tbs_Tzv7yG~GHbIT25b_LG4W_)v58~OEln)G(MyZ}wq+Iu-BaUW+q-8`W+o}0O` z@b>Sti^@D*l}^(y6neOJRxzKwd^T}9YrOQ|Kb70RKeUShZ72DDp+Mj6zO!;R&(Yuq z`mF{Atfw_yTBdg>Dw-eM-x&X}_1 z=$;4^YRW(MyL|hBf+Gpl((KX-7ZMrE4qloq@^@2nNt}`L0y(4SOw%%Cyu!G}&onm5 z-{WyS^teYN=Xa|{9t5vL+^QxjCU9hQ@P`B`~TU^D;LQ7nI8Sa__yKl z{2CdLy-KMJFE2%3eWH}bcwmEQLIjVOM|zlY4rs(bp0iH>ZC9Py?M=57iXJ>SEU=WA z&Ah@NkBJ09xa#_!7@5pwWV0<%b7^X~)f3oL}! z=Q5m-Jrq>d-|(gWe{V#@73N0k*Lgi&%u4eXSX^OlH2ugU+1$IYQ2GzMeA(rD+>-B? z?yH4(Gwgm(>UYb%D>C*z1_FZT;c3be=epFp$(M^)^i;iRCTNqWSCDZ=zs8Szo(yB z-dbm)$&XXIE-)`-mOrhjxnag>`7K5&obE**AHBG95D8Nj7^8D%?^w zJwMBGtchXrqi>xFM`S+iDY?mTDPFJ6Ds{%fwR7e8uY`(p7UasEe3vTO>$mM@id#h* z`;kp|xY^iOT}gZtY9cp3=Yzao^cI#yGyDF;?MTp$@%~@d+;K_H??%VVSz+R9A`T~g zlvH8;>2hO{=Yiu5Ga7miPgr%(qT`pJMQW_ooio834}H`OOtFh7nf2;nWPReJTZhDc zpAzz0QOxETar|d(rK6D-r`CdUmRA?Q6u${7oVU7uu|mOe<}SzjmGbOw8~CUHa{3kY zOe@*%`0e`W2cPf%Z~EL5z}#}aG5mIn40GpwU(n#P@Ph(93xn$uKC?4D1+8Q-pS`U| zZ1dOtzq}rNs;Zo^3mzO$|G|Es@chL2$8Yc5*A;P=BjCz}yoLw!-*?_rSS_EJ^D5y% zjGfqq?eFC>8tpaNnbKeVd0@p~Ui0tz|4r95QmVfH@^n045%P#jPjo}V z#4kope9FIO=rAVnIrwkAP@q>4ZJl82B>e8`!Ml=D_EV;O-YYIs%Pu0sWv5@+o6lcR zpcnmfmcRiqwv(~bl+&(D?O%BHHl3X7R+sn zWoOEH&)m#VuzaB;o5JHip!IoYWDJ$}>OOw+=WWA-Lg`nA9Xd{CUCr};<&|9A)HDH9 z6CR)ax$VYv`^7?Swc<<<+msm!T@`X-yl4^?fHJb{@xygZ9jA3KrtBg8!nM9?V_GfA{}y&In5h-|xLTe5{XMFGe@b zF@0lm@JQ~T+U=(g8#xrL{vvGoEl0+X^?E*!Rfm|!?+^DC@;iE2W+^Rr*SXp8jwExd zy;;QeC;P83?*8xF{cFeSKh{@|#Im3M|NgJs;$^)&CkzhA7%SF@G3~r^rMZpcf!D3a z3^E%oHZQPhnI8|@n7nZcyUv^D)%q41zaMsPO22vaY(eIA3Fci!YOkAqPpWHPp?}}; z-0$~aWa>3dG(N<6Wn8#kkRY-D{YrL`mYp6J(`GlVGqk(TZvFht|K#{>OBpVI>1|%P zd9C1kYQaLIpL$#uWFHAeDql?O>e<%twk2(s z=!|UrioNZp`Ty)?y}8md-Sx=l2K6bAvkbPcS#iZCk7uG)Yt_YDp@D7FWFwd*=gGG1 z(qm+w9%rVbIb-9L1^c$M>iUF>Fnx4+ymQ7@QG;g|shgFoZKg6Fe*EqCMUM-f9OYLg z?YXQJlauCRW}WK!DU@4!%j*k;T*@bQ@4c!PAY0M>>3{7K-;dYI8$-( zr;=8s`wf?qFP{k-erBClvgq{T{>&dayY1$Gd+PL@JMI3Veasz2Cw?_16fd=TwAZAm zG@#WajJ9!>7X7>oHFIjTM>X*?| z@yUNTlzR!Z_;>8sVG-I;^sLdeDdoM?L>bo4PWmb=cMOFKJLnR-`vLX!`PMeVHgkR%vB9C zJ1%`YcqMaJL)J0%Jx#wP56pi1MT}9TO?#d2h7*S790nHRw*B9J*2rkoy79RPJ(}d; z^P1@($K{F7zTac{)|yh&@OXXOG@cVX4kmWYf1Q)E%SvNn)#=%yyN_OfWX0TQ{Py#* zli!>7E4Y}x=)Jy2`aw2h)9fq%c=}&7?{(ud{+)PRVZHGWks_Ptf7CChoPT}%cJVeo zg;FVIXS<0TJ5o4reO}?r+7!Q&y+BMwu4mU?5rflv8=l+Eeqb^CeSrbXH)Bbz50;Wj zcSZhn{ktXCeag4xeKV8e?wcF@QpC6M2^+{5v)qyBart9lY4w}6dGqXlYBehLLbGk& zblhWYusr`bcVFPapZovTG9KzbWZ(9~>-+Kj|2bRN{_oxMQ@Zj`{{EspAtjfNE_Q1X zU#S+^wm?f(`?2r#8{pYv?KGDyk9z_IXMX!sGUHa6yYA~ZC9a?C-t_PLyCcoJ-=VtI z{}v}_-$O~y#N!FQTaN$W7MNDX+*rtbqgTQrP+DA^DKqEry2Pzk3-Y#4ixZmMv#P$+ z^hSv51G_< zJQ66rZK87Ge#bGNZMW72x*axt8o^;Z=T_fB4JDubJ<%VB(QIBEPe=ZU@iAhC|Wt#sXwo{xuWsgp%SOhA&wsAM4Y3l4@x78?^ z_)W&pR-t#>wPUyIuC~|&tXU$a7^=cvSW{;$A1hsZwd1z!KC|CHeAwsxugOoh=zTEp zPtR}byAQvao}akwe{$vjmV-&p=RD5ceH^qq`JCm%k~NL6CT;m-7xv_ z_0IX#KW^tgUUUEYEatbro96f1Js00|@QBRzE6IlIW0JjC-rRJsEYD%*Zt9;bpJ4H= z-a9ubZ6nX)eEWX8_ue_5Z9n)oJ-uOM_uTu2jQ`Pkch(l0E6r`p%;%Xq{|VdA|DD|y zlH&EOCFGRg)#*I)OEuX!e`?!q{Qj~0$N%KB`+J}Lv%CHC^N0J)FW(_?w_B1d-*@R z+aN#Z?mYInyz6$N`{8rU{h)!9|C|e}^B-<2-oNmR?1j~~AL>pp{M~mjG4=Oue4HLmK9aZigs@8DJX@#44p%J1vbFW4WRtMc=@ za`7_Fwo9_lHC9PS^)w#w;P|I}>Y5wp(besd%eQN8^V;F!Anl?daQsv)W7L)4DT{1_ zO4!eQ>X4V{>XCkWe3A0nrJXg_UpbuQS!AMh-EV9>_$pqN;mPCfi_8m>eGg38VK9wL zxAS1wtfIwTZ22k^tr>Z{R5^-!9^AU{Hg#7?>730KtO1!8n?v&!EDTPW#GkaMb;?>! z4L6UHxFt3}H!eDG@WUSk)sBCw7Oh?{5a{L0x45qNhxL;MkH3cGZ|~rE{=VN#H~T`& z26ra&Zkz<}cN5)%!4m&*t;54XgKc6<8$kN%`6Q{&DaAv&Zfi3$H!@Sezr{`eCQo zy^@3ysVxq>?o4?5`0W0simXHB7PBA!`|`ZWt*+3x@cpyb%^k6l&ENk2d!;mWn&|$n zdx`3o^_v?DPT1YJ_ejH`dF-NwgyblbthqEFZr?c10Q*NLxVJ`ussE_kl) z=(D!<%|8#Yf0R3@KI!LOmox8UWb{{e>5D&iI56|WiqH8^j&FSTukMd)%1k-5SNGqG zB0e55k#{^oc7f+jTO%*u?LTYZl*!ujId;<_sfBwYRDG(SB<#^q-Ll+D&Bgs(^g&1G z&1`B$Gnd+2^ty3Ix+c}BHS|@l#)6Gf-tzOExIZp_^tRJ}M*Ks@slU1QH3+*OXyTop zIgxeI+M~}u=^hGgTe0QF!z@{mMXDmK|4imCl|JO- zUX9YYefY;7NwF^bV_zBX{$Bk4o$I|B7UHs<_g@{qf9&3W-UmMSALs77Jg->l-p%K+ zZF`d3KNi0&DBjI-gU_~a|Jo0J1+5JaD=hp!o_<&0d(lmmoz?zv?*9Jg|I9xB$Zc8s zcY{xY&2P;J8R6vb3wwB3dStZUwQ(>W^at%ZNP3*`VCLrS{d=CXU2JZecEjT9s|Sz! z+!$uQu<-q8{73D+vfZJ3&vWFjG1xL5n#RZDc--KKjKoyVi%7OC*GDXl*s!?}6e zj#Ss<5j#1qe=M4CMvUcsN8??V^ZS^Ov45}-mr2M>nE4@|@eaqncE<$u65;ZC<@c3W ze(dznmy=Ky-q>~E5qEYT&%tvK9vVyiQFHq~&F=P-%J(<^oqyZBMx=a0;Wdv2^(VR8 zE$-)i$jQ22bNWS7(;;W?Y4@1&nk!5l%``r*tto<3DEo8wT&zDLR_|HK$|b%n;@Irv zx?g`U&V4_19p~OzyiV&sZohvt_it_QlP{}wIq`>^)uz1q@#M&ihu zW%VhC1%|1~kEdB5N)`3}I$guVvB8+@j{64PYNunD<@HQFn>i|j8Vf~C`Gi&+oWJ~b z=&Hy+8yRPPTY1uV_o*P^b;@Q-TNw|37KoPFbUx#D{w>u#!TjDv=U<%Z3lzAelQU`V zeIIw9(?4$KPna*(usCTjL{(XtH6%wr$#_USUiQ1CPjYee$k4x~G zRDMuTc;uwta%{czg$t7yKF$==5J?a0QRS?=`K)>tJCBq3g@O~e-*YxM7JQy7BO|(@ zbjg3FXJ6hP<2ZO=?!ode+b6QTYhw&Q{6^UL$G>ylB{O?2%sbY2y6Imhmls#Yx|Ssx)oO zlsa*Y{h#ga-;YgfV~jYK3JJ({a?HJOMD@X|;^_w}PTolK@NhY%a=$S?Irr>)A))z+ zT};7A^Y|Vt=J8#_{qi2WlBiLWy};E21+I+=1|qeU>#O|FHh0MTmdt+tRme#9f&PP} zIc!`pc7GX8JFGvDu>4hSW7)y3j9~qT_fJZ1iIbe4{#-uyp3Uz$`G0R3eyiUH_+q>1Y+z?P5`OSVasT(-^0hambI+O2{&X)f;vBE~X^DH%r_?ICxNJXezklpr zz3BG%tCE?^D}xUCKRR?KasRZp)wO;7+dyaL{CdCb;7LSv^zx}c=NU|kp8biy> zM#q$wQ+h@11mD{3Q`x>Th2c@^tv6ww;i5{aOZXiR8s@K>H~mq`jk2c}H@rb=+d1(BDH%Nv`b|SJb^c_Rz#t!y=>O_i5%<)vIb&UCX98dTO=y-JEthy;)&V zip}h;HX-eEemUEuD4Ipw7syaItz9~sQ+s$<%mPnO-am(Kld?VzyrzOU1>j{hPX z((FrozAC>xcCVgu?{j;|YbScpeg9!j5I@2n0wQ0Ez+ z^^NbYu(KZJwvxy zGv3O^i~gQoQ*`^&?=u{4r;54c|KBrhlDxtE?E33BUWAKRS5MxI!~EwlA5Ld*+E4$#RXpFyJ^BC2 zXzN2&f{)&=J@DPxV4+=VL{`rM;To5lA0O5FOt+9Zx7bQtRP@YJMnkohp2qhg3#W*8 za>~uRzH%kwVRf;XS5x0k3AyOVBv-_1Qe|*3&LC~yn(92}CcCd&e%-Nnye2im<7YO@ zGVXPXHJiU*X}#`#>~_()%U41I?oIUa);VDGEA!yQKa=C0z4)BJaXaW>o!)KlL&@3Z$?9p7hn`$zAFdinqNFVAOZdh9sELiI=Q#>GFr=RbM|IUt_}# z&0Nm=tA+nmGkp6CTO6$QVeLXzh&7HT3pM zF5*1*nc>8rOdqbY1nvihe$1@)VL9A?OfM{(e_(gQ`U^{2_RF2UT_dBGtk`A2#}&Du z!2bsy<57hjlgw^EseFDr=?5QIy>Ig+2R74$hZTAiCuDY{2MX4lk?AoKF6^-R!;m!n z>UGx7Kkk7-@c8YT-hKbfKmWL$|FE#ZLN)i#4$vgfq2*T5sjQ0H?4KL>ADLZPe?u7L zb+g+$-K3OMUBCY4bTQgzdH%GF*}r)=?3e%la=UQNuK%hrWw(wtM;ZRry}j&3=$aDG znk>*T;{E(5=`)`_7yWivNj~Y6{{KhJ@i`pcPD`pSHyt?o)@7cH`7Z$zAd6EX&2`_qQB8urv3!)2b~S_bl3V`g+u(V68$| zx7YIfEK_HF-v4o1m-LU)rTpKXZrsaqT5=Es^O7y!nhr=$;=R>p9SokKyyL-&sGQ?gYaR18<86mG?FI<{vLl z|KMMum8kq9;&|A!`v-ti6{y=c z*0*iZeAw@#zfWR4S0Jm5tmBp5h8Knl9`Ctf$;f`?{4+k0UEEC0*Za5qv-|zT?ELm` z*H?&Xuyf5}my+m`cT=3i$Mo}?qNLE2u6;Kh&P|doW*7P3_m*8m*sjOZS$V$bzVml_ z_x<_GBcrEy;1!>Ss2S&e^%r|$Y8##;JglC-r*`{^-VKGq+k6a7IPVtBe&4(AN$<9Q zeLK`Q6bh%m>)&{)qK~Wimyu_8clZ*I>dTk=Tw6C;Yp{Jl)=*ut%oH zC!uQ2CXJ3WGhRxEpLmu1`Hk*I)oo&%fBu!8pMLZE{7cbg6F$1t`}Rs${N|3DqHg>* zw=FUFrG{#_$KLfkjV%-Godnp8H=DaF9F2&yuDW$MVwTfQw*Pz9ltliETl6Ax(RZu8 z{N^ne7rbZHoyB~Q|Fl`h++9I#+8@J{noL-9=H6##OI;y$rkM5ZTRHaEawc{kG#hMo zcA33!30<`2t&7`=o+I)d_1?8N8!tLC{XSawKI^={^O?U*-=p~KlOOr#FOU55ukYsn z^Upth@JgsTnf`b~)V|EO+7sq$*yR*mS??*6^7fVb_9ektIcvAv_y1$`>o>-|VYhGHY%}He zh1l&EPA}SfgU{aoO8<=w*4+Yj>$tz2fBrkeQ&Evmf`?;Av|`q`gNMZp3Xfm6Yi!6f80NQ|MKSi=Kq4*>Wj>7|4=`9^SjY4 zfkJ-vXAPoXWHN93pVxA1{r-NN=hk^Se>c9LGih_e&NDKOx4~=h=SFuoPg}BR`z~&- z9ectK7T>s^cjET%7Y81h@o9>b@t^(w=5fB=slx)XcHfiS*?9zeJbydHGsZW|?KW%J z$FyHzpWySi@ekr3u4~JG|L}I=x>lXp6Sw`n(7XN5zutRCb##CJWxx6T^RJx$_Pd0B zHT<<-cJSatV^tM)LE|_7>U}3{=$)Vb`J?K#+WF^S=Fj;=lR2D>*@=(t`xoe^VyH6L-&|&a5v^vn$^#Lx-NCy@^7~$`oHjgZ4m0v zbwM{Hy0!Q5|8)=UX3X2-nWcO~GcaGQ~4bRyORAcx%>r#7qbELn0@NYb@ zh|T+pZ^pSCc2U6vHf#q1mhHMR{lvv2y}uHdI<)@rC}muhF=T8B=KXYIMSVuct>aHs zTo3p;zf?BaDClKw^iXq~3Tu9t@H*>DYH#)0n|qctYSrn72u$)@>vR31cU|bTTidn; zUI_{7+7M(SP(1&4<$(uAE?h5AMEc>mo94fU|`a>>Oj|& zWX2}11s?>=`zNUT88#eL{3F{gVXD89)2;V{4gdF-%yZZUH&n>Kzr?Qa+y39Z<^v9o zu1bqx*6pwujWM&`K=_6vRsFx_U^@bI)rjm*WxHFE5~FFo*IP$B>B5_8iYerD#r z=0pGQ>9cX{u;JmeXK($#C60eCgDrd0|2Yz~zSMAs-LT>RuEX54kDvMP`-Td=tY#+W zicUT5gP#-F&E|;oZdiX$ch;U(uPTw~#Xrmq_UI|3awpvLc7GJ6?YQT`nkh_;AszzV zQyqmb1XtVk-E#_AKy6EYR z>&4bdFjSbx_jUgZU1c3^Wne3_wYpe*#;8(PgL+JPx!T1)R5VCO3#T8d7Jzj7f9S=Z~S-tNW&vLe&)aP zdzm{*vL=5#%DRsCn&$&4#@-DT@^1?)*l+&-+I--D_G5?N_Ww3A2S_Hdsvq2S(vGbm zxk8Tp_Y9dR{`LRgH5~oNXCj~c|6b&>gXZ^U*Kuu-b`;RdOE9cR+Y8=dBc%m}a_o)& zWsL+5#Fh5dGpT$3(|dV~CrbBVh)!ODsYi~+fd_$0_?#7{HBQ;K^JbIh3?7Aj%>{>x z_*g_vFdOtUH@sS0r05{@Adz)*vhfcI!DzD|{LTOM_?sDa7xBn%@K-p*?RJ;pf!(bW z2M3>k>@9-FPO={`&ua&9;N(0t%NZ8hOH-v{%%8`xr)&_F;DE}<~K6xwd`DyfByA=#+MWG>_7j~4id8UxB1uEbf@0tU(YW-mg5&9 z_OtZcFS6^A-Nk>CLAv0tTl&p!JVG{qTx-Q!BfmU5f5q)%!0?gy~+P8%-Lkbz43<-@2`$zDnRPN5~J^4;I=B{|O&Fs+Rwi;e<@( z{9TNjcttKaYOo95n$P*5;oFaB*9|gXO$0n04}G$};K+Ni>EXe!B=+<99fp#>m@8Ue zZR3(;)Xm~e+)yy@;?34hp6#Lf3wZ-?2e=l^XO-({cvPw(n;tMPOLekCsO_#r)^5ib zZ8ID*Zm(-G3%3q&|53!Jn8m|fP$R(_y_exz^Bjqt{tfxPyI%ay5Upk0#gikWw#B>Z z&~vkOP5l>K)%LRGF*og6)Ar!+1jdUQYhQeS@`|JB*wr7#CNiR{9cN!C2!HiR`&Yx= zFM`qPjo&+G2Q_Cap1Q;OYd)*A#xKd1t;Gwbzn1pMsQ*;j!!7NiV8(vHG@`+3%DwH* zYhG^e3})t+4rLL%tuy_7*Ks-N-0n}ptpODrGPMss`M;X^Ep+{cOBxlyUo&0&0~ahx z+w?1M+O)2=(Er|f=}gB?H@*#8>EdzAvt!TwDUw%1e#%xxeAlSDaG2G~xX!XyF|(}WSk>4(pP9G7f`DKjHB7P;mF2bxq?xHCO?#ii&o> zV-tsh_{J}1f9~IM=jrJ;Pg^$4dZQTqv1R|xyRoOcm^gl?bX&o?-VG%p9sD-t*;h;Ht zge_kEMIPr2Ird+LG8}5`>ywW=wAQuz|CAtHAZ<1OJ0m zXNMR~Yi4m*dH4O<4so-t_YN$>C3{)uW)Pqaosq(LneorT6ueZiGDn- zu(d7Seo6nCifs$cG$s2~w;cH7=XF>5zvB_7D>ILa=zVJUW{v3MIoXwX{`1-ee5}XW z<-#9tIm=#uhAA)F(M!PA@xlMsp^Oc)otaE@KU$wza<;Zt!a`&rQ}dzvYcu53|CcpI zG}O4Q=)NIocENkvgQB;tCSSJqyKyF;l~&KL;+o9)IBTo0Zs5$0WkIsLE+#EFB^*0@ zO{J8b!z9IoVh*nJiU0e~PrGU?by7u3gvM?QcRY6>^M|Cf6?bG)_}M>6Kj-USxs`Kh_v7@vayjl> zvO2UjSk|83euZV;mewSF_j!Er2d5-SFOI5`&wm|a`Bn1pm&kyC^^TVX>%4j;y_eV} zF$*N7iEXcb%g%FHVOBfS{h*4g>?~fj>-CCSC+Oz3Uy(6%<9^05U+S(-i`*Z*Lnp+x zFY=#l+vxit>ft%AmEJ4g{5>JH>?Es{miZFDH|)|PrnVYf|DGAPy7ni;9-M${^?a~Cw83biqQ|Z>R+(yuZs0>X;2ziX^{Zs=IO=;o-ffW`^5fVCi zF2WMJ1)l4?5B!jSf57aG#OLY-e*+k|Dm;i+xX?dEMriS)KMP&h>`rOVPRz3x{4BTO ztj%ohf~fPEvizTtfBe3m^V{zHzUD^bhsN(MC%&IQuXpcm_8nfF{~y%r|Nm!pdrt0l z(2);!_iG&g&2ZutYaLtO+lG`}ru_$=>P>wcyCHG6!ci;9eLbrB0aG;$v~M>&`0{C& z>W;HwYmRUK^=f}#_#@l4gGaJ6Cf&Z*aFxyGzJO2I@)J(W`fo1L3i;2vj)&=rgida( z&|iUrtEMP!@h_d@RQ0NCq45RI2~4wtop?+$cBltC$-mN(Xv&&ptrqTHm2<(O^M%ee zt>SW*(o&wHSt@@dZtQ(kQ~jyb)c)kHrA8ZrX9v5?*kQmK>{8*kpgCavuAAETmK!Z% zo*nMkn700i`PJXArp>Aj^I4O5cI8L8rmJB`s<`7Kzkm2~cE2&V%&lE2f94(ZyEkD& z!e*U}kh?XOwSHYu6ADdQMfjv@H{D}8Aik!^-6QVB=69=hNwnN4`e#vdWJ=R_*Y$U6 znl*m!kXko)^XA4*?yeQP1W(lPDSmpgMMk1!M|eAQvX8~LPafbuZPg_|um=F99!qIP;i^Cr5Z{mOBTE5Puc7lwcI7{5EsC$ZTUqtzCeT|*t(D9{rSHrT4 zo=;m2Kd@pvaP;ZQs~fBXj&6JGTmR8bnT_S~KDL#!8V=q_={+)&&2RFYhxx8)?^flD z|7mJDcrJ9o(X)MD7qp$b@K>vP)51mf8w%>~y8gc8-jSi{etD0q7Mq0Q+6&nXi_%my z8a2PR# z4>qio%w;{t6WaD7^lPk1;-;*|Nt~Y3!xaCdoGD^rF!AW|z7=HKe(de0^A|TS7GGh( zrdrjwr#WrG*)MimrPZP*6lgeltQ6LL&lr65;HUcEB@%ocXBqRgmo+vPA7PfZZMiFS z+fjLgOTv__TeEmL3b@4ctymM>Rwo>2v%c^$IIu)3>%mX^zso{gEh4S&*gNi8*DUbx z(}F0oZOtqK&5N^N7%gV-jCO2)(C+xq{_|y5_m9~D5-x|*q8|rb6lKo2kfPt*&&Y0G zBDulwUh|~ob9obH{S!Dcts-iwt>#}_t=c3F_uo^p-R+sw>Ku}?{nx&@w^E|#$dAG+ z3=eHYnLD2;DZkxd@+Y#OEwyQ7#00H5V$b&mG(C~r^*s2&>gzG*Z--b1a8F47cjxr7 z`wdYI$A562f8PCjQTL@&PQU7=aQ*q}m0{ukt0}oT=_BRdw4kVBXWFLyOo~=;~}+ z#`Ih4gyDnrS90iHn_mxH2-@&zZkAUJ?H|ZPSE=U?H6jncAim3ETpcZAEtOWaCaVlT>75ea#x^ z;orDJlDXsI>+5E7QZy%?S@cgqVpqb4<*T_nKbVWH$QAcKaH2_WZgFY(3WKgGJdFqT zB-~lu+*p1v)J@@G@#gF6a#yITDnCv7*WCXhIH17Q(EOy_!KC?l;p{?Ens(ROUp4Sv zxv%NMCn;RW92UJ|SB7xn`*rz6&7G`8J9ZXKW8uoo;BzxpxVS1qme(;(EcorafQTNBq}`&eugiIg>~*H|{8Bu&uy=C>=;TGa&R%zUKD82RY@owHSSf7zK{d4rB*3%czt zxv;@sbzy^A%sH-Sr3_~#2&=B1_@d8`TQ$#UFWbxw*@7*~?h+i6RZG|BvQ6I0&v1KQ z)lRvX%6?x9-Gf}7e>>BPYP)+fTnh^R@Q5WOY_^@BFUGa3Y7%p6MS;)>gGi=RwL4>GO)34cNu^>w;ctUyY&hx91%RI(LdAw5Ih`i}c1u@!6jE zo&O>+ncKMj`2Tv&d9~ZEH*DYBE;ga)t%?hu)TLQkKV%%|zg_wJX1qXiQ(0Ao)}H$< zZ@vp#UOaEztg!MO*S;HEJ`&#_SO`nLzRztCaX$I-HnC#wmidj7cfJQLU(KtWxA^wM zXUkju{^gr;iI3$=*3J97_VATtU7581<}W_w)ZTW1i`=JI-PFEe5OrLhxAno!KeX9Dk(m8R}5s-62C?j3bHpez2M!%-^~!q z7wNW8p10|Fhpfm3lbfr2pK~WqJ8Tg5@w7>Tem#qC<3wGv`Xg6jIIqd*uS{F~ofw*K3GFL?gcWQn+iAd?Q)f=oHhfO_Zf_J4PAJe> zB64L`l9w-I(;3!n2R|eTKj`%GjBmK8VByA2QKV_D-0qX`?m`ktV&9_(dT$z(*zU$X4WYZzYB$( zGCEr$>{@Q{N;DkbrJI+);|IE5$3~vHKOy-P(~77$=Rvd5jLD1l!WL)QiILNa@j``1p7S;ZiiTa1% z*WZeL?Z~W*_SS+8ItLrI??@c9xxMPP%tKDrz~z0jd5(HH7+!BXXjR$T^Dn44P(aJq?s315 ze&*#x$;}&IE^m|D>~fjV{P& zm2y3pdBWCAZBDcrt3gYS!o)pKG*zDV^ETyj%q~q5Gkx^YTxQXo%7YtxrS?|8u;jkm z?da`XrTysf1W5}crtHOrejScS_&=CEb>UvOym7{nnX@IE9&N2F2z^}D5>&$@Gof?2 zV?!Ft(K!k=(_CbgOA9-{KiqpjhJWq<_v@bD_npF&&L%9%7Btz$jI$u7YOk|6d+EK! zul{h}uRKu4!C2cAE2bg7$k3)BIZ&RrDZV+T@M~55m-m}hfBUr^G+1K9F8FUDJJ)>$ zi@+V+g8s{vTOVI1vtX8FeR%a%$@6aw`*;(ky=IbJ$zF8L^^NZI4E>b zzwJJU+!41Q?z_03F)!4(d^lm6ThDJzmU9}lD)D_EuHEETJjyahwS3*tvsO>ij6Js+ z38e;qJGp#f^Fnti$;DEFZ3p#y&hA{P^jG=gVZ9>vE&uywWnb4bun{Zci@VHaCDmwR z=u*4ygt3$0=6|X;xjkf**&n}pz{hY=ga4QQ<0T61Z@+U+4QJdCo|Wo#_2ZoPVNwD< z7aHGuah>pSj_hM5X^W{l=jQN~ayBys$jYmxZnL=;-SML%=JVo$Uxlw!44!kCZh4XN zF^GG~d$I0&+qpY3Y#y#iIB4x}cOnav=?-bET;>@gexBEIV=$+hM8o`?-zgy`%WaHy zXy?rQk<9WrZ$;wvOJ;vUl4TxTJb1+C#%j}P-2xSvET8jJru+>!b>jY>h`B$K^X++Z zzrS^sznGB8^7+mRnR7QJ%zSsp?LVC3cR_hW23XPb^tR zn&t7V=YJypz5LA_Un^=b_xoHPj%SA^Jh-9OA#r%c(VCmwFZo3hnyAK5%p2mF6{NWm*GvX4y2Y)VL{cyDQf$uj132By#3VJiIH8SW+ zda^THCu%=<#kudpkEEvDz3RNd-`GCPy|qzzYtby1Yocc~n`U}7woFLi`S3%E`N01} zs{Epz#_Vf9i}W0PV852Vp>c~G6Z0(|)fGQ$7To<-9{uoXiDJL|;g1R~;jawX8~z=U zW8yHV;D1}g`yiodg@huDeaESX6~C^nU;ZFP;E;F|!yjh%!#CAFv@o~7Ix@rV|MKF+ z4mZ?eez^TU%FPsPA7U^g;`4`N_lpxdmNQGJ@4gyy%wkKM+3oKYHAYMoNgcxT!-~JU zGDlo&-;m)|6ShREBH^H2bz0R5aFR^U-Om$tJFat&*OabC!*?^1b9cA>dh+MB$m8!N z3PA!A#?|+QOCr8r=rPKjA~AcygRRY7b|$6{X0~s29schBx8rLYhw$3BuI!H+#IN$^ zPDq@fX6*FPe@9{C8sRm)`-Q9<``_=~V)GzJxKUpCL!6ypf#J6MZ87|}8Khruag?|5 z^*=vhYrcQAyoAkVL!(oGtLFm zbvl`t-!hz$k!j|fDc`1_-x}As`HqS` z!RWZngHP#CjBhI_54?fsG`Xj;2{`f%!|L3~+3Ct`7DNU9ac=UHVJ*eOiaeQEZkS!#R$DWOYDZ)W$ z-{QyT)EDmyJ)p*%S@AoAHQ{IY&(DfJ0*M*_#F@GRcgaoCw%}*{S7Edv)uD-pgF*fm z`-(pvKa53vKiA5Yd46tvaEtNq&&6*pitPSY^>bgm<`bpxug<$)8vWSPee3#-iX^7O zuSS!YS)~pf*PGwvTz>g{5nqCSc5}i!n;*rj`}VC!+V=B5Pr|&)t32j?<`3IApE=wO zI9&1hJ6Ga|Q+qhO&u1uhwEa*0zU^Dj!tFeVE}Y%)oiD&wU!JM|^XXn0Ma4djfI8lb z5Bgjr&)P{e%>DasMdr_mo9{iG@ahaVrn32dEKf+!{xSzrf!;Wwb#akDSxhn zlIX^Q#k;y#?(o*msy4OwX2^Jak4Xv#Qyt%;^o~C!Oa(K$PqO;+xH;N02RoRF?CV}? z67cIkFVAP2ThAW7I9T~`y;b0)x)#k+DTDQwBAi?U1=<$)PGTxf^maZ_^yH39_Zf>M zXI_ibhZAP6n5+Q?wl~|r5J0&$-IUUkZoz!q^Gry$ zTsCW>RmH*cRkr7fmK`?V{NjxGVll;;k~<%-J?Gv$N0RIKd!7T+*aZ#z@38)VZ2jQq zhkGvNHv{H=>NRvw_c6b|{>p^zH9I%IWze%R{5!vG{!VL0#zKRGO*yag_8k;V*ZRM; zuUU=#jIC@ z`hK@e4fuawR{W%AwBUD+DbGZAXg2X!@iYFb+K`%hpebg7)O6+}_3u`dw0P@(EL+Lp z6yN@;Ve9;Z5jN~UR~<0ev8PNmsdclU6f1{`zMgDD`qk;RdxE&Mcsk1YJtYYxeSLMILhe!x zzc;UHyU$v+u0ph>#-~Va9BXVcaQ`ZL-yt*y(zdPLjD8nY!P#XRr$Y8<;Htn_BS2{g> z@V|ZP>X4lemI<>m-&+1LWWh1^QwQg$@Gr1a|DW>t*p3g&xDOuuSy?7yCy-fT_%%T$ z*1`P2A}bRckyL~CDG~23Bt*Y_thh$_e8awy`Clb08mE}<)91P$^Q$Ov=864DhuV6K zIcE6pkkCD9qkK=Q`2AtO?L8NlG@L%q8S_xreWvr;_dMo@!u}XHRqlTxu;6RJvD+%mPzn&lSU&wNf_0h)0gbz2=#ceKrEp&fn zaAHE>M3Gh*-i?cwoRxRg$$r?BqxGo$;WqU{HI7H)q*P0Hbq%j?QbYg`_t_IhdQMIHyj$3BNoibbZh4b_;Dqms30;X?PR0w@2!8tn2`QU{IBeSW`a9ot={NBvG|84I)@X|n}nGpU@D;Nd=a^MenI^UIjK zISKvpf3u@4W{EA?&gQKyW4XAdAa{-P1g`BGOPf3XPMY#USglo7x8Q}E49~5gc`efl z=1f$Ye#rAf;sJx>oiFZ0Or5V6A;L9TU`f>_4n9A@#R?%d2Nyd%@i9ET=aCho8PnU7 z^G>e2u=vos7d1R;yiG}0ym?Mqh}g-OCIu96ap&#gQ)a!+ob%c4_X$3ypl{`eqcfc5 zUYue1R#dbif1%T^@5?&x&J{5@GPfyx*)tuZ8`ruQ80Z~5#++5^XdayD#W%4aaj`Q~ zJ#SNHLBYZvmiH|So)^xT-MIZk)1~sTNGT6}-i0_-YYo{vLE-mi`QXoeLa6WE+jW=)XqA#=)p10ZTH#M9lWaiV8f5#^5ct^I=R0vy!2Ua@w+*O$5~A~ z*&7<32rxFWay3T6eYCP9NXLTdxbeZKXN-p&mT{OJZ*vM|xX`jl zlkI72~$LGn+H`cF|(hfeb!H8j5R8wNM;rZ(J zha3F$FHDZq(7R!g`S{hcX|-+|N;O{pwd5}TYCh=8qbKOWxQ9c@<4^5`-KRokeAB2~ zb$QjMm;dK*aKtNDE=O;Hhmp|KrjGK87c1&F&$qv0;b-`2&-$O! zuSyu6|J<_bOss`S`<4%Xc6bVLx9nULSYYlF`67pzNnWj4*m;kg$U%bxjvs7T*dIAe z73tp>pT@EE!3X)L&5jz(jqR(tTjqSFrVezF}?IvTlMBAc9?x;5o+V< z-KoSnr{$O{n?b}EHICAXjFcrlUtYV)rWhQzTw);H?4ch0BIuOk5i_$ z!SaINQzlIK|Ka*wju~fCw7)Hqx?}c=ae{ulxSPo1pIq!ea)b}6Jz}W+!5DQ~nf>1X zug!fYq%$(k$v;`}z^~Rp@WbN6oU>n?Xx#pA?FO0JmKib)MxqtTKlgiBdUu_iBX!W~ z$2UXu!>ZFoKbY<_bg7-Z+2f>>KJVl6jdK%){EL&dAN#>WCqKH_ac%P9tLNR-oz_Y% z<7iHp;l}6m^TEkH2N{h!R)^;Mx~fMmc+$pocDW80bHYq^!8~b`4epHzCWl2b=04n> zr0A>?BcqW$sfR6bro0pPectFPT5n_w)DApq|8bU0KrKP6Ks#dY!#xsu+#K33PPrbM z>tU(k`*7~5BXeGH2yfe=R*~OYDel{H#^AZ<4U6_W3p=h<&zWJ!>yu#2!&)t(sM=zq z`Qe7z56<~>Vy3kAtTbD}7NhhiY=zH+>5DF$IpkK}vi>G(!U1hghpGkbG3zcbOwEYtYBj<@ye_VulRUjSux8B0T-_eb%M-{2Q?Iay2#pi{Fut(xWFM~N$ux<-j}Rg zL{9TEA8Cv~Au#;1n4>+XpIzF)9%f`a7L^8lp{?D#$D%#unCx7_Wts&j3 zC)Uhjko4}qXzT}x8hLSz@KtMzHtI&mH!Pm`(3g{qMNmaTu|*;A4|~)9EzBBh3|ZY< z!xJ0MYrk6G;O{@TLceW;zg7RDwAwX6nyaL1q>Lgu&lacf zB=idZag$|@U!@;jwe>+T%eE^W8}#o#*(Cif;Os$PPKE~+@;{I7mvjB~XWlj&sel%q z@}rm8Cog%mcliMo&7F=6%q+8?Cdfx@bdhYX5D+c@#g_G?K|-Z6e)*%e_nto$rv?Sy z)W0{AkE3W^_M7e<1>SmdtwfHtl)q|FPz|vH>3V*L#xY5eH!<>D3^i;P+FP5H7xoCB-L*1mmF9&71$qLL zE-y9=KCGbbbgh2Zx`(_Q4>5jp<|;m%Fz2PaQ;bH^ybXZ~twjnREFV`lS1kFy=t;7n zzee>d741o^!fw;%t7}Vk+>m=DSk8EMQl>(Sc2(lzh4;9d;$FF2NRl{c^Zcqv$eCCnDg6?k%H>(gJ{>92Eblc=_)d56D)P$Q+F_}2;==64l?x>m zxuPQ`rZ_gJ8yqnft;our)G~MWT$NWUEymV;Yg0T@ZZv-D>u&gy^_mS*Tnzmb>U@gaZJ}5u0H28i7GHcON{Hx`noR&7))<-c#`)jAEsJgAd&#>yQn!f6l*F!=jn4ONbrU-o3K~k=fBb{ zW*eTK^MB*c9~VUhUr4BQR=J2AdghoL`c{=qpS|I~j2s)|-z^dXOi~N=-#$CkaK?j; zg};fz;HwAQD(1saW92ruT#yg&I<-`-X@-%^$D*b2cZE5fKfRX=Sy8fnkwM%FW`|F$ zc6)vaE?w5sY7ix*S{O2a&ch3Bb{wUL9GpIAL|3piHLUs6l=0=#|G(3>@zlD2aL{3UBoc^f8{R8*M&wX4OjUSpHI1_L?f--b%f2M+kZi2XDFdn3R2 z{RRgc7XCzz-3Pf(ML!qdVKAtRTOVQ~$*Fp3YT(TY%T45%xC|;dc&|>M&LW{I{?Y$e zOPmUS%TkGHJdO_(YC{;O$g%$`t#3Fjo+vSeasGk>)u$Zp^)l`e*gK)@L7Pg)uZI>n z8hUyk0pA*rsVRl5GusA9_C+xz%nA4cRUw`TAIfb8EVd!xvBQz9a5!UaT)~ zaLYZoaxz?___ME~(p}+-Cr6l4IPX{{Nx6MEd2ojCg1-|OH?}Lv{DQTEDAH|`Jm30;K$t7-|@8bojs4>V%G2CijDE?j1~!vX4hFCvz~j*uEZy|`lc|8vx?_V zOX21KwPS0W9)4f4P@Or)$j#({joN{SlW*uS9=9=w7vlP`SMd46ZEZ@TR(z2HYQ-*% zW|A@=E^w|3UB%k*f$xRq`~c|)r4RQy91lGVW*1`hNy;sl`z20~c-veiRg^FZLgl|3Th<7%ADSY+Ew~o&rZkzOo zzqutmm&0N{_XN&AhVgH1iC$RDa*nNMzqsXfC(gMGWB#}GIiB?Vz2u&R+WC*(A01p2 z&p8{mpJ#LMRTL?z`*A4ZqVWx>Mib3H6GG14kUnzv&+ixN71-0csyX{8-nr_cKDrGw=?Rh|0`j^A0$Z4~*Q%Rf}`{4r%+ zb6`>bvFjS$RK5%eDnn zu-WlcX!d%ri8qTgaj-KN>>{@j?G9)7v==4a>yY4n9z@ z4dG{G@=(wU<4BNQAhU2sY*Gt*;{*HSY(k8yHnha7*zGtg`<25jRd$^`LFSlmMXjoj z-1r-=iyt0%HV)``_p?I zN)d{jsRwEl0%b!|da6G@xp7nHdmP)L8wPC6>KqJm^9zGjSEvY@mHXwKZ!~VCwBogKwJ1ew6bk|1y$^+MD`2X-Sdif^!;3PwH z<_PtIVu6WvifudiY!4nOYr7@>No*IxdT9qf(TaSz@(BhUe_uVCwjlW7wjSAl$=05X z$LFhSr1@QEw?7=65&mFlSAk_=d|TQ3zzJnR*>gDmn76(-Xuod9nS^g14ZY3NMSo=H zH$3o3czO87CDn^cE<#^TH1doj3;dTjZsU{6=ABfqAk?PVBsV!FZeowqai$qEY}#y! zdyl7b96Z#1Vfo6(drfqnvnFqH?QoV*yM2dO=KE8X>ckH9DtG1Ho^D6Ah1s31jT?MF zWS&)I{b%CAr}$b~;%kEcgB;=P1uB-UIWi_`6BkH*F!~TvW2ni)s(;u(?K*3R*D*#p z31ug>KVDB-+^{0_ymh|iPUV8yk=V&<&(fi5oZ4;!29uviju z^ub2X`+}3cbpFaIXMC;`yQ_YZV2a7B*hEp?b_a zJjG#S(=XvtgZZU(%+q*U?(%L?c-sF@S76PX4Hi?vcLj9MSzjX>FDX>Zxi}>&)nN2@A92DwMs|(6_et;9SfEn(-LA5_!*GKxS%Okeebj92m6{U zB&zHElBTj3K0hp>B7JX0T+>f~rk45d58bsf-0+jxYW;!4T*VNN(nCtOWE@gN&O5s` z7M*;<9`PPARvXoa_RI;h;}^`kFy#n~j(UwG%N$-GBhhWl{jd0}A2zYvzw9j3Fn>zP z6q)bG0y;R?d0ca5QE^=Ok#kY=AI+MCp60{GJozj)3^+Hq|CQ{~ZFluJahUgEgK%}- zn}9^7oW|`(t}GX5N>GyJZORBZ%-1zbgU?0#c}1@m=bQ&;ICr~g%N}A=m;G{AhkZCP1DOw>Y)C)eaxNTSs%{+ zJ6*wVPTVa)rUy4v&vNd4sgP9JeA$7`zfI%Ndfui)juYxf+3#}f(o;0ss1W#YpZ){i zQ>UzQ)D!HO(o|MtsQt*QwfM2ONUgkan+M;bG(HL84Qrbl3mIVIEJ@o*#NzJG50V6$G46knmz-xEfN& zv%*tPPp&^}eLutZx@D)EP2FpMEQ=Su&T8<(i=UAx!+@QM;h$C`3$x>c|1Vh-oWkr` zEno3Y3~*W$$9F#RsnL!dlKzbCt>4Wj^)!i9>~8j-&1HO=y`kZb0OJGu{TvK+Eewuq zvULT!zql>hP{AQ~`rrcv&mRW=>R-M2HkZAj;fw@x;~ox$!;c=MGV*vfc@`~5l=|xP z>BGwUY}Bbxikoa;BUy1mtVQpMQA}Lc4&J7&L&p~#U|F{QYQchY-!1nn z+PM0f`8t)n2aDM`!x-zrO1!2%|MR+CVlJ2B<-afdFqu;4_Z@y`7|Pjn74d$xQ`EZAuj;r(zu^CUL|1IduaYzNKr z5*|OkK1%C|Tev~OgePHk5U)xI``s}DE$d`S@AouIy}Q9^&e z(%+ctPV?C6PDHO@+b5ki!MaGXnqB^{xb@+LnNB_0&pO38ZdjHmwO=Uy(ULgjh$vft zZ^OscSJYNZ2QyYkvpiV(<+`{VbE}R_b<^v{6~Y~XJ-fJ<@7QJhMy5k;LxFVD*K@bd z2G8(TQk;;+@`^E9?REE|6{xzl3ar?c`oRV6cQ zEJ$Q>y=~8vyZvRmlkmY=N8H_WThAwG?!8$MlCa_G;|&}6Dw0`#=dGB@VfEn}=QqEX z%!~&ong&)Mc2GaGM)HG<>x}Tw@+BcgpnC2qPuP74`R~cBnS47Rxvh3)w^h0kcrbH? z5L<#@bC=)(&b{@l4M)P?@NOtLApS$fV9_%7#?x(#;v2i#ryOT9@Z0x8;(qmEx%?j) zi+?Y$$ljlkX!pWmig1J_lTcu+63;P4bD3t5Vnzd1x5xd?c48}< zL`(iG*um>C%ZX1RC!vo^f}iCbo7wHJArEGVJI)aHI9PY^#KG!@0*m$!hR^OVc3zRN zOX+G`a;?D0;AC;GaLLvS2~r!E#F}|%)h#p;wi5i2KU;;T%R?fCkLOVSm1MaHw+lxv zI_dL1D3oSr)n6Qb%h0Le{gTAfnM^sNE+;#j6K1$y-NoEg)?#FTu;9cWvtus(>GgiQ z_#_t8w=E0GG2pzv!u5m7! zPVj*Ob;H&eBi7f;{}{?Ycw}C1>~@_r%Z(!eCp}|+cx}GLec;UOCVR)@4=0EoSb1=R z?>A|dbIfz!Fg_HUn0jm)+m9o28@`_Hk~~&@n7y&;zVNRuhbZoAI-*OeG`9SyNMb7e zH2L3(jO?cJhYD&r^_MmtI@<9ow|$niB-=q7?(?pGi|c9wj#hvE&bV-@V);@QDcjc> zdIsCM3~m%icro1XXMe~Upp`0lP{%`FykB?jXP1iX8znOgn;iGPZB^L!OyIZ~Z(r@h z?d%U-uE_jeedp=XtrrAa7q)N-oDuIYbGUR*QqS?we4gCB4|})&F*1-pXeQCJ_DAyD z{X7yHjK`%D^%nMT`(w&fqm?6jPMTA~;@`rxUzp}`Gc3JutcRDY#*B-v<@|~Z%?kp% z0@_@7?u$z{Pn>tf*q~I{p!?#48?9&j6djf4ebG29(;{}TNBHfog=;qy8NW$&i{-d+ zl~MElMR{yD&M4nq@ZgBr367nbn(uixM!(#8Eixsgl08W2TRr-^Yc^+ivjL9cCzc)F;t( z>x)eP1R3Xtd-T{j|7t2d_RAGOz?Tk;`A|o*-1qQ?UN1_ z7ITc5GO`XHJJcp@$L43i+Th)IF!-PJqfZlN&Suy9rg>oZhZ|~P(GwY^Pq8IrHyrd< z;rt@~(1)v{vxoJC!7^ntiQD;yjbo-;jvC>ebX=#_k7-_cPZ|nPOmd@UTL+ zNQnAReGQ8n%MT~aikafy=G`Tcd_>_9o3ZmDd){Bh8u3#Cj%hHf_`Od%<>t}G_u)3< ziNHxszj-R2Nh}iHB+t9C>&l`}Y%D*y9y~pivq^;ih2no+o&-ImvPp4%I)#s>2*`BI zKAbaEP{HRy)3XUz63v_fyhMKFUrx%);=Xs(@}G3d8+Jj%<&xzKZ4L)Z?0tPW;c3%6 zBX;}4ISG797dbsnWVg*<(s8i#;RavkruCT$`gbpR32yXl+}2yd@F+J)#nIY@k5k^w zeOc!cv7UW}CnvP{3UAWpR6Me5&lYWtb6dO>T{)RKgpaIl$=$VTVnK|OLX+g>2YU;0 zgr9VGeSM|c<@a!ch0iH3#^b9xt{j})%_+v(++x(^QJ%ElpzOepIZRA57R_qOrm$Fw+Hephs;+~HdD!sm)jOV3B}ErFbls65uZ$Bp6@Z^{3pT_5G1xhIPx3QP3LgiSyNON?8x#d zNKQHzs>gFj;-JIrRM22e@3ucWmd**i=aXiXm~lRA)bKcX!W_&4gM+b_pD&+(cF>7^5YoG4PgTvnXkMtDXo&+hxJTyeQyzB9-S3yIh8=Z|b?7ZEH5{EbWLllW0qk zxaq{&Wbg7sM6W02NoPOXLEBS(Q-o}rC$i;VTWr!LBJJjO@Ip$aplsuIPI1m1mV)1! zS9713k>qS}TQMW+$)Y;ugLjH~I`^6!+Y-%a$M)FahPvy+2{W6U`gYxY^+)RQ9^Vs^ zizJvn9LN!#cJ#vKKf;yz6+6N%OkwV@kiMkcs_<~8@dJx#0*P^Z_h^bsiB#l&EOvM> zn{(4+gCj~uI!-z>`nOHH+p)m9{pZp{`7XzLWlD@Tlyb~|k;roXaF~S1DfeF@9F2ut z%m%R)`9e)kKb8o5XXk11VLtJfx5sDtfx{AlZ3p!?Pn&eFr%L$i!4ppIftO~P%xLL8 zmgAt$yx9E_+nf&=Mm(sF?vwWP%co&XuP0E`S&%h8PDX-GtW}uZOU6L z*}Nk3fyHCShu&%rlF#nv>5*x97NPO}u=uuPO8Go~H*{qFm>)bWR3@AdS5SDLcSE7a z%-L>Q-xBcE3u`$w-en>O<`A8>fZ z&&=Fm@cXY^LcZdL7RG~&0ScV12RU{~F8scH*(6TZ1Gl&EAB{Nh+4b@NCILDJI#9`@$$J@bGSvBM2t*} z+RYC}`xrhNrz}>8n6&fvqeGA8ePYgGXUdLDC^~WQTzvmLZQ(7TZ5 z4ArhHiwm2{u!xAN^3rp{wLA<`2FDu8Rv^^ zO3OOZm@fz?1=_dWQYcdJ%Lr4EG7OGL*pMU|V|MT`!_?;9#p;P&4`w!A;-1L$l;>x| zht(e1#F|SiI1>qth*!Dg0p(qrLD!5ueXZ zOm|gzn@VIfvh@sBh_kL{59}@Gxvue0UT{hygQ`sT!HUHaj}LC}>zSbA>6qYf@UUVS z<6kK&kBs-s33J#33eQQfIoO0AJgP9`U;qn&pJ`!j8EgWYivP;JR^Sij3x?90R8Zs(0Q` z>R|e~W2QlyOK->goDC+n8f`5RA8x2|<*;%5uwJsnLe??K^ueP^^}M+U3bhnst@u6v z|5)9;V*V9Ho~bi;G3-%%+$s_-9)nFe_NQ#SB)$7$MWC= z=jK0hvlxu(*YKzru(MSE=c#=Aa3APiZN3-jM;!JhJSxxNXAg{DcSOu!%J){q9^u~I zVrtyij%<7gn$BK3=V11tho8fo?##L|r|TNWUSF~H_WWE*n2iDsz2SU^Q_qoqp~a7@|-z->nyTEP6T=RRk*Q* z#Km2Y&NH-YK2hcM{zC#EtHjigCngA7J|W|>|Do#~D@o?=e{$Dm|5@GG-`do0G+;&X zqouny{0L@ed{Dum=iS);;Dh|RhP3JbIGubx%j@ZDRM@caKlmUZ(|n-b{6l_=J+ng= zPmF+*!1UY?@+=Ao7ROV!J1A7d2uumokf>PW{r`cCTy_2G)D1=qCwK%H8@{rbCfw6! zc$)QHVNwkH)TQSZS@DXpFntXXapc)kY5mppxs&|ye+zPU-;Ub%;G}dT4`ZDi(?yr! z#DFTxht94W-*Nkh?}&SFj7#jc@=nGc5&ms%OiT7I6Dqv$;27us-`XXXQVNqKEesj$ zUIYpQvWz-_uH5sJbpumtw;7k!O|~r#fPPHfA=U(OWdyNxL`l)8*br0Y7Z=K z@Ua^h_Ko!fg?ZZztLBv(d9m9v|NjALcZhDV$ z%BHk9JZ-%?i^olecb7-Y1^psn56i$0^QX*aJ@zuvBlzJqp{)}q@f8Zr^4^=FySQie#I3?VPqmQ5V?hlD~_%K~8{MGwOE0;g&_gIwMlmBj4+%lI3%S4(J89e2+IBJFd z+Iu<){Mb=(Ot9jMt>NA31;(`@JA(YQJNheGw{h-IJM2aSgo$J!_3%2*J~+L`oD{f3}L4P8`Tx|7&cXZ z4>3rX&l#O8XdBLIEV0nwjQI+Sl3;1lz?E(W6Sn5VIRJuIJl#`Kx+=YMUAp^Y<}J7)g9l>TsK zk5ky8ZG3M4!2IBX8Rsg`0A2~c7fZW$ z8HjArxagv2&K#YpD8{Z(&sk%*fB))*0!Ld`Zj|Fr;BD9$aKEwRa-xXn)CX(07u-pz zy~&d>a@3PvTzw;rKi3Y&M)TEEWh$SS(E5Cvnj1_Jid5{k#z}Za=J8 zsvA`fE3?mU;0Zs>++UH~+##vC&#}V$K)K_Ukb_4Vp2rwUKfm85{l31jf7>6!ZJ=$b zACBF=cUj;AXv!ws#sFl6gL>ofhoRc7dgYg|hHyHmI$!3?kT8-fI_$@NgjFHILKQs2 z%=pj3XhTAifRn(~r(R4)>_U7b`;oClwo?W7v5A{oAdZ7bH3w zB(v04-!VFSrD5IohZ{dAGD{ZE<>9H_URZtfaDKtngSq{@JD0E-1nj-(ET0S7H5z+@ zx2ZwcAVvRycjHm^8y0;la=UIMs|s%@IMBGT?dXwvH_sHEaeV5t^VC-UD%o93Gu#Y# z9~7Ko*^|I|M=9am;z;H{W(N})ZP!RhSzUC9`ygk?u}*ToGee=U-J$k}b3ebG_u){& zgV<+(402*5F8Jg#pLbw)t&^NR^O-Pcl+fVzLoI=FR!I(97KZd2{4XrNv-2=TGv~;- zHa`FVpHn`t={57jwp68^eK$my+u7tK8s?q({UFKgko&{lJ%2zgbfvrEY;MeLAu|8C z85>r<=Y4QeBCSJwk1^|MvrY+%>r8{J_ir`F0K;&P{Q$Jm$Spn2O@iuE;>K#5%%53w(a17 zy$?1>tdkJlP{`jV#(3_1McRRf{v10JBw5xUF}3hN7!T z{<__}FU4hEuWtVvy3aLXaVTTZ!%qv$cuFN)7V!R?B5^Jt>-F|nrff%DX&tw@1)LV z;J@cpE1wlhgYEfHjtj+!i63sLA3S2mW@9~p>9YpogAF2A139V>S0+2WJ23O3q(aca z!(q&ghlT%1-1~jUJl{g1VNQ)qeSu;08+Pl%xv8hz!UE1XSNdMN zqBgrS&neD7W}FR2WE$pvOeox8dYAFBigWmd!sQ>#4<2RPCAdMxP&Bc__2{GdZd3T! z+8U1>TyId2(h+pnph(f1wZY5pH-iZ?~d&=MD?4gAEp;2Q!kJ9n^WYHXd4b@POqV-d%?5EIVX6x^M7_?rKQj zQ`&LWqhXq)O`gx^c@KY=@ia@Q-_BXs`I()EDg5Em?@rtJL@U}}PxlGaVoYyy3aSZv z-gigwyiey*rtl1wbbcldrv+sb*$mvb{eAe|ZllX8hG|S6W9lCMT3F1zFIIHU@3w?B zOSRfhJ$Tu!(X>#cEfd9{aM^CT?H-KAyocsa9#hV+>}?t*>K+uZmz z1YT%vJv4ofVN>I_Q*YQMc-!VlI4q1&xe01F&Pe)p^FJuTT`f~E{Jy_ULH)Mk0VS03m^7dU0T!B>inJUpp{y} zp9@SI3TDoGoZ-rD;v#X-3RF1TJEiD>){eFO(5-nca3S%d^+v{RoHMddvHZNZ@fgz! z^M)dWQkH8QHoN9#l85(so6-)*Y}{UV#o^(M%MH&H z3Ur*}*lr|sEMD|{vn$619mxwTTjt0Fbf|wgd+=aK-~`S&?AAY$f7kQ=;$!Vt+T+X= zuvkjuUvo24`;SCpS6PW>mcP5(%x=#}W_f(Rai1j1n~8bdjkX60?;nbr5M#_#aKlni z+)OLs!P*lNw|^ft+pEGZE%J*`p+v^%Pc|Rd;YHyVIxZc~b3PnpdH<(r#q#QTKeAYU zSag0d$ar9RX8oZB1_v4#AILKaE!AglXj~%4{(C|~;EF4&Efn|O}6lBf~D=(RMcz$nCi!I|orW)pw?V{0 z-W+CKF}V=c%JSb~oVCjr9$5B8n~nKmLz{iws{hk z?98or@Iztsk6*62tAec0K3Hk(apbuK@1&R*`w;stVX;5|2cy@5MX{FZx+F`!!5? z8q&CfuR7oI-6CcQjp&@d0}m3J8X3;~emlXisom^^)C`LSvaa$N04bE{J<@u&F^@cf+(5S*#2@IgWMBW9M;=k8cGJNSJ6e|E`)&;S2-{rrBRobg-z-yQi(2iTdaHAHslI|%=4 z?qc%iZK__qK!x4%OB$a@LV*s;8JUg?e4x$J2PULwf)+TwV`F&N@c)=mJbwHA zCK~WbUhv{k@MXU2z^0Y^!R$mt%7#<63nf|en?5#*w`3)*i%s3L_m$nu7!k{|9Cq2MS*sp9Jn;;!Q|F#kl=#3bK#@s0b6eSk z7?uxdOx(_Q+`<;fn5j#yzQ{aVK$#~->fj_MUf;Dr_jry9C~}(LTI_hjHKZ!`PSAsO z4wVN!2uL=wC?qu5vHereRG(mw%(ha6foB}|OuwHLH3b$IR5ti@p>lGQj# zlTD)2^^M>kBd$d5^@sfC1>MkLC`glJHCXDrv1?z`)qvQ?%g=Evd>E^8anW*jR)dm= zX)4XN5l%w;AAR~Ow9fqEbKj<^i&YOC{`f_ot@R(93Y$=4`$67-ACdvTT?%YC;@G@w zn5S@gRWB%CHtperWu~bQ7RhUE>pT6Sw0VDZ{)6|MRz6(d5M~qp!J2*VyH{f-#(~A4Zj3?{`{~lNva;#@O&$dIC=_N9F|MWXgx$X4#;$5on_v^ zw=QwM)AENagrC~JuxgEM-oATW4m@gf=9$=ZKq=voKJORD89Sb_%O7~y zpu-`N(6N+xkJ*isdGgH-W4z~Vh%t~kD3QwY z^4a-)Y8{Ihe$?#ruwL)dT2aLLJgw#64B>_^_y13_W^R4WYc=73OvlWR94*Wfr9})D zC#dbYa2iy#t*&dieOUhXFEgu)HY_JnjGM9(?lZ>+HqN(`J~Tt*gDF$G+kcf?e2V{_ z_c!fpZd+sA(k%SPW12;agO8fmi7Gu2<{4sb0Y1%bb3aO0Xx8xZqy--+67G>PiV*K@ zzFhyW{&0x|hI8IMZh6z(iN@GItkK{{@p$P{JSlhTZ}ox=NM9W zunV&76S_M6_x{xZUV@jN&A1>Sa!u^j(M6}FbLW=tFJBUw5%8nZti50RL)wbt8?uxI zDp4zSB3&}sNA1Ij1b8@|yVAq==%hA}xV17LL;RDHy z_x{R@yLxSKlb4gPU;l%Z)$;O%N9zx82pymCfb+wL&qoruYJV_UC4UW!R(k2=+uj`e zuDQ`H=kb4L#tuK;M1^2>W~TV=$I-`PI2fc>KXO0l6vNiv!prC1_psvE^kBQQQ|5L_ zvKo|V?E86sk3{vuhZSN!FZpS-Z{B1(P4ir?Z}F~&&a$G0vkyyXNarkEy3auBVZ-&q zHL^~5{Ad5aV;3wa(EB0r+Wx{dF4+r*7k20uSQxRq_i_s?@b8k;`EPf(adCj`C8sj} zyA1M2WO)-7Jb2j1&Mw0Fflq_wt#id}DRw1x%efC;2%g=>Q<2Te#=h+TpZUz4JJR^v zv!q0?@_v}j+?c@GTQGHzY`oyX8F3jg79RGV zR_VhD^H?9V7ic6rGUJnUnB3vxxVf=++cRmFmkTRB|1ckFbN|7op~;oQOtBteezZ9%DG-Yt*b zx>?Q#?p*v2njz`kzQ?>X%;CN3fd{c0x}{y*A1<7ok%1@G&pB*+FgEBclMH2cQ4{pAf$F z8(aOo-+vpTyJly6?mLn6?S}e~zYlwa-~L(@@R?cN!caQ>)x!xQ>>s~Ju^Kg;&68tz zs8dsW%yAB5qL282Km3f0YuTnharhu$(ad6yz|;C_{{s#-{SOmr>I4oLhdkC}Vfw(= z_3)zpA>YpjZp7)cD%94WFtt$R6kWf1zvHhSnH0Uoi zGh!}MuU#+FUE2IEY~s;#5(g%Kx_6IP z{q#o1;HH_3>W?~Nt(H94A;-iyA)$ev@lS=rmnH}H+xb=zJbwI)Ocgf#Ul$xbed5xA zLl;^fILg;COUqwqu%B{4n$wtX!R$*H;%0|%8ES)0Qq4$T#=+mR<-WAhh0}!(S4&S7 z+u@z|p@Vl~vI^_3{QcS;{2`Yg9XkAyBRJbh{CMgWy$=dna^le^bB#C{7V3RBUm(CE zFtu5{zh#xR{BMReMN5rK{~vDjeH*qs!|>9_0t5C6&`EHqVGlraw;Xcn|3jUwIysmh zWZ1iaUuc!%|M`mbs}9H6Xf`csS@`e+&(eeQ4>4_ezxA#n+kS@gSJ*7&c{y$gNq%5y zkz&06y>P?A@Q1HHm?v0#^4fp4;T=!^i4(G};*58eJh*Q1!Q;a+el89(W=)|rf;DF1 z)5U9Ce&?|Ts6Kt|s&v#rnvpZU{o{i35!KBa8vgtBQ|d~1a<>~CdE3f=*!#|J`@$5N z=d&bUZa>a@%}M6LeqMz|IdawiKQ4=qX^{22=`5H3qrJCDN$6m8Yt!Fz+^2b)8dCVU zZs`AaDvu8pzp&zkKC^^|{8i@~F&TDN8-v)SJU*TaTpv<8|4Ao2YAWN4SXkH6BR~89 zwHBG;dliwza%#m*4~t|f3YH&Se0o` zJ>W#V>@LXyl_>^|Hs9}tc3IpqJ*c_K)4}T?*PXd8_XHR`60e-|InPvhvaey|1xx0` z3A1eu>$U1Hc$Btmkz_!r`eVmLcV-QB{+xObsTt|a8p8Yd9Qs$>`^A6#|KGzoV#;!B z)DqsctY6G0ci=^UhuRlE=Y=2Q+722?Hcz}fN2Vc8W#_E@D?KW@n9)PFlm)Y`liuY3d8_g9j{Rst*UK9SS>m=Y_t7 zE&u=L7Lqe8K1=XQet)?1TkZT0hgsg)uR5@sNqvXm-uwNoZ%EsZ+T z2Y%T9p1z7h`8cbA0pkWaCbq2!9|WX2lizDHG*obC9Fj264__d_&-jnCVv3!9h)uwI zPK8q~YXxN(4|y0&d>`D%vqPTw-vqN_$2~XmlZ^U!IUlf_pU7``(4(ATEV+57f~CZa zV@;j=IT{`>IJ!uz>rg||#RzHM5Pr@Iv%6;Pi{^J8_*ojc*Zk7v@9wiFmd)F=@zYxO z?nzCB4R>~QXLfMabsf0H)i}ASH^qn12^4NL5VWXU?pUmjC<8ku%t9 z&x2(u+zUPkNd98tVb$7tyTV|~3dI(o2Wg?_)>pZJB4Y}ViqqFg^Vl2yeeq;(Xn4=V ze9%G9zDXlpW0EAR@qwR?3=#?rSql<^{&F9DV1Hbw@qztO`DUXM?=T*_uoW&9(;1AP z-2WgS!Wp;VfB@T(ga=l3e%INBm$dh(`Yf$*G5lCux3@4pXkCOUo3*kC6T ztCoLdmas>>@#3_&g&aZL7lQDNNKHO(#czTqFy}KjAda+R%zcYiBcy*+M!5)J~D-+Oc(U-##>hnvT z<#RztI_4i=^e{-I^xbLS#N&KZHstb0dUkWl1wXt%5QB4_a;n0o?0BNHzh!%=60 zM1?)lmk%tkeEv7yaie)->(c|3_k%vpmRPg<%dUApE2|bHr6&JtOA4%>!*($L4r-6!iL(zg{uB)6SCxSUV+4R^N*|axE^vE&)5y(*4 zx}`Lg$ zmPcwqaDqicxT~WNZ^H`4=J(=ZXPdQ!7?5a8ahr)-6CmgCk>h^xC(0ePM+=7b=W26-*=vbh38-WZu&7Xal`F7cGA2}4PvZJ+bhC8XcIr_W~GuZ{r_%v9)@p0{t`VLxS7;yeoM+%?PhvQ%EYs@%T@ky@J z=iFeiK*sME^Px0@*gsxv4t-tg*cL5!mP}?;T@cyk;5+Z2UJXy}_IJzln)+mUn+jyO z=W+8j&pp3yw)4RzMt2XKM+u#Ym9Txqb&%`Q{-|y%3kueh4 ze&NJdwnWoIZxqk_c<3{PPo5{|{G8b+G0k?awlm+1i2vLB7td2j;WIt@dt*p6a@$c*V= zgU0{%zU7BzP2y){l3I}XYPC(=YR68;mc|c`VRmb6J~->K9Ze|k3^nRlR|$7`UQ#K__$_&xWHwius7xHf{1_@ zFWYYDIIZC~{Qpv6^%wQ@Kc-AAGJZD~bqH?mS=4YV=D{&8vAf~Upv{+{nJ2qL{(BD{ zvj~`2d`FA7{oaF9T+Fr?3a^J4)wS{E=OwlrJQ8o+21<&Y-@XJK&EH;;na}W{=*ann z?rWs?-tb!ZP)$)Hk*RzyyU2v+;F4K%+ktw)oR z_L!A-3Un@#W}2bJnt0*R;?MhcoyzQLzuY#*<3Zxyid2?k?e(m6t+p@jKUiP=AhDqG z|Nq0{kTGsC_B9Q>XZQ0M_!boC-F}ev9Ls!9Fmy+P{)hm^@ExS#)A(O%sH~I ztd?|ec;V1-OhG{8m}Z#l|ErbPew@GRyWH8F?Vw+!Z%flEU6H@rI~)&9J|(1C=569I~f)GQ(Tei#xZziuGUl zMa^c%;@)|sD-Sh3nkMsozF*@ZsLXUcE0`TS*%N`>B?R&K-f;(K=(^0R@4 zhuhpZ&&=HK?8L=%oXx=B{4386F%cP04r})L4Ll)#4F9}7ETO(EyH~FIu!MSi4Nva# zhizYY7*8{O{a@;@o7^qRO<7Esam{!Gnm-8&=Hy z`*{w`W_+T{sbDE-%rT!?F84={u){kMrfl}8oS=ipI(8{kNibYjc#xLL@W_LE**E9C zQ7hJEoE4U+wOj7AZQ6h5gVwv=XZEl7&7CK8oAJJ186P}cbJ(xuKReU&!#Q$Q42J%! z*Vx&V*%Jz81uP2gZ&<$f-~!Y^vTLD(qQ&@A5mIgawtGy6 z&v~$j%QJlEYd6&ouNM9P>O7Uf`#>_wxO{#q zB-iKjRBnH3Fx`?7)F+gROL&wn#;(Zm$8i6i!x9?v-Yo35d75+K^@TR8_CwDN8vEdt zXYcdB-}w*A=l-5>Fk0c&<$F5fhu`x^s2{wL(&G1z)0FqY!7O7lt+azjViu&eWW6{k zsG(P5`X_(E7zo^B|s%e_a4&A{j1 z56M{v{(fM5P`I#Qee*=&{k#{B$U0P9W^T)1tZzJOV{?|dsh)S=q)8$ly4Ogw?3?lD z(Se8S7j6`8e4|n%ENO5uQ)z|wJj*-Z+YJ28emwlT(Bk<{HyiQxkm_dT#wM1}_V-?O z2g#`|eb1Ayp!O=S?&f!Pj|?)>Z+)$p;LUwcMV_ZwI`@p>+xge7YXAANZ3dSTqk{y~ z-{()Q6Ssz3kox^&KM;gX9>;dyvF`*&vaRBB7A}mCoFlPwy{%T zZOa=OJ&O|$UR0PGlr!c35-uorC|G=0y7G71jIGNLOK5!0Y3$-MpZS+ruHFZ<*vz>` zMuPkNEW8w!qG@P0V8;lWAa+Y2^0buV=OaD4VXiGxnJSKStP7VvzJVN>h& zP_7QmhFy^znVP}P<{aCd^7w5TBt7kRG`U*ed2ozNcHW|brHm6&o*zz_4=R$vj;&=8 z-f%FXV0pl8)+WX78*2ZWyEtc9BnbZ!<8cDFwqrw`wYh;~!7jnv7j9lW=7|Pz&xJ0W;apJe zmhoWm0l6)%;g$!F_%|g^w^cl`Zi%|HgBoZkWaBmFgQrWHH%`=2Sl_sK@gsx6MGdQU z_?%C1FAr<;`*3lsORI?FgndU89xU8Yu=u(cJA?hA2d6mCt>gZ7QDgyoiOL^mFDs6v zDvJdUvAj5t`G1v!+OdR3fzBNFcNE=RC2eEa)VMt){D4=*hIr>ADkcxqY)=|qKJKzS z(x6Z1x2Dy?{8xLo9*|P4IKgvZ+KCMo;wz8)wB+sPseEhwILOh>ygBfnOhGEE@^6+q zPaAHp*x^;Fn7)Kxen0P}(#D!qlRup|Ir=jAnaIKEEc`oaRJ58m74R$&XFq1kdzs6^ zx^3Qvt>2o8YJYAzfO_v}XUEp9g31q}wq0<%6A@UT9<+rgW#BtK!+mFC`7oyH!K-fa$ta}0~?KwZQf znI4&q-wzbe;D2H9`Q>JZ#~J-TiC<(w{J5{PH3T*#Kd|Nh|1dbgez8*4!qy!^|9(hW zST{Ua*xaVpSUBUX)Pon=A1*c?sabL(&F_W|7t1|~wcB`1KV0Eb{=LS)gwMgl?-)zN z^Q(nCm5Dtf)~^;WY`$Fo?^#crq`hJRy_->G^-^X^)OrnR;tRT<$V6Sbn9G6_^gY1rjC(ai*&pfm%?BmG`J_X4v zx8EH&lCL0Q*_PnjJpaN(D~TS*gK7_w@9yW--NnZ_!{U2en&ur7es>0mrA^5nj^s9c zet%d%cxUI|K)xn*Hot0S!DoD|hd-RZvGVi3=dF!xTs+@ibxAZP9~KeeFDUQ~G2C|d zuypQ^b%)oGz!$tz;R-LmtybokC8q>g1$I z{&iTxbXYq73){_EpI_+L)mF7VeYyGZ%K81f5^_W*arZKPlu?=}vhT8s39aaJ5y@xwOLZ7LwR>=oX?{su=@+ecy%InC-V|q69u({q zV61sj`}$IW#OsXeBR$3Qo+k?z&J*Klb$Hmd${}TnT>bw`0XH;`Df}&9+)!|FrRcx5 zq^y-2nHD_Jw<s+ga&4cFsL!FD!fy zR9G}OubA7sLPz$%4UKE8|Jk`JZ?em*x-6i@)6+OhQm^6nKk0SNtvq5ThEfLQyv1;kikc0Mh@X*R zZUYUiOf+Ws#()3+Z%N0-_cA-3mHR{u&lRMxyil`izI1@?zhluGF-1P%g$a)v`Zru| zX5;+V{X??p={G*f1Cv0f4)OZPH8GfYPbj~Vs_=;2@kqn$hs(cTDBu?{QL&Ra=yZRT zMDFhVNS^AQjxAh#&5hRoPW^b;WAR}jpS!2%s%d+EeptuJJT-Se&-=4GPqXS&cZqGB z__1oo%9CBJ%m;a@m$M&of3lc5i-^3j(!*(!W-6D3uJH}Vny`H7_;KKJQ z56ouG6WFSL)@V-HtklF@?!*UDpXV?hJ7{V3+iG2+L=0%)?#1F8&)Ebt51wAovS|MAX&>Tw z5?18yO!~epA%SydnQh}?=+ZfcU<_RPZIb@QSV z6DR&nNM_Z}cjt7oJi)VIvCYrF3(^wocrEz2KJW?u?rVOq?|Ym6`Q94Pz@0%LXw3We z_og4otlYl?j^D16_@4K08}q?Cb_eg8xi_BZMcKHxcB^! z_?~~HOoC1NKw|gnc}5`(lV3Dueb;jg`C}s%kv!{>E@#}s9VMrPIqyg@TDkw=W9?M5 zK4R5&%dlVJ$m1n4G6tOS&L$d+)dlz2^;!Z>YeTomwUe#>)W5RlV zEu&b?7m}F^%(yRoJ9pxx<<;X~3td%G9VZ-dWV6y(z`|{G{{8t|jLlzzuH8{J zX+8B@+WhV11r7&8=gwYyEGMWnNg?@r^8*Jp6~`ZM-49HSJy#&hAYFT~M%Ig)WAR7% z2chpiY%#oCeYZ(e#(B=v7KUqw+RctxM6_6Ln)cxsSKI9cpKd(u-2+YzD{|LY?0w&+ zpgG^}rqp!*wuWH&=l9s4(bq|Ih7Ov_;_ijvBkR8~Tg}j(sjN^F?h8n`*bONKJSo zcJL^}Blmiqdh>^^ckX>ScE6aX`fo;jb?ZCc2pOjv7R?Pmgw7cLxqEk6n?a!6O=kJr z-z|v}p`7R07(QgIwyBY0{$r@6p;vrZoyE_TwZUUnwe7;$)74#X>4TQ@KXjgBd!45{ zd3XDtHJ2N1HGe6Y8S|g#;hk0Sg_4)G4qZ9m!Ii>L!`O9|@oAX^!*LcXffbXKofmRc zhHCGtUA3d8d>v2i_JV6%JCdKy)?6T0y6?!lsK+d|@p+T`r}SO1y}6CcuV;dV?p-!E zgAlX3Ot&PN%J(K8v8gy5W5s{xX;Z_-cU3ZW@^RDmKHFm^anSE}3XfX#_qW$R97=Zo zzI(!hT^Dn+TU&Xn4yGR3aEp~cleZw5RsP?igU&LNlCLHqJ7 z%`%W4s&wrKL+kYWYs7rnEdSq~a=uNmNBHgDC})!c$*jzI3qEY@&vBNKSgf=FmRTTBVw8O5b1_eUUt)5tyP!_SmP~f_1FF9)it0>e%@2REJSn}++v2;f z>B0VeKMwO1&zbmC@$e?8@2!Wss_$wgC}l2pH~`93ix1~H%ZtsP`&~Xoap%DnuB6=A z3VYwlCvQ9v!sf6CwCuV^WbLlT-fe%3_dLJ*IK)h%_-1u%Oxx*$6}tp75B7-Y?sXR3 zcA&zd>0!UwvxnQ-HU#9gCCoX+$@uF5^HYTf@vkIqp9e)i^4a|%8hao1zI``KU{0rj zki_ml14Eew=5oRoaSx8XxBTEM>~CS(RN1_vtb+OA@%@YkJ7%p4l>mk0{x%-rceVRg zB){FyHDwReoriBMANGhuXDzJI-+Qp%?2kT2%!eKN)1J2(1e)EH7fDuc+YtEml#}0| zXRddbpWbtMb@HQMR_kLXzEXJ6_vgVk!-Kus{unmR-kBmM-IiGJh3Ss6f%<;Ij;Vt6 zmTpTw?5KSZIDPem2du3I2iTS#{U_Jy$uI6N!4c0Ubcp5q>F)0RP618}PI>RK|FXI8 zr)lKlhaltRkN-zVqNPYcQKs z-qZd&5(h(WgXYj5f9L1#wUIa&x*5cKcWI7UyW_h9pU!*VPf*y&=~q10iCIE(c1~me z_PuX-5|&+h#b);V!@2v6M-`PPyIoTR4Gu`;w)Fl04Mv(BJlK5u!%#S&V{)9$ARzrKPmfHHM#AHtzZsWX81B8l zXj8+A&kMa>MJER)&-t-k@u2gjrci+c-t%<13c|8FVUI|@Rbz%#^quE68+T;3FG!X7@M{Mf zixf|Rgd%fL!U-<(&HbA!6c{rv9L%jgICqz1Dit;?Yzb1!F3L~Q zVYtucwa-q7`}9wjEbA6~p5ybaL{4%sHVHU{{$~+2eDFbjSMvdfBF3i&Sp?W;voAe% z`buTMl=%O}b5w;6K2Qi{`=Q9hF)b$kLxugHe`;(C8sa#-K0EgIw@e6Jbtyrj_vI;* z(imD)XNSgOCUG+MWolZGb3nH9kp0{ae%uaX^6T*|QsPd}lg6Wpa6olKG{=Rgv z;$tg_(kSfUd9WbiZ~gx_1}uM_x#enqBQ)UEZi;7?u8mBI4*LlY1C-+411fGz-w6m4P1wzGSt z-Ou)cjk7NFpn<_OftE!NFZ|&b56j!({UtbdTU9u#fulhUmf7Ecj(QY(-- zC_G2vpvUbM_SH={CY<6jzRh(v>_c2z=Oe|bDlErx1uV}_YSR#K=)QCC;TjPinGW$i zeiwzW$SQ2Ny%4bTeVO6jhdm;;uNFO?rxoZ|z3Z@uHc!IBo3AA9=O1;wC)p;T4!T;c z`jygx;KmG{--jjCXIHH@H4rUIT+y^cuK53j2_YYDJALDGac%s$|L^lEX_g147d%+5 z(B0fvbtwNpp%+8^4auE5Hk_26VfjbKP?cx8^-`V%b677Ye69aK>BHy88v@c2{?7mZ zpzs-=COez^f2ZH~KHM(05;d*7&O77vrXzdb6*Ehp1vQKFR>W5~J-+eXvWzg9_vrFziRYYxA5DJ z53H;vYZO@wKgj)zWpt2O8CTf;Lblyyfz9GY%6x{O6MaOxglg7^gtO#Y)JP~WRG43F z(dYE~`!@7LQ;e$kCU*8e|8EHH`0xM5&YEH31r|1gV6(fd?aU<~f<;z-Dt;F6Q2X4j zfCnp%Bpj)ou~uhF@~Za0D8-)Qu7oui!K_=pL``{UBvkvIzdhhk>n`SY^|K@x!qP?+1S5*-E*0*ZFaXGAAWR0^I?yO@2=(@7bhRzcs{xy znUyb$v=Xu}~`S$PY zToRlNdw1y1dyo#wj{ie1Tud`OboiJ>w7~aj)`v5aS-EpBu07u!bnhZ}!|vEF`v>P< ziHNMpJHS!;H|YD$Gr{fGHq<>#5_?`G+r?G(xD_(0@24^c6wWe^|DQj9KJ$?C%fR-S(ixTSrM5G6`tK~ix|+>w1^>yAAa+T? zIp@WvGyazoYQL@WmCZo%YVpdLX93se%Ct`?J(u%DRxs{S@$#61JOz&n51xpaZeb+m zedm+l%D&7HIf^OIkIOtuQ+-{_g(Q>am^P_ zorT&Pb2lpIcwabT`0egt360HFyZj5bd~FKdd(h=~*?eBx59MB-8`L5m{#X+&_hFm( zz3*I{ynEkh@};T1=bFAF;JLL3vxItmPHjv(m%w+6fELR$s(M)q;BzI&pUyyc~WM~k=At4Y_+b$noS5-Xo32-pX$ZLHe!@9VQUB1esX)PHYO+VijXU60FN?*Ch6 z9`t>o|GWE3*^2sy0w1Qa|Bnt}S%0v#kzaSN>h5I=7nto@vUrZ&tZjwML>8}55>ox6 zY_`-d-^x*5FW=~I+*cRN2^sf9PAAx~us^uKe5GceLvo?VE7L_EKo{J#G*}3DU;WJJ zv`)>oX7NAK=?tMi47W1pyk`G-F=ELv2`3)rd&Ydm>$$8X%pG-p1aH#%)%59o(=yft zhawD|yIA%!)@w>NetKo6w{?$|olp}m!=5p&*6Wa5~>cqqUzWWB)-=F__+SnN|*F;04|=D3zko}t1(V#QLi zTK8jnzfJ16ckWPxU~OQ5e5jpAn9j$IB7P|)ZpmBad01edBDO z`2{T}F7Xyd%snLi*ukpi=9Zfcn^o*(R_Pa+``JD+y^+IK!X<3;_=s@ADvmEdw_IAd z;)vF9j!PZ2H?9irc+qRTaC(BS=bWBzmR}_`M3%|92*r+=b|c)rSqG@=iBRyr~{6 zS(IAuFU4k6l5F&#=+S|*k8I*E=zUyxq9*NTQTN|;p=q<_@;W+N#l&mfrFi~5IH9?5 z^Q!6-m-GJe9FlK8Rn7gSM>4{w<>93LS{LJ|Om3CbGl_RuTDa>$LmZdhm->b!A=W=m z?JJteRXs_3^4R*|r9Fz;U{c>Y>R#+yxr;dH!k&WU<8?G@Fm@YW5ukiJD-M8wn!ZLvk-fRbdXzt@_YUbvCF(v-)jqV4B4pi{JKlmU)I^40* zizkXllKDXWbjK#q1s~@B=yW)du>0|m^C7l=lB|Z2@0kU)^gr$IIQ(-N;{*HS3l4I{ z9#m1#;b;Fp^FsnZdt<}73l;u94l*C`kqG^ev#6f&!wJn9O|N3s@cfWalB<{gv_SD; zf&u%53J%`K3Wp*TD&&;^hc~kbR7mh1zaS_4H`JrCLI1&m)rH!7I5OH6`s~lBdG#St zjro8>Ud#$P;lHIGSGyV;Y~TOVK0A)#==fi2Y9vHK5? zk$nHb2ML-S!5OCEN4pnnyPsTNGT%<*VCe!m9*#uzx1CupIi_)>K3E>s`aoKgiG8aF z`z?M!h6uaz{|XB^6i&6@Weeho;L+Z;jXV zg=ZK~7q=sW^nv?qEOtK>#8>sMWV5xg|Nh@-{{PeKXBSB8L`8at%K!i0aZJ`S-fbh# z3cIaW5BgXgNYs$1iGR=_Fm=_J_gCjKTnIRt6yDg;_&~v4{ttgn@9I5@@`ql;sA^5( znCunDD8~cZJdn3=?Jwc22BA~V^)wn~?!5Sl+2XUa*}}NnBARPW)Y+CENEe~CF=lkhhOBW>Tg{g}3hn`%% zpZ|EPQAFJO$6ssY{>tAkf3RKXkjw#o4%It9K6vZvu}S`$oIPisi@3>xmAAM5RTYw;|qqr@%7*mq{%W<`xtEgd-tub3{r zlsY`8dg8@XCGXBnR5op#ey?+ukxTA{|5JR8mOWQdWSl(D#Eb8b#P8$0Tl}6znjYV< zdveTs&zNUC?twxa89R(-=-TM6slM}jW8XDvsqYq3*d_!%tDSGM-C3G-b+d%VytHXc z^NXdOT~yQ^i)viF5^IVQhfzyLl_=^Ftv3ndEFL&(0b)} z9fjFRVEn6W{reR96x1o`z( zeHe{j+*$?2I$sy*l- z6Jc0kpvaJ5qyJ~Y&-lO1oCXqJ45#=x|8p4Th&eC*YR77r{dWq_RBomjN0|@Q&u45| zknaF02O7g!8$QTCyO8uC@w39wkNm9@zV~x#)o^9BzG|N$@+C#&9O#P64WN^xk2&ra zIGA9={{0`D9(zN>)d{={Tm$TK82(*9cvIt#z#kqqQJz0GKaBoMvKnkzP{IH156=oY zCgu+n@xM+V{Ir0bz2RSL0BB{R#}5gS#s3$F@aPB`|H=LEuro&2VR>^`J_b$+jLlHrT*qWdaeI{8BO z+lgG#>P$E_wISipK8~)uEQ4`;W~va^nB)A8G%$rdIS% z)w=%Bi(<3Gb2c;UyZtKBY&qx>CUB7Xk^Uc6+Xsmm(;p-RXdI}J|KZ4fAXrwj;D^Y; z2{Q7G?b@0BysDjU3w_jhPBH!uZ>W(FaBSIj&|hJ%V}%0K6p1<>fve3&>fiBbvpx91 zqgBeH(8Ag_rP}#p&XKDeD>T~zRGAO_-z9LhnQ4mD;(0Q&{%~kHwiN!XWpm*%H(#}9 z@*25@)(6HPy7#AiR}e1iImavffhyzY`rksw4}bj79r}~OF8_Z*@ga$Y zVb#8jTaShC=}5L(DnE6KKYcs+!4%IgLXBQ3|CB_3{XbK&B2sA=51Wni^`1ksriU^$ zzwOL=q`^P?{|)wo8dA)M{@+t=R%rOS|IdZoh7TJ!8iF@ zOak)e|2L|2GBU=TpWbP~Gx@;J{eL?X4&QWaap2JZ;jG|f^im<%%khEzQHBet35Opv z*L%0Lifx{k`|9+00YUNm^V^!{Jzg#&xif6@^B$%2B~$)d^xj*hSUv6D$u+b5nFS9? zL}~NP-u~E;cdgVe8J>x{(lbifIoqOHa#@=MSDbt-c43c^iDb`}Qw}`ko?40%7tWes zEoOST{>p{SezxU9ez1BU9X#dTxumK#L2%M>1dV+2vB5 z6AsFJZdy9;_|EfOrVB4K<~=z1BD?UoQ8u5nM2R~0oUb`Na||xETb`KETlw5d;8pg* zye7Hr$+G4gorx=o+hx|3{J1s8K$4@B>$0H5YrWvUZC@M%4lO(`qh8;#Tt?ASAds<- zDR|0;0_L+Ox2G4$9uPSs$=0RzxOv*$C(G~53Y^Kbd5;C7=cM+i4<|y-_7&wn;cR6% zp1{&6Sa_UOlyTyz3Z^-|o)({*Bu`FwV|SaKkK_Ct!_sHYYTk$6aUDGJ=c~;V6|;$Z zHLmYGC%yFTJf1r?&vx>%%&(YYlCki;*zV@U0NL1A6As8Q-#d6P%to5^RSR?9Jb}Z> zeY1G(Oo?Oeoy&8PUEulN2`_ER`xSdNPIye2#3xgwF7$nmfn#_{(76v+^u3M*7WXzv zL~5?js*r5%f6D)KYJq?>>+_b(>+&mBoNC^sQ*pOr#nJX=#aa44?{B!seo?Z@RpI7j z&!r*~uexSFPq^Zo-Z;Z>qjgj7%A60W9(>LZ{eOPm!j{YV@I_6AS$gJjp6@*mKb$d= zl;~Vovqiss&fIps3MMr{R?ZFG2WC9ix|S8-VPP<sx6I%l)$W*;*Hks0llhr<=mSsgtmaBn)BU-8y;CxQ$g?%csSM`GtW z%X1A6l39&&9?h0eeK&p2#w8cx)D(&t3=C3|=SDIxFfcG~oAAJsw{5{{f!0F@9ZIZ1 zPBbOti2j<`t7Rd^lu#jH)lyPWHKFN&xP-2$Kl7vCs~;}xa_j0>wzA?Cadtn>*!Vz0 znd7B$%EAW=v%(Hl`TMC!ushUF^15(5sEb=zHzG@ojUnse%7aW>mrZPDWntLF+LANZ zP`bU@lF7w;ndmfziC5ASUik-$@bvF-;SqJKxWn4Q+30yhpFi%yK2~@3#{cu0H96$< z!d1VO7D^Zw-Hepde7&ng{!o*I18Dhk^+U}71^%xNQ$scEA0(=H$u-w{NStrxIlZv{ z;FPC=)0vJRnZV23Tyn_Ee|HG=4 z-?lGdWDwY=+K{`D-Qk1cQMnsCk0yEi;MYE}dC`g`)g@>DIZ8;h`0;3n^%TD6IFMm` zo}VFvTU>%CY!2&!kOZ442BQ5Fo7{5Wh%&r{!GdSE1HJ&I? z(#z0dD(5*r{rJVT#fKB5@6F+4Rb~j)GMO^dJv`xspQVOLd@T-Z&xc2jJa}Lk?sZnYBte9!ds*XwgV#)|zwVpM)y{sY>=bKe zQ((Zs#^*MA{EeEo_*PQWD>?w43YPf-NuBY}~@)FU+2JEGA1Yp@XMsfkQ~5 z!I_ge4U3j{F*64&oKYem=xM)4>iT>Z<10Vax(_=wmv=UPoS}PpvGIW)77;ThJ}zNt zcU!6W<+1VttBkJ+IyyNiIjqeW3io%vP-T8#pye>5CxH9mhBD2DWZtfm?5@lmzql7n z5n<)rvqL~gi}7(`ffAqO;e`PK)_!h&+@10q4?j9AZfn%gzY>s9@n8*i>#-8U0!0p~ zhXD%^K(MX)D1(?r zzY^^^mNWe+6Ih z!2_p0B_A|z$`+i~@^FH2@S(Rf*E3r%SEod z@`sxjl0>GJO%n>*5N=_^RDNOO!v*Us%-xv-O{6Budd}ly+oL6T??VC4`U*R4d;N&_ zd<;iUMsu}0yh@hV5MR#SctygxxL|eTP`k`VZv0t$4QX+?h}plML`-BF02#e4mG_O?_co$fPfwIy$@4sZ4&;> z(5q1EP@3W>Beq0D*5HUEkD40828Rzj zP8l~F83>#24KWeo6JlmMXXLSHgCdh~V?zfkW55=X#th4Ln+Lb&D5*$@St>-yNHF9* zHd4?!SZxq}N=5cOkHU@+<;tUWO%L*$)%#XF6sXuDreE<$Ldqhe>dWysK1QdKrxKf- z1U5!Kd}t)Z;3F-|+idV8L6`gZf#(VdYZ-!!V?pbWXljbhXSh+K_;cRuH9eCXK0Zi`Nonw7Zaes1n&-t9 zXKgb%SKWqbzc|;iAISbvB+RfXP*MN1oAQYw_L-7TPINSdPj$Mf{~+b#0};hQ4j<0t zyv@ml1v7Ny*-jZP-=(w4$#_x9%AP$d-ZN}c(^N?+a_@J4>XT8@yr+4OSafIHoHuiM zm<^pzI7uH=I1^#w%GB22#8;B0&CKvaph@$_J+37FMFzkf6|+(D=ai zPQ>K9A=Wt;rg16iysV#nty9&?erB_a{C1H|r>{P`lI?x-~dO{bJoBs!fc1l*$x>_Wt zw|AaoKX`b#o!gAQJrP_!N)<-zQzo%1ST3CJrr3TuSb#U{2*2IZPeKN6Vi`3T0zM~K zh=^@J{BY*R2~Ez<6IWO!Ih07YJiKs>$2KHT^cb@9RiLB=H6X$FydRU8()&}&TGW32F=hmVKD`e9?|gBcN5 zE+&Xb8Y(5eVQ=klbNFO4#lZJH--8d1Df$-cOP2gKd;E*FX7ROeyn32XFDzjyeD#AT zrJXhJTx%HTqSU9b@eDelqT!#v}Q4H3p( z92064*|-|LxNo?qNV1pnwHNI?bZ~~gQ=_+w9qaM~1)I3|GX9HMXzLj=ePNw4pRe<% zYjcy)#eg5XFTGg9?sAt)#)`{MT}(c>)o*!INcV!b$}1Wbti&ue)!8kU=S++)(on;;Ng&T*Zu8=eJH;Ez>}2^C9oW3+dB1w)gKY~R>}qg6d_Zfx&lkmJiGUwd zYK2u4HI<)zHJDMuHuuhpkPG2%j33^WE|`%g$NH9el_1B79L=nQ-@2RD&6Q^UaBe=R z0yrMPlc2)&&%&UFO<;zGYDG;T^XGQW%%JqRYe9Uh&JUZ;JlM>iQFc-OxK8Ijp;qUe zNyQI3g!x-VR&TK9J2U0w9bx9){^g<79V|L6xjG^pjHz}HxAJzcHQN-U{J55jMQNL7 zT&0kToBBfUvz5B2#GWuGUd=paIN3F`i?5I4ReyZM#R+DjhYoDo%-iy4Z-k!fEsqB|8hbq+@;v9& zaFOFW#QZ?--HigtKNq3|nt!}eVG`p$vVn&q`2*i7@2USy*WNJE`?S&hz|-#*5$-J6 z`|8doUi`Cy{lS{b`ieE~%vSYzyz_XK_V=$ee_$ZnynfLFONX=%^#LLkV$qI$T5B5{ z5~k1b@hf?d!tkO|wa8H*o5dhULQK=i<>l*DXYzu*Szf3NaZ9oDOw?&tL6KH<9Q5 zzfq|(?0j>H;-Uoy!~~8%-jKX-hMfqb^7j6xDe+qJe*+9&#;lyWd1dyy*$bp+Pu)1r z_uR&ZZ6*^g9MEIum@nRardeQ3h)Pq#Wu}F}m$+uUFw|E6acDlfgC1v)Vu0l&l?V}D zc1xC}9t9yK*6J&n0t#(kd;IWubcjR4>!hW^kD#lIn)hlMZDwQlc_k+%#C%{eJ7a-W zPehKM7h}O8*~1N2&vPmqHTnF(A^P6;J-Nyn9=hC)6(14|LJyiGcs-0h+pvGZq>vjW zd3_SG+$j$?EPT#vaK?^HJ|d+jO?!=w2!A_wpQxzovCzj1HJSmEt!^h7k1`u4rLeB$ zyeYxnCKOhA&F#?DhKLK+bG|KlZ*Z!}`C;o487`Oe3m$}giL&9cj1YC&AQQ2lp~67K zA%^+k*@PtKMv1Ub3LU!q4Oi+}uh>*vv1)$K73C+q{Z6F7(uZGG{t^50MMh5Ww71jp z<`*XWkM$L5Jel{(?cAkXMimu7%+23991ScEMCj%WOm=qd7LaE6n3ztBMr1u@dSCoA5*5f0C_}VR%<3`@xyB9YuO%QqrRM z4hd9PHzjzSR$2JvMVOhNe&^*f;TXx*J~MWsW5+@|tS&P*hJ-OL?rnEJwDLboQ?I50 zN5{!-SLTCRQ9EDAm0VEnI(T7mGmik1QKyTP6&tMQ6nrc)U*uvV5s~)2 z=^)R?882j(@T7z=AM9(o5OT%iK&saiwSpfBKAg>h%sce{wPbYEXtG}xK4e{|uJ`5N z1Fp}zs{7bKZ|eLTwCs?g`m3uqFIY2%>Bvt{fB7K4!Ldfg#JuOg($nonU$wstNO3B9 z;4EKnVYB*xMMr1+)aen{;SKRzXSYW7-Sjy6a8`QQ?M0gy&N?kv@=VF>Lyg53l}F7_ zuKI{If9NoL^2;&pi=fN*hTR4BT6QN6xW&$6i$36Fv!nieT&ZhdLrP_VL_*AFUW1t% zSAKj^A;q*#_XuPAk+NgU4;y(n_|GYjKiGKqf8*jwcfLeU(DLI@a*zsJ<9>FKQuQ}-(jw}*7z4PS`C1ly zV|CiM)InFr;`_Wn1u>Q>OAV*@DD9rIzFB;_qcpq2PDaDy?T+_Xo)HsZ%KZ7l-^F0g zq&}~s=f&78{pK!RctgX^V3QYL=2K7C!-ff`J{-{HZx=ke< z_Qz8`PjFCv5vN_G(9?F{)fCx<4-5`If9`cr;7H8#xooZeqD%_>jM3#;^fZu7F9H{(f8ZBtcDzilDUxJsJE^UyEOsKXKtcI<_B@-`ex49-?j;_q9S z)spZcT(VYrr8m>(1fz;H$@W95rDWK&Rc*a0gIT_FDJ+OFa%?Or5;<&~Fh5G6)!FL8 z9bJBQ_NJmTr>@{b3Kgu^y0|7!5@A#L!DZ>NFCp89`DTO70I;@Q4-Ts)YuOPH9dDZdEy=)tE|zH&L-o> z+^m^~86jbFH(H#K;S+t(>?U(W-Oa`BaiXpFF0t09E{0Y~m!IEJWQ=55_+EwS!Hk6h zLF_J$y$?BrS@mt07#^$FI`ix?y!BSo&B^lc}Fd+T>_0RJTnVRzqjvcvar)(_^{8I zk44o!?lr%OWdHMXFaH0YP#Mh@v)XSur+pyjxyuLsaIx~Gew5lJF!fc_$5(Ft8@Zf~ z75=4tTOs@O)uZiODecFvUNWdL3FRn}G|W0H&t}1YNO+fO zZ9xB4?g|q{s? z3)eD_2MK(4<})qY^ng=-!{Z1Ijw_m}g$Gxzs`6rFKit6MWG`iNz;RxI=X(#yIU>w0 zd@Ki4trX{bp4MoMRVyfA+WIiU-QPxzl`|lWd&P_wzxcSg4E4HO7p3>N^ID{;YZ`EN zHYr31BrJ&IYntK6`PSe@0EfHs!3o?x-csx$!>zhpf>MkJo}Lt(BFb0DvfZG^L6OaQj&Mv& zR+Em>0<(2NdUoobht_R#QCK3%z0&88$8BYyw#jTuPMdM^n=!94(M_6F*~s~@L}P!$ zQ9aSNJpLsq8p5006g%H`xZb!WlG)lX&m>Uz;G{)}u!m!AZ=OxpE7(Q0+#XA^VvVRn0W6GbUKjzwEh(PR$&&_`=X)o`<7hvd{rTT zc*B%+;+#qz8t#wZ#?4|8`oJf&hv#arag~exNx!5GL5y8%8SF$DzF%;*S@uqj{Xwfd zL&~KGfsIFVtF#}a*~_oG`A)}LP3ZV61#a%E|GhU)UT{QSke~U`KQ_V4`W>sp9k^=b zRuVwigZaXI*jZM+vdL`EF+SU+g`^=HGL~Wsv zW2HxsaJ#>CzMsU zJFVWa#(>-L!yzG?oC8roV(d=0ViLa37iKva!N;1YEef+^2UXhUa>rAa7dg&6PnG4R; zDau$zR($?)Y0=9r=YDR{RS#0*J_aPU&py-b-|J#vdVoXA!OEEQZrS(%s`c{Uu;JZO9H%R5Cb z=gp}SALbr%c(t6P?O@FHo&|a=j;9n|n-7(?KR@^4$P1ZR`7)8cQ)nqPeEpwtYNFAn$Y7!Jz* znldGPsauQ^W8C^Ab|Ho(dgY9d5*?S?GQMYN5x;!kN7JmR-ww6fHeS+#f|FyiJN=Yd z4=j*9%gxv5!OASGEh@}3mt_m1hl!wCh|9`jPAk@hvSu14SbNIxw`%wcG_+l6=sM#m z<&`1tmSfW3Y&2y>yjQq{9Uqgsf{q`DoBN968a|?op)9%L4nN|In5XCk#>ngxO=EXU z==r(m&V#mq#q*Q|JGkd@G(_}y=y0|(Xt6l#2&_FN)gKh3_jMDoMk zO6Eq3mBQ_Z?ymbhL&G41EoM%S;1TUPAG(+??7q{X)#Bh2-V`Ac_k1#=!;yC`&)F8T ziZgwDaE0ZBzRd?GKI=mV`%Kmwu)4K+lr`PrbZ!uIW)Gjkhx;s?NvocI8MZhEi75gyy8%LZ}S~fuCimke6B4$3@ zQIg<+Vd8yjWc3v)FxdabaI`)FW&oMjdF#Rt-%>_WYFxG#6KF(23daQdJCH{Tb> zf)#xaS~O$U6}5)TSO~PRup20GI3?&EpSOZh!IAZ4fUE0)Ee9IsaWqtD*$6VM(R+A+ zjgf(8_dN*)Ha1(w;HHB&WD^c3q)0I-bTX*OG+RuGixpj3-mK2FK*i#{=JMv5-oL-9 z^c5d`kjd>#6%FB&^^ z-CcOjb%-%NX?U$7Fi{|aeI+aNVm=lHJ@-Wi69QOU7W9bmcwn&Bk_HLiy5%p2!@FcbR|!aPToVaam7;HQn-_o^;dW|zpYjN?8yA^fhp zL52{!%mX{^kZx|rv$*)?w6K29%kH=a$$v| z*q$E=bJLoqi!*(1_v+_q*ksT!JwZXX>q>I`QZDhjSCZk z4u;j_mauz8I2iKzngrdP{F(LG9d5UCVF#22*z(ygguZxk)U`1?ck+b~w+}TG+-1{< zotV`=_uxYgj>di-hIkV#(MYAU+l;D|1nw9VxT!8|zE|LIp65!ZMUK`U;|ja>#7U*+ z?O&QE%suc)Oo%s2u((M7waY;yl9ceb<||(>0lp$M&XAJR(oeC1Ri14oA7yuf;je~RSJS!~5)B6|3~YivRxZ4yE_tC?#}y5V6PdTVR4FvE=I}BLMp=Cd;k14F?67%TzJ=QNIm#9K z5f;)e;*AX|jER{a!k9j+K5Q<`W^n$&lc(#Ym{`|6?_&5oXThT;*MJ!=Vx1f&57xfr zInWrsi2L9xZpVb!gBQYVBpV(sC_44MzrE0}WXpm8`Sy^WnNmsx4<@wrbn@=GaL|2E z37bwqEboyYQRY(JY-~n5gpLX|A5CNw*!pXN&~)eu(PugKcG zSD@GN1y^i?NRxxu)Pn+Y)`u3@UC@o`5ffnvQ(%U|L{X zVZi8MBNOB%;M``RJnzEEbF2pMQqQ}rTCm6FaSwx+D904>t`u%|W~Ey8f)G9p6*k8v z|B3=uw(1j&xi47?9WOk%%esf1FG^M5h{_Si4_x7n3JxOsAN1*ScAjtgD#%yha9oau zg_rT5!z=ECft)K3mmafsYt?31oaCgiCQMJnNAA-h^$t~y?_Er-Uh7?+voxOL%So9K zW#ulam@H}9nDxc+Oo!wV1s0B;FHK7%8Y_$xS>DTYwPrFNN$B~K%ENkOp(6K=1Qs?C zvH6?~k7So5TvOp+m1#cbs`TL)(cof4?5j%e$npprZcop$)A{9m@hzyxg5VmZ!!1ay#LDrQ*iFmFHABnF0(x?0$M`{neG* zzpY*ypmX76y7LD`PA89l4@*}4zNZmT{_1L|*Zb9ZJthlJFE={OX?u}F~FG5h=m zixk}_3UObWQaBtc^ox@`v{^NojtMx5mQ^!oGBv0@4~oiAwAl`@(IWF zp&A_%r+9>%ddVprXZ=P*BQxgTF$HnW?YP zA@jw8lMWgN%#6#I7;ra!s661S?!$Rvui)Vz8zsiYI~8^q3N)PLGHjY-C&_$h!Mka_ zJbj6u3U)Ybh)CGl+hQ_oAnHRj$JQ*2IHBzi^S#PNGGAlGsXm9D*p=ZpLu#$`8dn-eMs+oth zc@DyZgCyJZff`Eten=_{6R7&m*SBJ?qjJ7`%VAt>ftZz`FbPj??0gWfsVN zVHH~P)!#cVj)%R8X=Ugt{U6RO)^@hfT<*y-3-!A%UMl`sL-T_~Y|_jNmKXH2?rfem zU%qSp)m1|8xA2!T?ARUg=TYXT4v)AMd%VAF0v)0{^S=1%pv~@*rOc-$F0(L@U)AKk zH{`GT)xUdYcK9t3V@eZ}a5Q3WIQU3FB0YS%d2aX1*U?V0f2MXc#UlH7OZ2NK+! z|Km7YUY%oG+|lrv>BHt3MIwx=5<@On&XrsJTr10vjae|@_bK+H_tN~99%p0lm{-il zE?BP0?qAy&s=+wH;foW;0auTPJx4li{lu7EI21zOu`#jPXe!yBNjT7vUa>$dAo)ts z4lS1rJxAYjG=!~ZRrnO%v@wLOx$DIF6`==pL>NnL3Iw#Y1mt8IA2oeUTzrs&i_!3k zV}%auBDp3DgAJb#IdLDX=w?!$q>#paxWQrZJ&6{+>LvwIrsK02C3#k;azsnIcy&lD za$NYby`8z0St#L$w(a|h07E%Z9?q4<#}Dzd>T}9RDB8K1i(iO+T_U{ViU<$4T!$W) z&lFFu=0k=LI2nEl9$0U{eQ{!W)0Qbd3$}VKoXEdmx?|a77N^D=?9-b%-&;Ls;o+-v zNT_^%#UNgeW%?eiHut>;9oWj783Y;~PBbwD#J-p!a4129Y5QJ?c z+gM-E(`eEV`@P`F5`LaG)&qMNJ31UMXucHGq7*04Us1)BCfsxHBZrWJ>AkGX_f=kU z91WQVt0Y)h^;wjd<&GIOD6_^*=TA;=g_0 z*%TKXkCnc$IH1<@ctwzDE_*@egC^$c zg8{7D_X<4WVsH%ZWL8LM5ok;AVYSHcaT4!xJ{BPN#cd+P?+Oi;Z~-TW!v`B$s?NJH zL^Ca5bro=zPP$%OLJhZ&R{7qr!s( z>3_~mhF@=6SbgY_Y-Uj4mg}*VZCtR$nX$ltxvAenk|l68gRa67Q%A=V$7&UgliUgc zj2#sx71E?6xU23pI`9g}oD}@oIzhhro=n4@a?7_@1!pSE4B~R0+4PdRVw!}8fPiew z_m0GbE$b_$RK}iDY`*g)LUbk5!oGm;B_$jUymtf{WQ@-+G%_h}St(+pCC5Ewp`l}@ zfbWY_AqzQ@Kc3j&VQdi8b+k1`k25dO`LOdr2MhTfjxr*x2U;HrNUtbx)I`2~c3YUqmJ_w(VwMy||ogwH}%)`AzpfSLL*+ozO;Qv3$bM*A&tWWMC)6KG60-lCwi`;u`d zLnKer7e(fG++G*F1SZTc$OwENw0edJJNsM_J`ODvmc>lzLE@Zjk9VKj`|yNt_}*6m zJ7n70gq!buNm#3sB-q%#h^t|vj;IX79`VC+9}lqh?D!D3!Omd9>LU%Yeg$U*{X|%G zEfNaO3bmZ*V0v}f`KS%+#S9JemIjA@9)^kYrn$Os&Iyqd4P;p;xj{}^mQm#QL4^p5 z8D<;{_H2-K>(}Aq%unD<*pZMSqs3?BqAH^&^I&h4Ba;WimqLZTI*iOy7_J^{Ft#vc z4~Vl+;j=y{5D@X8)<9n7|2p^i1u3f(W!|y`{^-6c->yl>N`X{ri z-}2z}bK3h(=G07Et115SLYA7mp57wGIDzM zPChmc6~#mOT+S_Vj}BN@F8aL3xcX4?_J_NU*i{-h6+U>NwfDJ0Kw58%Pk@&YcZCnT z@*J^_0~^^zHdP*2kfHCx$=v0yB*@Qtz(YgukwWG9|84?fe!ok{WlmUJ-Xro#WH{MfMO&U^A0MNk`*6VTL^#-%bZU3!F5E z=Z4^v0!xmA38JF!`IvSdZW2(deR!ZC*zs7OK-29@5^O0A_N)(Lcv#noaGm9xx-fEi zJyX$Yf1Z046F;~LGksLZQE*}?5Vq-HXWkK{$oMFr$Jn)*rNNBzSj7VFKDOlfEKR#F z3Nktr9A5A*VbVg~S9|>reRbY7#dxO8i}!oP_#{8KH&$w1NM7dO)cohc8TnIkHd+6+ ztdL0eKC;U`C&z@vP%>z#j%IzombriP$InORm~fVt3NGi%Zm1F4_rj7>&Gx~c1>bL3 z8jIGr=nEe7{L@gT{-SRZv#kE(sG#s!{ zGH*E$d+$qM+L1cx>U-Z;=p{rcD9n@*I&^O5!wAuE%R^EkEY|b*lGyh(cXi%-$n#FR zxphEsO!K@4EwXVP(z_HE_6RWTS#bG~0Jr2p3${Y*J2wnGR8KU0h|>`fnWOWe z;KBsf#(6>TwbXBHN|DNZTrQ%s>vtPj*&4-_P@9#rs{;L4J4gE?dI zf(Nd48j@@Z5o$(^%a0sL6=OXxBSc7I^2WvqNzA?M43FP&I5@CbC`!&#VN6`@x{{qq z!GqaRMumrk^}|Pp=O>~&99YdwZuW|@DhWD1SR-U}gzezDJ)+KY@@n6^w782j>{DQJ z+0R*GwEW-~0m-Nh=D`=MCf99WXnnqElVJUMw&cR&%nUqVl7BtTVx4cp|LShl^z(E6 zJA7fa==*T?z`qw7EQOaIHN8J&@>j@NbK|#N&Z!@cl}7D+ygBB<8EK||{(0-!4!mxv zi3l=gFA~rF)b#WGkK(;5`ujgjw^2Q(nWy_h`A3$DmOd+ERev+bp=j+I-OX>pR-V(j z-4tLFcxNS>wc$ez4wvdnMT>M4nR-5QD8$&tbsX%J4K!_><$Tb@q4AD=e56z0h-YY><=t62Lo2irX!*;Xpu~1&>29OA(J8kW?f=znl&;M-~Wr+SJ|MS5a`BwD~X6;ymfCBl+Czro`uFW%t|KTYQYa2bb zqOQsZ|5WxL{*Y=H=r~(X_rvUE3|22oL*gFb zuE&06JgmDOSY8p&{XKBVrFQV`0RlV*WUMqmiArF=1MYLjR7(e-{;KIiM3L4 z-{Z)|@$h;R2T$XA4uzn;ZDKqP1_5zg%?zULU2Tr{c&n#6J>za}SWu9l6x{fcLy(*2 zuwvkMajTjPnIOFdW^FCpt;&hLP8Fv=w8XHr^%l?Ja9DXqg2^PMA%;ov2cLpyo0lkW zx`!>ZgH(|7(PJ;vnEuQVVUsZCNC-%`RY(_z2$1{a5HW9p1KW&%fU_@Iw>ZCOyU6EMu`#M~I2n@R8SAwIu>S z>_jH*4EWA_@&8}`RqTiVzxl#(uNj`k^)$3r3Yq|S^v#OT^<5#4t zjQbl@*upR&FZy|?4S~{*F2`i4Vqj$ z#z$ni86$MWm^U*fG(@vr5qId|o+I9e%%G&j)WKuQ-Vjqz=%{%^fxFp>^I(O- zgk}bl4RehQ>`p3ku?yQA5fLkV#=`R@g^M$|XBMA8M>&&FxygbMfa zsm!w9kE|E}@ILP2AGyH8+y}SR*qc}}Ot29!xX|HPb^8SSL#L;lopEdp3pmOj9Qoy= zI=w}nS(Ew5kyj@#aw#f^F|q=MDFE1}nz~9u+1Di&HV;OXOCb zZ0MZN`aqGbfZJO^l|}HJBHJD(#b$k$X61tl+_4W9Fh7##aHzHrVO+5Esgv}*t|sHQ z1TLW?Vm@v+0zM^Jc;8c$ZQ}ScN6v+lyRuPzN07o!#sKc*#8gJdg~kgf91!XE_%I=* zm~Ud53ggGU3R6Uu9_45VN!)Q#NW)7(QP$>Alw*WOV2pvdLBUpjhlZr42Z#8aoT?Nq zcc>Pz-cy++BlUbj!wK($5p$lXMoc})%#tRWP{#X&)#i=QvSyyCt7a`*vocoFOK;2J zV-FnI4_Xwz*ur$rj_H-K!2brd{e~VV5+sBqn41I+>|Y{Mjt>D+=lvU+9DgOigcnP=9|N^ZjQ`8S?rUPDsq${O}KZQggXaXEod6mk-Xx z@4fQjAM*!mnfTc241wim``3iev8XYY;}Dm1KTyT*zpvvCPe)LJ0n^j!Ne(+WSs8S> z8#9Vm7K%x5GvDEBQPAV9TbX4AS? z@L)v?myC(!(`8(H#LuxaO`1{BR2H}aF}Ol6kmW$i6xNe`Ne!ax%ddzrI<;Pn z3AlW~VE%%gRS})69^DppYVTUzTMXw{^YLpgSi#e(lvF;+BdNTjdxO#(j|D3Xm<|dh zR>%r6o)%*6bUYR(#9kPXBj^-Ryz7Fhs+;#zg|wrLo8PcD9elvavcN?A>q|DK4NVRK zADo%Fo-Z<<+#n%n`<~+%m+ceX7c*K8w%6F1aU9sg_t4PJwn06Jla=9*QM74bg@MSA z10K5%Wqwq@;Ppo^dvW4Kg?gsLk$!A--x6Q`I=sQy!cL%^;pxw>UVoOI@%pv)@x`A7 zQv@{r&URAx$KG_Ig8$>eCZ3}KOa~t*xU&g4HnIjx)d}@$cBtV0bnt=wS>{*!Vl`d_ z@iVf$FxuewH@w=x!N7^_hv_+SWl0u+29^9c{s$5aFPs?;Bz^i2;K8VHpiQ7I?)E{4 zSjYbA$FEYu{p)Xd@E>mc|KiUZ`TuTR2RB9^nI)jr?EL#xg?!(KJ>C_Hu?vLQj~@^e z^(mXp|A5)4^_AoNr^(kZ1hmEWvq@b({Dbq3jbUJ|oq&GJ?t}9z_~sjx$Tcx#@YsZ0 zwLbZH>W9w^4zW!SJB%s<7!BC{7jZn;qR2e+$btg9+Lug1Dm*W3Iz(9S2y}4H6Yz33 zaAF8(5|H{Zfqm*34bcD_PPWyo4xbciSWY^;sH!$FYgdXoUp-G>&OO$(lJ z92AiVc(8z<+g6$JlLmK_gAhaEOG%D3lILBx8!cN`uuL3w$I~?1SKZ(HO~-}W1Pxnp;ojr^b)s|ChNnK!Da?70?!!@OvKwc8*<#W zT38)VpJgaf`O7ZJrYIra=RHHGz5UVOMb8&;Go94d&=2^mJw-#rW8q2ukRCn__S|mv zpecL@m*^RM{PBvDG4w$4ywCl%Z$-v~Vc$NVD|ctezs1+}`*=A(BnVkv+8E zLZTtTS$@TdhdMh0Khz5dbt-w7{`ga~G+U8DfmwUi@q-M~QA%taOc892kAAEWX*mDm zN1Ywp0@;t6(E?1|Q&&$v&i?th;~ybrg+z^-xHWak-Nz5VuTd=9d_jbtk@07Nfup?E z&a(>a4UH_)4-WsY@iOCJxV6f+pF{a<#XqLaO$O|ZEsZ*!vkyq|Gcuk($kxx(e8A!R zgG9Zmht+D14;0eFR8F6~*kCXrPUXW5wgc(>540Hyln*{o$dqS@uwmg?@WcLB^8ttZ zj~hM+=xz{cW+*Y?Z~SlZkNtpL!v_JE^HC2fI20W}B#5#%G|us0KhR(!$HXF#b3lwo zpu1)9gXRzE{SW5Y@iQ{jFdSz-;Lv9?@xeh3Z+02>hDKKBL#zx7^@1P&5NXiSXK!e@ zviret$El%ejExL6F+An3ngqTW2`xymudr|U!|&36l)ZZ@XVBLN?X|CXO60l!&*j-y z+fbAssKh#9OY`2Qhl(8R2RN$~gqXK9b||$dvCiReV7mE4fy-Y}A@u2i0xR_bi(3g_ zSs#A$$Wh|Bz_vt`)mdQOa~2`%D*}xMktY-~ZJiRb*cXO0EqEj%UfFa{P(oFSlV@U& z2Ro}ngcD!*VrBs!#sL&b76DLp|Rp<33u%jSOjOm1+N3%GS#DSdWOXRp_D7G|cvg*6=95^D- zkX)h2So@4|bJGT~m2;oXOX88ZeZ)cEA?&!TgWd{S;;JEYR>?U^q3Q!kGPokcAEV&xBJUm%bcbaICxgbR!@C-`|%X z9DcyV7GAeDzS1J3#*0NXi_!hv=A)f03j+Eb=fpqYV*kYOz=nl=A#W^4{Z`?|2MWne zvGU?)v;S1su<#^5RQX}U!kfsKDPS-qjxpiX6(QyyJWU5AA7t;#>so*OgF>hGixqNA ztQ(RZeSE*Jqjw_c6dF~|gatb~f;i+j@;S5)HfYEnU}Ici!y>srVm15EKpQzG<_!rA zYpS1$i1Z3FA8`1_c;HZg*{bhHx(PnS>uOhL->tp>E9rlKQ>mPEnDe~;7;VBHi`uO-a#ti~&4DUH5ETotn5;!;# zei(49)|a;oFklIO{6pM;JwSqaWpU#J1=q!Id5)~&k>re%ch_RGiK~%oV^MneW6F}B zMe7|-|6l&Ephml`Vbkuv3lopp*u*`!x76->arjz*K#&#+Z$zFyeyvg02J=hKX|o z8dl1cOB_7Ybwpt1`wGRGao<=Y)C8N&CzQ7_Gc%so3Qf?I7Hf6>bd9k@Jhe&VioMl` zJIOn&CHB5_5}sjTk)&0T!C_#buOY$ID3X%n^OV2q=!Gn4=C;l|k41Ffb9mUkdFT+3 zeVFlhrGh~38~$Fckahzn(YPRk1A8kMi1}A3#GKf~^n#o1MAhbn#doG~bUiR+UC_0V zV{cSD|GpLfX04My(6CTogN^v#dU;oFHiZjyjQbZHbKJwBJD7DhFuX=a9c`-3FKPxiBakY?Or!@{Zh$icWEgP)Ok#xx#AheM%k zva4D@%#dSZ4dDG?xFPYw-@py2bqpKo85giQK2X>%bnt+D3nT7KkYnQh z!6Trx@OI`$}l{aQ0Y@dxiJKmR&@Mkf9v3*Q8!NC+@KNYMUn|MGaV zc=Lh(=Y5%fvo|!R$T2bRf9Ad9zyY}!9#t)&f_)qhHt2CM9Av0a{bV%Zgbn-W2ls?l z7%wny5)D0Yu0`K2w-h254TWaRf$J`Z zRMcD=iYAyBWlp~LZI;T4iemyT0-Sq9m;@h8=;A))Aht)AVMY0#8wrXl88b9wA3Q4W zV^}RXk55ybwIFZj`+^56{x{E5)!~Yec52|h=w8vru$oKidsBpP``-5)3LoP_+`cyn ziB@{ai0%r}t58vx^Gb)4RY6%no4@*^;M6u{C2r>voiHfB!qnV!=|WP%iwyzxiqkGJaw=-viPET05fC_Rv_MIEUxg0Gx*bw-O06Bn z6*@9vO~HpGBj0m4FFt6oeeXd9LH>r_9u^u(1_8%o1p*YS9DcU3UgDFH3g3fFioE4!k~GbmsLZ!>&LU81yYO;E_jx&EHM1=kGX)2MIj4x(3iue_1EuL zus2lvxM9P>zTir2`@xn*9U~5{l?Un>q?i~!2$-y9GvjAuIx*3|`GCVUm3vo?9ekjW zDr8q8$He^ec=Ln$UHmWfID%waQV%&UeBa>kGjP$b5A}>c_%A)Y_CusWj7OE3GvQQw zh%t)>``>6g)%VArUfKPD@5k1|mtKB2{V~o){y-I@K@-mkuP|OF4jcYI4=y`=KRA2h z;sqb%S2iS=F|!ydR3ETYYI8XH;DdmCi#@07z7YZWcxjuS5Jlj6Uys8rR-^e*Q7W|MRZ@x%{&HO8@hD zi{!62GqL%*2s9~jupKb?oFJo>uV8qW%}k7;iz}{1z`=&uPocT@V9QdQFWrjyKBfy* z#9Jpib2wfR6Mdq_ZPUV(zk$QdM2nH(l-%ErP6(RqEUsQS+2 zoeF%tZ%zut9oWaZ%%=E#@eF|l0j$aiI!!0R$mSxM>gfdh*UoPO}b{&({S#)H>QjFwD4&sI}V&k!OJw|d`VRVSCg z_lcsFsBplMwRsLFtK_Smgh>tt3I=n6 z^F0{L*mOjtnie%(xY^k(TjiKxtB~@F%PAp4E2N}xLSPHygBE6n#)}+WtxO+^FR`vr zWOU(o>}P3Su~wmu<9NUXyYFrJE*n}D0=~9HNU$ghBy66c$h^kmfZ8VkX7knEZ0!sO zkMlA!P7v?Z(dcA--B`%4F3QDtFwwb@gH7X;*e8LYqNbEIRSEBTQ(QW_+*rOeHfVY1 zv9dDp`2{q#3v6!^5WmOaFv(V6wQ6Hh!Wu<|z7G!=ZpiJkk>Pypa3p^f2giaO{%3Xb zIN}QrPki3|gR9|*RHz?YNQ?lZ`v!fzzzcF*96Tjn-xsj-UzsC+AR<6Jp@M@il!fD= z0`r~Pj0-e_+l)v;P~>pF^_*FFg=`* z!FYL*r^FwL57Sf_QYS7ps#;n4*G$5Tzxt4aC~J&4!vl7%3*NI^`ehj$uQ4+w2JkUH zn4tE6f5{U8!Ac*VdmqkBV9QrxO1zh#EZkxcA`thbDcFER%VFgucBQ2pP73e6`8xFZ zJ?ARqq%PLqJZ(W0i03|lM(5(C2n3>}=gn-qAu)D1S;KI%vo5wU#4q4X-f zi9>Fk;zHY(?kG3MC88-20$q_r-$^y-nMhl@>f@`d}5&@guL)`XYWp&mfD}%C`oC*iN@5y8+VA}be zE%AfgcjdRAnx|g>9>OcZ#-bw5wD1Fq1K+B?!sID`|F3VDdEJQhkb_Xubryj_xrIfn zi7ZE}^cHa*7ts4OarV8*Q$y@R7S2)il5)0?;BeykCLmD2!zTBU!$yU@-@}FH4gV&g z9cqjVuJ2Xo>0#s)5-~7u5jgXVdx4YG1269CNs2<;cm0_UWH}vPT+q=ZJ(+doA%zZ( zMN^s*A`Apf#M+s@&{WkL(D;7fi> z0SmEWmWMw?R2cST99zG6!4|3i7P^w zO^L7e;Y=={9N~VOn4ol_9j$u~SQ;s$H8e3D-XqX>>XU>tSM@;w9_2$q?rKsU1v)Dk zizJ051&o^##01~xwk)3d&P7a_d5P?S2U}7a|5rXYm|%9`gk->j4|YrmIb4%w-Mn;2 z_=`u6_!54H7V9Z`|F}h`TkSmXFX4bQ!$lR(RVMOW300-_ z{on)pxeNz*m@h7VAQ!Wwdin9A|G!D`Cbex=zS7D3flt2wkYI(TeTX{G`e*WyC*4FD zvbZD+9v@ura@m!}#czZ-W;gMFdidijFRz>kV?*Ch&U;gMT=)(?XbFh>q{=me$xFB@ zl*3``8?hyaS{f?)U7HyvMBh7TrBEbZsKk~S5?~<0u&3ORNiCtni76s6hQsk4Yl1$g zffgY5q{)aw;X%Yh^A>{`A=@Vnc9JKWIP_Q?*((wl6RIy7bg~{iaUwzBUJCQc_lgdm zk4?GQnzEk5Bl4jDAKP3O5sfcR0S}tk+2E4ykI_1IaZxY^h@2+4>rXn3kJId{$a*?eGviXYlYwMSzGwR%bJl!0`%$ z4i^8C#d{wqu`!x0V`kvf^Uz<+tPsJ+KCQ=g@45t=8Imf_PHhaIv(9h}C^Ni1ombY{ z&;Ehk;f=%|g_BRUR$4f5*atjFRk$L-KmGi#2%ZAw27AT^1%Z1uZH<3e61?~s|4A6I z-`^@(GW&DF0Xc!trq;*@d_pZ#?e*s}cO6iStYx#deN)UV;`m@r7}HJ0T$>MPOxRg| zB+s$8W|96PapvM(u9yQ#91aC?!6(|9zBoT|IMDivQ$lRY6xK%dJuNDdOJ{U6+sL%- zJm<-n<->i6`;mkAf{64ba#DvQq;qU%IJhvZZtdht;*d}{cR}30NkQx$hrXr{2{+-r@ftQ8q55|I@}lKmNMU$WafoHIQ&v+GjCEV$Mg7 zhY!mt%o#mu4j-TY`HX<%2QlH_R~~IY-?+)7RiTA7;qr<{0=8H0P1q{BBB@PMy2)sL zg(AbDFAnD(W;&^?Q{?6seZ>_bHsge>&5ISxpPS0+8S^Ch0wc~UTu-R6mQpmT8qH*EnqwE z!x0e;&U_Yy5Ty@o%nqN|b2wPJ8#KGR3AW8?o3~B$poduSdSSimd-DIY!#OD`gPMj=J6ZXMX*vn0it)cW`#0rkA886;+2s3^z z7ved7VS@h>wWTcv8Wle>zdT&QW7=~3L)c}0q2q^Nss1TlE)^NcV890I`*SGB@Tjub z|6xAx;`ggrsh+wY^$s`xU}j)#JfPUD%_8*i_5q7MOouoOCaG%tlrV7k@x8!EZZ`YD z2AzMUO0yQaW#_YTIDgce-eT$$SoHnzuiHKXzmJ|OjNnc8)Lc-*@PV=JqJzrE&1{Vd zA7@%9$>{Wu#j+hymQ zWiJ*^s4}g%U@z6&Bg}m$=ulwfG!eFZ(bl~W_EuF(4&0Fqw9HxqsOZc0TF_( zoWYAYV;c{3 zMDvdx*6&8AZkkV3c;RCAm!;bL-HdZhgHz^P@jnQeTjsCB+`Y+wQOLde z&Lr;A$3JA5OFqc)?6JAFkmHARDC1OT3y#z?{0EvQCc8X4_=l}$jle#hjj3WR0y*&= zt__F3DoF6KxqlRIY+Z2lmE&GXp#$x$+eOtS{MJ3F*QvAl^kIucgusCxQ&uhw+9Qx* z!^2!6viJwfRAz1`UOk2bsmC8UAG*IKi^0KsBAde%IW8ty_Ll!!%^DnxcC3*;a9Ue& z$K1;v$3IFiY8UAWR^C7G^N|1hX$=nY*8exY``L7$=Ka5SlbU7Z4{B7gWnJZXx8T5L z`HNSktOzQ3VBd1@8=7WFOeO4%P#<88U-y8nF`-)cn$93JS7D{RLT3xNIo4UmB@NECC zLmOH|x6I_8C&(x^Rp6>~2;Utm#@)-$X$N}D;9$AM>V83+UE9Xv$5hcMd%e4?I*HXk z4L6yu4i&jz%jm7&(0Pon?Q3YIpP&5J0J$5t>b9K|(qPyu?%&05Axo-j+J7T(b71(aKa|Ov|bMe zovUBZOSL#IXHHbt{4OZ+!Aw*p_Yp_W8Of#xFG?S6ic262L{N*mm~p36OaP-6SVz^tyy#n`HD zLi1uBO^McZ{9bk+3+I|iPUJfgVcVLt@w0g6`MEr&mRD?jaK-A_1%WoVLy0$Ta=a?{ z-lOyI!$$X%SJ@Y-Mqt)2ugi3)0MGB^wG4=d(A=c^DCA{qT4*=k^Rk<%5me z_~-w>q14e|VaN1+|C98CE4ZW<@hn{4)L?%op~Sp1!BcSm#{+)^cet}HLB#dNA0BO?XRG#t zhDvv`H~xG6^8lYvYX~iJb=vg7l5yq*73~n~1xr{XR@n14 zT=4$zH75D3Jj2KT+t=xbtN-5^SRknLk`^d zNw8~$tX&=Qb4O*wR|T)-7o(GS`g!CW$|i8yrJoh529acVysi zX55gdBd`6xzVUt7#kp*(0tP8-^@INY5a)kh5GKUN5g?(!#NPPO{w;gg|MQ0qq&j>s z5N=4Y(f^nFqDdlUg`|T4t3xX5i4KL&2NDC$zjD}-X5Z*=U?mevh+V^Srw6T~;yS90 zf;(pMixmmT3R+~@_Z(QrB;Gjj%7Q}^@}@U7eMso(o>};f9D4 zqW>Qizq4W8zURUP?uG9wVqy*-+VJZ`=(kx-2iLnPPRP;e`!<8;e9N!b>&!kU#Q&;zHW89 zqq9nCz15f99PPUkH5aPyx$5pSSIFnp@_AQ1uDZ4I`)IAb^zAZB<3xjGc9WJnYo*?) zSJ-Hr@Y9gyKIqWH`Cw8>L0V^wxemAc<>yyJ7a9gG;OAD}xvh1bk>xL*0wK0yhmPz^ zTAEi%ES_s#XKAcg(qp>b79i}nL7D5`L!LA5zBh9%pQA8W>_br0e4goxRSe|Qn>-&J zj}a1@%hTBFZ)4Ybfy2^Iworm^S!0&u@7urI%&YN*ATJR#pqvYZT?qjtL$!reCwG^Uyo36Qi?^yWK?(vGy4M%Pt?CV{{ zo^ffeS&1xbabLx&1vyjFQXe1C<)0-sN0gCcP322LmaA+Nw>W*=^5*h{7krhhaj|?W zF3DG2H? zEvV4Jk9+t-qToT8**%&skvsDTl5LPsai{TT!*mWjHLWqlD_6%X3#RgJFl^dGZ=*ZYy z&|xue`0$T4V!dL4d~ch>2La_(VT_9}{w!~JKK1sGb(`u_PCqLA@L~78FaNW?^wh+~ z?!U&y7Z9G z2lm9$^fQ4G6JOd~u~7a0{dv>R3qK3Xw}uE^i4^^nKW(qJ-HGdSuFo}hEU)KW#}mhQ zXpY5=s}E1GFI+N3Jdb^Y-iyVvYJ}q+8OD8ZW;&=}c|z2P!Jp?)<8i4L1r=64O$HI` zd%+AATHkjzi15sub5r|Z1UD1o!tE=x9KyJo76^Jg*eGBoBg*JwSWzLj`_wVDi-Jur z#PoPGzi^&&UhrzhnFfiA8-5u!6sH`RdD-n?LHNG;>=!~Z4$sr>V|}1!#MZ{zG4Fv7 z)4sji4h0Hube#CCpe%9YlcGT#3x`4FAAd>3$`0<${@jgkx~H*rT<~x_SKi0W;?wkK zVnPBJ*DDsr2L?NSh)7J)sZeKc5o_{LYM6AXV1ukft%o|hi-Ee}jso_s_uCzFxS2T3 z#P}EzjdP@~usl?frn%6Dt`F@aN!VY?6WBhGGz>hrx#JPP`vOg=F^9tMq#2^&NiGK6^^ z>?mOqoMFiNV1@*PjpQ+g4S!7Rwxk|B^5x)h8(~j|2~r=Q$Qm~1$xCLqe7F&CIAIqL zAB)t4F2)BumyDR*78UJgSoDkW6?Y?7$6B5%tD1k`a7umrgQ?*{Oh5&PnBxNlb2bj; zj}I%H!}qhPu{Zv2k=P^0{!bw3sY6Y9IX^RtJ~O9ROV78$d##5Y*cso~F`mD>=K;* z4Re(GAL#dq@yy9MaO6Q(YDU(F5Q&B21=`$-GlUx>v~KC9?PoFCJuwv0?qXWzpn?ff`#M zteBzCWKbb!)3%bc<-p-R!Wy~%)8%bsjAUiSZN#~_ueUfY z6p~=SxViC&bAu66a(|POu};s?lNlyD2j(nD5n+BHe4*>bx~}6cPY-WD#G-kq_`wfn z!He>_3yRfp4E=(4YpjnCKTr@`l-RIGSXg8Ohoka=Ig%XQP6j?21_~cqSQ+-7WG$H@%93zkiFluQ zgB-K$p%t zswmNj@jbM#BTbYg;KP&MjWt{HxxRzak({(vdl$Jq$ z`>`@!cg2D$R{{n2H4~S~sNS#K^ze>Ku#-&l0rLk&=X)C;{`jN7Y_N>6@RfY(hqsAMTf-Zw zKfi1?)#_~ip`$9w!@c)!@(OL2+zlrGA`bG*|C;h5myO3vVU<(iR67j@34R&x17ZtU zm3lgu+cd53NC|ha{FPv35)qc1;UanDVMb7AW5tIWh6NL3Bwu)h8L~NODE|;*JrE;s zelDkzfR=cXV}&kD3s3i<1OqV(@dq=wm_?$#aU9s0!LUH(OW6=<=An z2ylDKaz;ypkKw`NMFlTHFT^lq%#e1i{wK6UnnSy3doPoLMZ(?(yBt$oVvaU=H$PY< z!DgbesQJK+BvY|IW{!Xh6Cb=Vcwm$EF+l3zn~4{W%n-Tvp@zfgVT9%R*C}UoTby^4 zn6fqQUOAcTp0HrthgSx*l1)E^Wnvub#n)ZbHLH=_|5Wj(!1K<_T`T-*@+R8+nDePM z%*k+JnMnJSKHi2E21df&>=TYzlqiXZU0}&)KVtlgNyCG4`H?U4;+N$f*l^%NeVNzeoaiMud4~jtKR=sU!y(7O$A$}D=~jHOI?Nz9qrpPX(p}1c zFJgk2E7Kz$QQK#-=XrQS0$)m>nBgKMeQM_6gc~2?%vleV7^txJ*l?XXW>9=n%0_}i zCQXv(FoR49OY>woMgE6}-Iv~b{QHHn#??)H@>fmZL)AyVHe*ezEZEvRr6;7zrUCg&2 zFXvUoV>aJ3hA_?-JKu3PvMX0yv0}^PIVafK5EA^M!%9*{Xs=$evS`JD9f`KDqc7TC zaVaZ$apa$fnCfbVzs&Q_$M`AA$@MQ6`NG}Hy-xg2?hYO^QKmjER>6vY$_(3DOEUNm zvx-z-=5hStD1S8aO`w}xL)ohLLX&a~`P&cZu)8h1e64SOKHnnFh7Bc*2i{wGaWvR4 zUWtg|W$YK1WfNm|toU$=^Z?^a^zXMH@cBGpmy!5-FvJ$7Qg z&UL1T5(*Al_x4`c-raKEj36`aF2lStjfdY_#9e^TDIe`9fhs;VC|~ zm27&vj%Q3#f*x*2y!yZGSfYgwU!ghImXHeW%tnb&N0~WWSlACbt=}@CNJ~;$;!^8@ z4OTI{3uZc=V>fXUXO&=QId+us#(E(}mXiw}B^IRL_0i;S@-En*%-wxq?}j9nc6Ud% z(%MVu^O==e9t*B^(Ac0O&9G79VZaJQzUCDca~{W5e&}Dpzp2F}=i)haG3EwwPA(Z) z)(f$H-bJ%_obZ$9>F7M}u!EVy>zHZtu}0;l121Yt3RKrN?U|q^dqnA=Ks$rSj-azl z8;-KGA3JzJlEp#c$JJ5^jsQ!^J-5umohEe6TqO0Vynn&F36We)8B*Pe(r5b}&v^ux zh%!G?G~6KnwV^^y;-6l{4Ns}-t!p?~lqbwM#eGWD;>J~$WCsmn)+1U?hVz@b=lN}j zys~KdEEb**e|n6>9dDE`^jsjj?J8$a^Mu3+3~P6pRD5GdP%4^#x?z%{wAqJ$WjqI7 zHMp{=B-}NRj_7z$ubnYLm4BbDeAMb+%GC)!>!xR%*?*wIbMu{$bszX{J`Gjcz#{*If`D_HmwoD!EUKey`ppY{9xtl44AW+BD+oz3ZhKoi5Fz-29t3qHsw zb{%%;k&u^V*eSm3U}wvLA6)#(%O1~vsK+<4!-e@Lhgj3Ye_460u2*VelvaJ+b-wF< zs@$1tvlp80zmT@_TZ;YX{rkzyk{pX4k`B)(0~>woIroXVsT96J=OX!=}zMjp>H5ypZP6BL|)x zb=bqn;=&og`ure|mBhsai&@?52MT8LU1W&hE7(%Q!j^nt=Y|EB55KNFz5cDZ%@5fR zGA+{{6$q5QK3F*UuBf~W-5L^}+TZ(-AmPgCctFNthwO643j#@3n?5?^ z6ejH5P$D%`T-r23rsju|V}u=}!-GeYoEj6>&0}>?6X8=6Z&sKQJIjQp@ff=V%ce)d z8m=sk8bA1&76rK5NAmYyPCPmJsO^NLg2IU(^TL?+$^@}FYW&>F+I^wBIaam8f=MVz zWpQK2D^5P^7jBZR{U!!k!mk)&nG+UFjg|~FP-9q-{9q5;196@Yg%(~9f|#4W1btq} zDw)3F`SJ&Lly|Z|3Tj)jruFE78jnBoIT&&%!I6dW`9I!^A5NVwZ9Z7> zkI(7&qo7@}>>&b27NoX6viV%XudQXr_(g>4fksO~u=e?yHB$t_z7>#o-R;mYCPPsR7JPJZ9W8$Np>U!~Io`^>7Xf)2f3b)P(%Rl&C^ zq2z3k&G&B!9m^))-)3p4`0>Zd$R}SnKl%@ONEDzzXs2bbU!tprMqVJ@4J83EVGPMWk2v{8>765UckauX|@_)*cAM`j! zDo6(L@H0MQR6c0fl)>jA+}7q`%5=TQA-3}y$_bXNc!G%N->u8a{B?xIe`Xqe&}=bNwysfiQ-<8#5rjb*IpeL36^}m<~cI{ zo-U6cD2QwQv19ZX-Sgr?1atFYO@0|WR^A^je5LGsJY46Q@)y>!EPgn{s>ktIhDDm+ zEj1p!?v^Kt=Dp3V(=sL=Sin)DEXvURz~U;qi7wj#Y4ttq{T=r``!5>AR5~wG&-7Rj zW>E2qbwmHDiN<5=*5?RspSEPto(@_lq|Qu|$HJHr>& z-fW9DcrDn#-N}*s;LHy(amS;6VoVuxYy^)z4tChf?i$Crqa?(JExlm!9~Nha{o>y9 zS)AgUdE~@dW2?Wk=yCr}4)73YZ98UVTz&jN*p~o3{wAY>7@o#s8LAB*YFK;HzE5IK zP;l%`NOCA)_m}3DVqAE_MyMmkkdZgOQTm_*3r~x1!_L-)+6QkGm9~`#%Zc+XRQzxt zRxtFadd!CiKBkk+43FlsGsy8}+qb(vxY2m@<>SihOp+gx_*XJa?|-<-uxS1c1@ZIZ zeVae?hQgbCI4Bkiq{>KYyA22;OwRswqG;Z&xo&Pcv>g>Bg5|3 zQsq_bq8mSD?@)3&n3!-TpFJ;OU426T0X<8``>XcbEG=@px8>Er3-xSuFK(RJ6!pla+f)JK3U+ttBrmX+ZQKhFh!y`nOaXp`M`&$Vv zIljiWg^Cv!K9bqOa-+n6<$%F4#RLt;z(vZ2Cb z2YiBz2cL;@Gs^vIx?;uAzhIs*TQjFH=fMpI4RJd{_!_N>I+z|>D6u$9k>@$TmNoxI z!;K3PS$iJr;FEpOSJ$WbyeUEKLhQu~H6F3oyExgM*~Mm8=r9_D9#p8&lHqm@QL$4| zUtn`E({SQMjTjXs#w+J+R2`I>cW8$<8y;|&Ja2Yxqd|$Q3>z=Ib3l)rFwZT93GvJe zoY`tcnCI0dROIuQch*1bYuI&=yKS;hqh3S%e5d0pEhhwN{LnjgzM_VGhdRTBy$^md zFHAqQpm5n`;XM_MM>IZ!h_WT0xZEPRyuHP6J@drq7A#&o0dL^-#e<>P3Onj2l z`rylf3eO7*Upb^IM!fULJm?_qaOP9uy`+|WC4+znA*L4_Y`9rIOvw;pJeaKIqTv$G zB(Pon)xPQrlXltE3uvguzklSI?R&WH`<1?Z($YfQSH-92nmwO?jQi48m8`3rSx?Sh zjk=m8z|a0KtLes`lH?jjW9|Nj2kTj+>=^E!ic_fyD?H?&09s4H%d(+Wv@;A^q zZ;px7%s)`q@94IYaiLacLd*Il^HWz=39ss!nx8cJ)z^6Ae*2~eJ8W3E7hC{e)+)j7 zvispb@up?|53^Pn2(dpn6!51eW`$y>xK#F9LGk_{>y|DSO}?77tbgBS-h<0HxmuRm zmH$&+{U_M5xA{jiXCi}yVvEe8@T)a^eNzM0KRA+b%5mzC>X$65Y(MnY^7Os`{q4n( zixMSF4Rgh~zt~9iHnJM8$d+64f8WiOOt2{qg&Tf*&;khuB}%oz&VIId$S)3+1xGRDtmaYmjT^Nq+DDV|~ zptR@5jSX>}Tf%C&9V{Xp&ral$vE`Yn?^L++Ym$IYTn3jy*yJe*XADFZ>@zd@-j?oW zu%xT2-DT!t#^4pud)rKZK4<=M`2P15b97@qGwrH* z`!YxMMfl1VWyJ_hrh<4I9|6Z3AsVoe?scsQ6AY~yJ;*tD>q-YKrT-Jw|XU^OeFzy*VId!?Ftm=-yH6kM=? zi?zR>Lotz!WxY7#VN3Z%$D12Wauiq(n2H=UFsV>sb8T^$!pm*n=#isQ5R>8K!IJsl z0Ly|$$%mXLc*ip)`pFBtUb|W-kmaez=EjG|5A<~%ady1?;75R*!UU!aK354no`#Av z=Kf~x9k&u!%-j$Wc)*Q+<;9cNn=x>;U9~@xVRJkdyI5EJ0p~3URp9vv_kJ>ppW_=3KYWmKkcu#WD zRZxX9E2SU0=179NC`Ff#RX5O zo{}l|Ay2kX;$Lr%YyH9gj>`or*w|inMpPIuILL8233h!>64;UEA=vOS?n42)^b55` zY?4tDsx9wX7sx6%eP1MFp~&IKnx41`iU&#ak*#{3^Jbl}HDEScgLkXQ@>W2-y zq*+S!SYu!j%@ZB)QKIY%0 z87_KVPY)jO=Gpn+7Kf6)faN0v3y+KgGb9)m1f1~@W?rFp><|arf+urC57sg^9Z1Yp zVVHO!rFgEjflymRLgXEZkPx{Ek~1_k7~gZZYTtJ}Hql_hha%2b2AnPdC;qO^2OCYl0haVyA>vld=5Ec2M&?unsVF&Y; z2uUZNY>d)jIlf`Tq#5NGCcfulSl#C==pZDccHm(}fi}}mi=-Omz5A~A_Qj5 z6yU7UO0 z_xTea_r(P_*xB;gr`-Fpu=`NseV0d0sTN)lLM#_IH!XOj#>3z2$9Uw6GTV|B=?=~< zjp@tIdn6jaP}^fCv1r4S$2&L={4n;IllWInIPf6ng@QPfqUKqJ4@CbI2?m7soaJ`z ztyuf~nEV@oJq;5?q!P9iu&p@1uyLnV#c!wYEdq!3q)Uo23fcQ}mef?d{5kiLa>HV| z`# zxlnShAR|k1u%gJprsK^H7HVepK|=f|6f`P-xN(+beEP`T&1l26=a1SirbeZnc^qv4 z;tp5DT3qt=Szfr6ygpbV)8rU@uP*nC5~tgv^7)f^z9=u(aQVDQV&<2gpYbfGIF9V+ zc*WGX;+le!jab99=RJ?7Itu*co)^c*_x;j=-eb@1iP=6q*m^M_LbB!Jq4#zl7f#V~ zapG*a-tZvCNiM}likER0pM^Y+yz3UR<&1(yPeg2d*fGK2U_ex1;yGar<_=>s&Ofrp zIahL+F|+ZwJ$G$xu#^c*NXp@BjM6Q9u)}!5-iHs)eQH=C-j(=@uZeF$rrTo~8PT(f z{4MGixEv2lH||tE?0HU>$4PzSgoA01A6&kF@T9&_!^a6`t3DJQNMYMifAF-05LZXU z$Nh{Ke*EA|To_fMcJz?qj1!0N{z$Slr=cmk2y~?%YzPiVX@8@2|P4w>dH; z?K~LxapCSplb1$*3k_sWHa%~9a6(68M$CVS5NupukIWyz7GjrUYk z{l0m={J6Kz;9M-1J!8SOXIpNsKK3wichgdp{w=ThxHq#NYT$Bw$I&p+Axc4vp~Nx4 zXu_=d%yS>GFeM+X2x9pou|wvB&IIBi0~`4q-TYc=H@Sz3%PQud!Ry+}Y@5#@T&$4i%=Y$-|8BG@o zj!5tta63Ox7w_quC&Ij!U6Ae2!83xB1L9hlcc}3#;S2hru|}EWjg08dviyj6h494_$pPK> zY}J-AKKyum&qISk`$DzWhYylEWK}u+n-?5xayakUmi)j%*-c$^#{)g)rsUu$ADkjj zu{TJZl48^JY;G=a$Yqz3UCiD-!9i@H!h=OjZyztP6cFtzVQ*7-K37M#La*t8j(aeh zqk*G{y5wYr)dG$hGIMVDSPAa2;N#Zt`Le*`jYGf;qjeTM3=LY6(lg?AJ~`~TLWq0* zrwLOgFdgiW=A0*gFyM2;antyzzCVPNIpWzH|M%?RTPY;ES(NeNKNY{?JdQ5Mjvezn zy!0EmnAN6bvQM3Up!I0-Mg9M5tVXMIuP(m&r^a6I)2g`DPY>U({(S04-Pt#GSMS^t z-Y#v_p~B%PU=aCYGFQX3mpg7U7%@0bZu;67!tbCZ!)l>auz{7aDbYbLz%bQ-Jw&|G zp^LLg!13apfKzj%PRW&?t1J-K5}qy9WS}D^Y$3`b!_M5(`lwaj^VoWx!v+g}9}=$o zp&%pZxA%ReqskF>#(SSPSo1mEIIFC|BWJ*K^R{F!!&;WVPK=BjsuI3Lh&EMe82E}T z{KMGLA!6ap+E`K$xAVad0j26ASA-5OtKl(dj_9G4`YILXXC+Sg$arhG6eyKT>=$B>>PXoZvN5&hyU>z zOc8XOARDc0FOjasF5KM1+_S@ysi(kBa?cB4bqS^b4@=&itqq;`g84tAF zGZHY!+VfxqADg3RjkUGOhdT-l6}1era%B8I&XC|)pi!~%8JkFj{RHtk%b0IxeKRgF zF)lEW4`Khudr^nKD#76O*~YDQ+rsoY)&F<;)Kv$_^FQL@VZ6tob!4O3bnR8_haBsl zC0G8Lf4BSP!%OSpSO1wh+h(<6V_0cmfs>wo>&KXRpNngjy?O55rLA+l)Adon6ni#V z<{YNO7eB~#)U7+D^lnxDgA=I%Er<3oc6FO1*f*#!^W@ivi12-k*1n zC6)7fm$S(j=yNzfdiZD6)&C!zgGx>BO*k2Pjos(}`8{qv28;rnBK8-4DHIw^hzMi& zV9Kh++wgqDF|Gzh(U}2OjSoI8C@^83H{n7@ibT_)145EKQ)CxQ7;&;%cqudlRUcUp zIg{~FIn#oi3vrf$9LEltK4xIJ>Ns(R9`~u*mof(p&U_G)nbf8*<3R?4B+m~M9#)YB zQ90ZOaeEB88`&&xUi}66$bk+yD2S0Qi*kj<==b|=^wNUVblbV&xLYsn)IovE4qF+y*WMRS=a6rk< zjcL*Xu?ZL44b+%8-485l+C3%Ah4^7#Ay33k+B+w;RDEXs-dz#caC!>tD@E-$~w+1SpqACC&B!w322EvgCk*&7>jyx3m+tMsf(?b@rY zZC4w#YKcg!`ghTH;vJ`j|A!R+yZrFYIUD)k|78Ev#eRAG%yGiRm8=Z^b$;!?>FBel zfa~?suDoj}Ww-NsRy{>l zei{`sn2QWr)EEz*u#78w_(QubCAr`b>w5XdW-k+-L!0xwB(x-39_U!Hm@)V6eQ?9M zVu|?j#}d4vd*915CnnWIFuy*U+PJT!-fzPae-=rv!uJIpnm@P`c4!^UaB-%d+p4gs|MPxzOZf!aQYyvr`gB%F@G<5o>-QKJbjC(2HRSJ7IuuzR9(eQ6!%JX_=)&Yy z1_xEg343Nd?&;n6@P&wm!Kq$N;lmmsJaLa2?+GzhShfqSd}!ePLZ37LE`F;8?!_$>VySNvaawzd}?nrb{SYU4u#go=xeJDUyZuhXwnX?}%{}9DLaDgyT4ar*-FZ z$1D+s4?AX7*G4Y77`gBeknO9twnj0S^tzmAgI1t3q;IQI>jwH)b1FoDI z87z~O4hh7~WbESNKrjv5hq=uXM>ARjUsNIuAU#pv1()6i{P0(OyIMv|D4u!^9A~ zXQ2!R{o)J~+!GAq)E8RRSVTCey7|=}oUzEHC#EscySb4`VU2oBiWr|5&&jhL87EB^ z`|q(4dH5rMdt=8A9yMo21=Ut&jt?8=KCqb~b6;`d0f#gFV!dtLlLNLSzHDRnuoha* z^Of^@>*3`GbxtJ2aPrCaFjVkc$Rr3(Z8x5RY{5Tp7q)MW4GW?=USQ0IA_|~&*Z{pmp zRPczez~{$s2glbARoZOH`{h8-$td<_SD?>9vj^`9(_ zNiuu*y=6U%e*ftwvYizlf3P(Q$g$1bV^wkcpoKxikDU+ZFz3vhQ#nIieeZ(<%*Q-Z zSWd_!7_&GuHzh0*W<7J`;zJc{rsPY9m<0IMIT_sM1O}uCSftcMuq!tQF=Z@JVN|ed zaXO%&BW}UBXcLEwKMzAhN5%sU5A9%w%m;-N%9$5#aCJP*(|PY<&bbNyy5@a;&|$+V z#l>;3F6)q^@nMD@P8at@A8uu+_Av{@?YL&TSbgu~fHwwiYLy3cncNxEgxCW&EL@Vp zC-%!L!eE1oof;QA7w7SVY$7`9)yGvH8m!_zAScZpAX4o#VTQs9$2^H99ms1`p zEQzp^Ffx8%xhS2V)8hD1hgo(Us-BLAor(lX`}kW-)0T=i_eUxJ=@DN#VdFB!=322m z6DAxO!G{zNzcNU4EHpiMW9avd8h1fD8xSRXg z4_N#W6Z^c)q43awNZU|BVaWvD3&{=7*&8mqFR(~5V0a*}`d|U`gA5r%7PV)LZyYscm0i3>k3oPCAM@k@ap;|0rW!n=Oe>|G$0P{$`ARsH#` z=yA^a(0Q>8cKQFaKC^nA=V|_7wK7ycHT>lNn$7#4Ngonat95_tFkza)VzrZO56adQ zKR)=}?820v&m@EsQdBCK7_7J*EsSq(-}1CThcO{)a>hvqE(I%=r3wq@S1PhLB|Kr! z<`rGRZTy~_rSqOppi_I(ilz)z+lLkpK2BWD?s!OHhQEh1LyyNYhhu7HqFjeHR4ytx z`n+gLeSUDFR6Wbd8B&~;OIi+f=vk;qc*?ZM1o-fGXh~jDD71Z0 zBE3hA`E*v=f%K9LB{sIMr)w?rdm6fCUU{L-y1v3pkvVzE(sir{5+=kkeMnJP*v8ys zK9$ozgQbRRB;-jGB87=OHLw0TU54NZ?x7n!|{OA#Re0GMF zB=Z#ZJ?eax&v)p`6cils`;>8Lts-Yk6zgFdpAQopf;6;J-g7Y=c>Lgl6T3val*J;) zQ`|kq8BseAFR<+G?RJdtnqb6m!K$&qPdZGc=#pyi-z9!Q3=c$@jyU}Jby(~C^p83U z`a*U#pPJa$275!HmiCf|j^0c@!Zx zN35F^h^dH5f#w zDzP!MGQ^13R4@khd2yyBeozQFp*LAwSWT7x;DSB>3M3A$JDB+R@thwl^@*pr1vjL* zEO>hVvctoPjteV-B1eFh3_ctc-WF1O*l+~bW$Gp8subY{V>CT3U7i5h1 zPVq%VIhZgioXhK0X!DTcnq%y!F5Ja`=#g;3o&_^F`BfLTrgsaCL7r2O? zP!ncsZuJssX{<=DZCIltVsX(x+%ROv5fn0+QA;t zm7eoG*qar5xGpKOp0`tM`n0AcN4%M7PY5S_!-fR~SHu+77}+sz-h8maX!-F6DWaMi zHvG_u6J)nMc;QUYj$D}wI*m76D!)hw-LVik;s2p<^M~j~3?aXmGt_K8nEh`l5q7+I z;K)mb9c@XR2P)32U_J7^O~JtOJr~2oDsETioF`HY6*`aSvOWwD=CmR_gid2oWL9&MeYwq#R5*3@ zyYa`$&S!tfGTpmQPN_hh@$jkdNew=2jX#94UtTTz{B5DQ25aI?IsOL$hdBP<7GC!> z$)f+zR|c=%vn?X(?Ee#$lkPrG-1bUs4(HR4g%$EMF74;|s8-U|t-hbx_`v~I7S2V9 ztt^_Boq3vQ%6UX_4OT9rlvE?&n?k=xPZ6MugNh)=b-h| z#q9H=#aO#;J6};d_E^2^u;RooQJ)S;SX{N?XJJ`s{P4n!u+`)L z+)?Z2H)BJPQH34HJvEk(nUw}#;+?uUp5(JPB<JOA6VN)$b+BTFOpegmX6_1$ zS(Dlw9tIQ~k@PhR z>=0`75nsp6Ho3X8*(rVU5=YkNnfGo4+~!i+dtvQ^1uT=#3)wq8?DSG97h;sKP?@2q ze((XSlhY$D?yYQ0j74n^{Q2_x}^`4bv}AN!Hl;V20}rBjM&37S)TJ0&j%p!5B_oUt@|Ue;QQqg_vD(5p6tit=Y>m!znsggy}T{du;qb_ zN=@Z2mD<(0p}A=*WUIqBw^;tqi%{+fW=v+dz{+r9h7s3+4FRgfhY}vOI6Ul3u<+1l zv{hzlDu{@BK3Adl9P8_jgVUr88V#oJ5O!mcb9hi=cyU9M;m>zXI|52X84gs)B*>(g zbBHY1x8UJK?Sl>M2ZIbkn7R8GH^g=^_}p+PsJ)!f#p09nWi#{R`eS?iEIeGIxCP!g z^R`{kUNS|-;n8J>E)BJUWLM?tLxGpqSLjSQ(>YH(aD~O30HeZ7|J?sX^~Ff`H!RrI zR_)Db)!c6(!muN~_0S88gO{H*7_vT-VSkWtQ9>n#_42U?ht-=NPChqRn(@+Ep2i~w zCh#Z~%rK7P)77!#lVVr=@_SBa)8a=m%@zx`yE7XUHZMDHxudg1MPY^!j~GX%;}HcL z8^#x}eE2l1Li%2WN%po)G;LWZap#HXbf%{Mmc>qwQyp_f*qse-B+NVz-fd+p&zjH? zrCTVm<1FL5#)=w_7mntSBqc62eK9a|Kwuq={l_6;9#%N%y>g%+0=@C zVXa(Ct@#(RHii`3V>B=*aMA~DdObf?e3kyE38zn`F7IRhA?o!47bN|bK?HN++KGcX@|50IN#oyQ@>h+Xeh9jta*&ch@y>2TGOp$L` zprC*E;Pdm-8-G7<;aL6nfyt#~Ni)CAJ~#gZOY;Z5mLEG5&(8^;<5l6oeAAO<edc9-qy9?0FynIQD}x!r1L}e{~C`P5e@Q ziB0$6LqisYIJV=A7JHc=RWbYRFkn9LXugs&lcItLYZJp934!WE4(}cu5R|h~pZJ9> z;6MzoUdwxRVaBed%#H_+2%O0;P%=H%@W6PnRE9#&c`oLo4@**nn?AnhbvVZQP`XLr zyZmI915=EDG%&}gu}rAqWUx8Y#(d|)9ft;eKFgN|&sp9(U5IRQTqI~!c%3F5+z{7#pdu))C&tHu(Zc0{Nt!&H#*+jsHfcK@(O#|% zUOawsj3Vrgg+KQyaI)L7UYL+!6ENjNTf{}~Mhy>PXKvr#p2jGxCCA$ulJA+Rym#$q zIk+eB+yV=u;&~FRK`Bk!^%a&k1>dXpYwm5CFW`{MdGEs+Ru0Ysx(8XU4|3c-*r>(5 zz=gphLYuQuft~4~VN-_)Lxv!$Yr&Hk)xQoYDhw4pj-t&{$N3-VF*2;+b9|uSDCD3c z$HZokYVyN|g)7M;jh~VEttjX;=Cu!wemwkxZ-Kdl922YH2h(+IA13hFhbT2%sNj&h zAk2Kgk=_0AffaI0ECs11JB->|KmBf%#gY707- zd>Lbdl(lH{f%<8xozBboAMmjrP>|zoeO0@0eqhtm@Wl=l9H8TW&Dn&!TQ)s>6xg8P z-_+Nt{M7kJysiK0rKdE~_zz3pU-iU~>8buV(J!x?e{da=)7$c~{$EB7N7nQLhcL#+ zFCQcq@E<#~>RPX-Ye86!Q&l(AZKlSWOPrW$9%rYT?_e0-~5ZBPSyh-!1vNYTLWNo_OC)~6pL`ot; zuvIMed18mX1e@aQL!UV{ELz_iC1{)|N>w)SspJr2ohQU`z@}%eu+4;t6JGR%=vX~m z;a1S0@4H7yo!vr9a=w%E5r5Vd`mT+K84qSFMkopR2MKhx322zG+Nd$T<8#UG2xj>3 zqTqw9i^B9}=LHT}8otu!ZRJ?1wq%jugcEyNc5(K)U%cuwb)JRahZ&Y}1vP9+dM$a9 z7sBM^MKvTDSDwstNaEw47jq{?)hb~x&%rt_h80Q|<~m2Tw;ikuZ2I}&4b#ICw&kiE zbM%>*H6A=xKeIzc|5_j0;#n;v!ZAWz>aGbtxRR0rBeY$cIxMYipR%n`o+wf1eN07X z8DoAjE29E8cf+Fs7lw^0Z)^8qLJhyTQp?<$>SOpBxlXWmrXPHuXepGrp@JjUWmb(G6UPK@_J)5; zjO6d}Gjexmc(We(ATVn>GylPcN9$&=H?*biRb+2yW2ybc-^`Fp%!@gmT923hd9>&Kv7!^JUn0F=|WSJtz#65wB;j5BUg%*25)1Q5} zZUpc%GQQ<7+ack}c2bW2fjN6alZiqzL;mmiR{V^t_Yb!JU*`Bg;j(;};{%2FKl(r? z;4h0)ZAI3WGo@>h)<6YGaI9>zr;h88v~!U^?}Qp^V& zjo8=UG~;2M;u$8{%vn(Toc~Qh96uvVgki-WFZnwE>O*E0a!lM7>kt3FW5&bG_rNPW%!WL<|Kb0O?n}Zz_~~J=QkW^{U0__V!y0`T5~0ZoCK?S&Zw^1pRRE@Z5ICn3yy!{uWi*o z?OJ!S=EKC#k32p`@X6MHII`tKy?~UR-v0W1941~l8{XxKj) z(*y%Wk#_|a3>PA12=_!pJr?`k!@w?i;!8j;Yej^Igfe4`;`YgnMHOM6XXu@FIrvYq z_>{x*3XvUZf(I+~JtcHxHDWj)ykYSWZ|EwJ@ncMJw$M}cV|w{8vRi|%N^|ivh6T|F z3*6WQw2$U+Al z4$(^+{G^QxtT_Ca9~3ZTKh&_%LZ5e8;(?1I;*SK@bWHA-Sk$ynt|BKumW}1XGpB|F zJmqZ-1ql`}R2R*dVN~$3Qo+nH72&s*%PH?-Jz3$5j81l>TgLyr0PRe$;G%?F&?1VB0V{OR_^ z0Tmox2OGZf9DJZC$>DJL=^cJX<{ygT%?IkEY;E|TaWx-sD&l8kJn^gF`wx!?KO?)Z zP$P$g5qm@P9ti=)?iDute^MGg2n01`u$4bJ((pmRM+rxMyn}4%6G~e0% z{mKIy7THJs9tR&NTn^!2SnOuV-q38~$-N|7&YvHA5OC>qxOc~bpOI;0!LRGg2kNKAf9HQ7&A5QG`GBJwkF9?C z!U7u>0sDrwSkSrevmfMZJ4(H#mE*?m=lNbMfhv&#vCD-@+9(~gPxZsRE`>L!< zNe{TzPkny)r#G{Gr(Bap+KLvhS^iJed)hx_B-VPFO!>oNZ}3smZ+@s<&7Kc6R$6lM zlaDaJ_{W;;z{?<0U?~^qr}Omi5(QT~fyR|G6N0!VaUbkhc2HW0L8P%lh*|I$gB!1- zjw0hB8^y-Nd5<_GS?^6Ta&l2>T3mftLE$2YP7Ft<%>`~r1B)mp=7z#&40`iKcmzvs z9FqHF7|C-`ae_;MPKU67N5a;FCJRN6Wgd+3c$jkVoVbGz=Xn>?!;4rB@JaNDF!oC_ zG%&pAVR%@0Kt;@=K$@xd$f1pVJck)WWIYc#JQo&bQEVv7k>T7oL6#?Boq>~ZQ_|5N zIkmCVf6AsbrAMdrb^PVuQ^|UkwVtidul8YqBmV~>mWK`w8y5VSvBuy*fSYvRvOC}9 zSn@BLvK+Wk+Fbl1n6n|mfXO3FOoVaKh7Bya7ECP@R2(`)c;sr5M5i{a;@)K>*x2wQ zM&64pU%v4$i|az+JKXFu*%#XXFp>!>61rG@mLavPwNYb<#Rn&az-Kx#i4QdnJm2GC zP{4HPe~?E#i-J!L7jwcPhd+u!EHZ4CA9ZREoKe)4mk(z)_}A*#V6cZ-hM$q~tPo=# zr@asxQ@}I1}j z19s*I2efzu_HjrhNHyn4%3o!9@IfGA6&u4NhYAiI#|H`WhZzpY@NjV~xM0J=mHOa^ z0CzJJgMp$uv-p7;{yzu*B$UW8abDoz@M78cQNo6WTcL?V$_RALg#tr@>=%DFg;NJi zB)nv+=CR3ZF}&qzT($9^O+CX7UPcQW7J&ta9L%@u@G|0OWR5??U?=|X!Jz;HCx!!w z7e7>R@H$DYXKHWYLT;;9=})X-dfFjMI~62v88$ z4*gZYJk|M-@9)DqRD~9n2{0r~vi~u~Zs}*egd<);$4}KNvpv50!Y!P*k|8nvmm%1bK!73AWDz zH6#AiT>tUrr$RmJVXdW!40Svy-U}|(u1aBE;PfTq@2CB%OcpL)e)y-;K0SST{s%9= z@$ZprW_+kov)piV^J<>oOWK-$I2_d2y>_86XX?=d=N_+`e23++;~x=@&H#^)_ZsqA zndcbR3&=_^=yqF=(_<&vbh0amO2MJCUsuvgj zWdA9UCi#D%_VLSHiI&n9g^4THKI{mW=A0wf{As}>rn+O290yNMuWnY1kug{Fo3Y}@ zo0f%4_LmPvA6hs=I4?t@<6PUp^DesLU5*u8&9}HWoRMb|nDak)5>thenwJcd0#`+z zD`PuDb(cO)QZc4iGP zR2B+ac&Swuh^OxoXO=bL;O@`9vaRMIv%p6OzC%JAwGYntm%`c3)^PZQ2t)dj#qZW~ z|6vrfk#FN+Y*?`Ls@IiY4S{c$g?{RE{;~6bEqm9-w=>uu6bmgZtNHtN>%!GjYMtE* z5C33ga1dayP~`tF+9_Dd#m`)!=wQXuVZ_Gpplyi}+XwRnGW*l^22MEJ=sQD2lp&3a zv31qd)pF*`n;$4KE2S5R?b5bkcvA9k(Si$6p9?HyO&yQPiFgHOA5>sD!1YMLxI$I% zK&*wOH%J7OoLoceogs zTbaJ7uHZ9y-eUG$thsT*gpOCuCXNAoa}I4@^5e)~@x70_QXGqq9OmLw%-~GXw^0^m zN?0J=A=|L3{V{v{1EW`(7T;MPd?++N%+7LxrBt(=MUGo)qV+) z++oA@Ffr3h*+eG8W+qc$;`jN2+>S@SvT?U2H|Tg*s5LuicpOVKaFfVVEBug{Z|i6j zw@jjq@zjSs1s@%BPR7YJF0FUk-s7+>iRC=+5yf*2?Rx|oeUF^UkzmU3@snh2OptTm zdT@mY--Ern%lM2q&sVrGJG&;%IQVuR$2{Bia83oEUQX+KqC5e!)^IEQaBMW_ey*W5 zPl(6SY9=om7jsWj!U`UpJRbc631K@bToWT!1aWxW6K_-A>UGe=V(!5L&Hc^{KE=ZN z8<`yRoy={1h%b}le#ns_CGm6tr+8E12EV20JqH!b8y-cORur<%SRv!=MK zz}m9&g~b66g#wEi1~Ni>j5vfexPS54i1M_p&^dn~Npdk)9G~Q#vwOtPyYck#_{}T0 z!p6sbW>fiF*@kU2yb5EcD#ar3Bx~j7OwqC6Ox#Iva^fU?p)3Nk1_6Z ze!)MM#sby`5q?IdR~t1qD|`@enf}|qnT3H@p827J5I-YxXJsk7ESu0iNhXdI{s%ES z9(o@>|Nm6nDaW{B*TtWS9Me>%2Y#%py+4o5QrAk7!HywmJ>UArOrLpF*q5{@GBmJM z{9;Hr(;%}(B!0n>eczv!uV1veL1Oh(2eq0Xxv}r6Pqi5oHWVucB=9s$vT0CJJyX{7 z;_^Wi83}fqQ$n)LjTK)xnO&?}7$=0dG+lIbV4HZrg>l=19Ri2e7=2oz^Zpjsp@$uc z^4em1o?c8kJ-6V*HrKN@I(lM~T<(_I2P1MExgB+%GqNt1;yS&!o+X{>Pv^r68x2Z~ z7A?pTaEOtcc%kP?_5!8J7S4D; z+}Ovd@Nj~b#L*CCmPP6oKh8DX$uO{!V(4>Z=@Bf5kY_lu;Nc9Pq?#5xuE%LoA`K6U z4;o}hD+xBwG?8;wVwia>E-~Zw!Ko~BN*`=ehfc4#RX6l_Q_(pWItzr``(xyTGjiw7TM+aAhsxVAM^6jESaR^*=SwW9iV3_HAEH=#&sVarH}BaYB%E;m$!>2qX8}Q`hMeX1I@=R! zH}Ez;P?HFDahwsy)I66{=0mJP)GuA(uHKp&$vywrnnD8-xES7dvL9ssSD|oFLp-S2 zLZ18o<_`%m9?Un^FJu27_;a0*%cM6;n4H!!?_0xGV|W^4EO05Y*L=x(P8Obu2iKF7#vwlyG!D)DYd% zr?#F$@zjToSTR*Lo;HW04=Z~3GQz&^QDb`JU@10};Y`l+DON2lN{mb097=XEZ@HoG z#kkl)i^)gEkmZV_i%4Jjo`c++Z4d5DG2~j;BO}AN_Ch36!KaxqW@Zr=H(e0={Ai|F z$%P1wp5t9{fkLVkx0GCjccgq+6Ws9NjZS5whK>s_W6F+YF7r5@Zm>6gGw||z-glsT zL*#lHUYXitc3wf2huQZwIEjWGYIA0B?OxrPPHWc_ytPi>WD zN?K^$e(UfMc812brUO1{=b3*<6u*^g-?w;*w#9P;Yf*-s3^QWlU3+w{u^)I=BO$12 zo4AeH;2%QTwRxv+*EiA((&n(Aqfm8kf zJL3ZrMu$Wder6dqeKx&MjXK6`4F7{04oEQ`Ua0!WYjNteInoVm0u_#re?N?v{ODol zfg5giCXdw^|1bnFf$pB;^*-3!T%$03CC|YJ_S4xIel4gf|MJ4Hf_;wyCtrfXjLaE) zY?JS9J?zfZpdw-=#^IsAz*2yX)zO7x!qx*H_>QY}vMpokYUGf5FokW0*9TW-b&EPS z=7f)}?`1k$`FV~77SHQYWN2z)VOkW%94E+g-eaj7>(Lg8?@a|aByKiD+|XxC>?m5s zI{E10iERs}d^{j{$~BL}MeyJRIdSohgh?8l91ArzaEsOWa5eKuHW}a07IZSytLPAj zC^&DUrqgKop@Z$vk=COgk*x^@D;CTW+9Af`SisMJ;BuE7bIUn19tGi}A_c})f)g$Y zIs_`pz0#d(`be?s1%J~kakd7FfDcC)#Tk$HylrW;zT?4{Fo&xn@WK(%UI(9s311o} zG(I@cr`XlM=Y`4#S4nv#mZnD=+5!S3_bi=T$z91`-K>zXDPc~JEQ>$mdLD)y4&n

^^n8X8^{DHxG*6t=r0`Hcg~O0z*G`Q@$%I=5bDuT^Ot_WADq_dv z+~U-vBi_lrqJXu>*dl`Y|IUXqItpeUb8KyH>t?vHsQQk8$2k^b{{ml24T}>NxBHGr z{*hqrh?`^;q9rq-_?(3y!=9!cl|n`j3cf`9@%7ALyJmCXWYY@AsANA&4X#PL3Ki^4 z99->%&Bj028bl-mjJ@7iFg}o3^TL6nF2h)!llAd-asG8|<$wG6A2O_vsNTo0$NE9i z{}uWR1%7z_nz_*ChjIFb3$7MomJhcSGq>>-A5K^iR8dg)hKG&4L6E)cn825x*I1f& zcz77GsdFeE=nFkL@Eg>JTHydtobo{R2BGR@*w7r!rHpaFa zI+s}4co~c|^qCHHBwQ%CaO13i-oeA}a~d-&7R(hmcu!jmO&(l44Tqj0&G0kMZLy5l=kWe8A&H zR)KJw4>#Y(N3Zy>z_~Y~6wKq(KGSXl2 zwmb;g!sMQBBf`j1QNlVu?Ud_#p9x%!?FVOE`6kBZ(QtuFpRvK`V58Vyjg3zlG`QPR z*$lh|9JtO_2OMx{nA_yYs&M(e+7|WdYa&t>TEZOnc->@v1bs+g+`@FwgKawB9u;Q3 z=PHd~WSAXnR6TSQ17>(>cpT$sGT5WW@xaEwy# z0)58}?n^!C_u?eZFf89Q=a^ip!<-K{IQfM3KFJJReB?mEB;hCLUBozCn4JX~xMKwp zI{5f_8QfVP=wAx8NjWg-vw#*CPaNj~4i3rAJ1#7Wee42$J1)LUROoG-VALVWF3aN3 z!g2hWkgowB!?f>B4g&XN7%Wsd<%AdyY(1J_#aJCBCEhP`O84i3f9!Jq4N4yV_!%J= z{^WkM*q_5GU4N~1^=-BA`Q;>kqV?(DaHq$O96LPOUQB;=<9jHxifjRAtb*N|Y0k|7 z+^tM*f2&`94CFNC|LoS}F-3WYkcevkqt^PCH9SrW8mDgfaOQ(?iKL?U4IXB`Lnq`4 zeAFtO*tAc$S1GWvG74}U3|XitKhU*jfd7UY-!j% zQTjm)FDENQ2eU*)6l0fILxZbIMFEdP9FyXP493Y7a}|zjIDD{}+jP*QF_Eu{Puzlw z<>5vPh34h#69r;E9=;=TEJ5r$tJ4BL#ufz@j*23d3#yFgc^H)*xM(UE39~#5oUkS2 zLy1|Ck(A8>2}4U^)&(AHB5LBClB`Y_7W`~(Q&7laVq1DjTeU(%;kXyW!Nx-uGC6d_ zAMB|((rC={opq7{pNNen#{{;WKJ2o>+)G4T83k1qY~X0H6wuXToM6Fyxs%V((@`Mf zL(AraJZw$(o;aK_XnbCMP&Qre$wCos#to?gdTgu?$Jidk@mMb3&Od`undc&l;tX}g zd{zY+>3i}G8+bD9x7+^ha(I4B;L`!m=gyDy*6V)d-y-t!IIJXhmE%~AOq zzkkKVzwgldt1cg4x|Zuo$Eiu&Ek$K9qKqw-7Y?wkKFeTWsHWp{V2QTky$JQ4%lTQF zxk`)~-#FwxJRs8Z^1zK5*(bz4d?>RDzVdN)}2m~nN6BI{m-ovaOVT@MWWI33v~cc?L`u|5b(5!^6GLq|%Gv4ykEN1x-+hleeT z(swK=oP2nJh?I_Y#etu!3lBfAcV~Kdl2xU<;aBQ&r#;&2LcA?PZOa)29v{>>_T57A zM4#n(S;nIVGvD(pZ2H13V6(QlbKZwU4jmbp$$LD~SQrYK6j-M)mVG`Tm$XZlGe}}( zdyA6f%QS`ehK!RXZC2Quy#3JYu+n)Vg9hW|#SS|-8CJe`J9$aKQhACJ3xC6e4h}9I zpD8+Q4E%XoEUhNOzos908T#Ohz|{Chuhi!8KbXn5?Wot3&A(5~I534LsDZ78>Cx9D zk0}D}Pd_>sXtduC*cxytu4igx*0tAvS5Ak#mfR z>f!jXqv|{i*QDh*S(|&>72>|{5olmnZ%I%VeW%AX?O;|>ug}49=9YJC2QD`rX7Dp) z=d8XmL$}03gq4}q@i0RG^YW>369P5}F`RwTv{;~FgR}C%6^?hF&uVGBBQ|-jMoNo7 zFv}rd*ZyK=Mn(l*P8&_01&S{@Ss4Wcl&oS88G89V5)m&@l-!{qbIw3y%LE%yzPoFu z$guM;P82>jdqU%pyDFS?jRG6b&3WXL3_Fr0N}2w?4b*}$+YN<)QpL);7w>m!K*5-Z|9w6I=p zRoagyx@Sp<17Au2kOMnDMFO zSX1jE}DDw&RV zEnrc|=2U)o=YL22+v28x=fVG$8-3$YEXjQFe)Tuk_@o~H7N-g9t;sSf3#A(!7!tNm zZqz>NugF;T!G*_JA&E`7U!lRXEu-nfj*trzbXXpwGflKKz9-eDe6Zp}kLU8fXEH@R z8ESK@4?C>;TM-e%Zj!LkV1kOEWXeK=SGpDged(+XnF=SL>AXneI>b8fdnboQ<;w#B zQY@EEc5nwToM9#qpx?G&KZmOJAr8?vQyvT5a;6+RL&mDO5{Xtx3pGJTi#ZYu8}uT? zR37YXy5Z=UeME>=@SYTh#f%40ULLQZZ;P;nFp5~Q#JV2D-;{czAs`tF@tlRoYTh=)_@`@ zmU9zr#CWA8xz}oNY*;3ccu3)bKx%$aj`Z!aX9T-`lm{zJ0ZAj;YpO zR;8`2W!f{pDjZ?=<8LvD*3+u^VLT~UO`iX6Qs9hwW${%PZ2#oC2MbkkGPFK?%bfb% zjggD9G~$n>!w>gB@8d64JA}S^S@Qqw?xU@hcMtPg$RF_V`d}~Gf8N3B)UF(fxAyCJ z8=9h?{VENR_2HlT|HdDtf_RIc`+bZ*yxZDrTT#yvP`^syP=#Bl!x_7EEK0vtZ(~{` z5fQikl#QKV%nI4(^`&<*W;S*#VDY{-sU$=G)W3I^Ok-Itv{?!Lu2@?T+!&x2=4Q8$ z$0PK7{~uR-0pX|p@&{%%-C7WN;E#l(==Uop4A%**erWjR=^ti;t5T)M^`)3USoKQt&|f8n!6>BW(H_ME$G9OSRhXE!i2%ehd`(U^bHLa;HtBPQqJ50Sk* zij_ZV-f$;h6G@w8Rl_3KcsVuwbgRS_|K&_S^RKtN-}!Jyj?bzj%CmMvnsA__T}SY%QtB&S@Q65JDcg5uEUKfEQ$?1a#Q5R8A>c1 znI6aqbsUIjI>y+}*dU9Y#4(?6*dSZ% zkRrs8_o;_-l8uR;kA?-~foIJOL3tI99OnfO)Uuo^d@twFaI|2{yMwEb99+xcTjj>z z>bj&#km=hFfAw$6q)I>hwW{MjaFip|Z*JumJ!{(vzmhBy{$pN-KPof}ta_Xceq=Kj zJ1S_qZ8{~<`nhzYD8m{}hHWSBm2%$Y^V@bqFSJXJzv1;3VZTMze$5v{f{Op}983J8 zTy4tCWGOL$i?8p0*Jg*Ovg>arPUUK!otyt_o=@|l!>{&NTsVHo&F_*zJ*za6QpW`r zds~NtiL>1O1e+_g4Nu%Vd$MMt*W%|f>P)xyw{P0o;9?YF%m0T*cdwB4x{C{W1Ce~2Z%{XnXx#I@~*)=cKYI^DuMc9}p?v?yle2}l- z(NCbE!;Xbn^+C~xJ$1ZNX$=XxK1fVtNRvO%-h94@+i|Ca+%_dPFDH)QtGo~HWqgz% zDb9Sb{u&3vhy7ohJtl~-GERLU`FYpcE^Sz_@8kX?!`2UzcvP4V{eS#H zWp(S8TN@Grnprq*RyhAYe?mrZF>^S^W_`r=Au6$-*h9}3^4oCk<3P|YLQT^YH zIZB1iLjJ%XKG!`edd&ZOkES*py7=H*$20}8vlC{=)Ef&P`66&boS&tkO`xb*gCj#k z`qzfUPn#az{UCR2N?WPtw>k0$b{uk;wz{rJT)Z>MV40C zDCV;6m$C-qUE(tGOw*4~i0PRY{BY*?SKGv9nX6je;d2%~?soBoZmrm!8urzBZ6=mt z!WXvK$sdXf(YAl=t02RrpHzOMz^;GEvSUo&n-6II(PtNC_#9xgty}Kn+o_ByCj&TY z?bPQTEZMl&arUtbA=TFy`##=7FNjDYK&2V3U7Xj9LM=asY(W?Qeu zw)db;#?|+FY;xEpK;T%4YVjv-#oE z#a7kIx$Bz>XVj|*SIPI}s%SI1`!P*;vfTASu!nv?2+OmW5_b1GOP0Mh^1Q!gC2gJ- ze$dJH6Vh(~mk}<_Q@oj(xnGoF*1}W9cKmL-b9PiOD&F|6yYyL{J(K$0ZEQ6Xa+N>p z^*9<1*zBodoyy1|K-Sp)Tv4ZfB5v>=CN7X_pya0 z+)%yNJ++a&vp|Z)isxX3z>f_Qip>Z9FJpYLEQH5|P3VPzLK9cUOm@}M6TOqyL zaYa2tOrnAu8{>sUtu1z$Mei>bOl91|A;r(mFt1su!kO*Mi@1; z@pm&+uuo@E4UpjNZ<()ryoSF;Ai?mB|F58pRf2C(z(6@8K# zf7ed6g(0nd@oq~#@q;>bXSZrz2<+GRR;Ae+)4PsodxY)eo?CwMXChtpi{GA<_903& zjCC^u)qq zr{7CoAL0#JcYk4-{jQ!A9yt^(*MrL`=^u|kh^L5Td7Fm^`2IR1_Q?}wU;EMOCDJj%^o z8O$(o%8~c{&rZa}M@?lgSR3#~v9YT`-unM89w&Cj-~h*jQw)xO1QX=T=o8|Qnu74H8pd{IUz@%B$v$C>k|JAxrv&$#)N^P4V zHk~8xLo~DC_O?8EMxFGzan1c)0uxG`4^F6F`C*E(4A1##2RX__E-pUpc2A$@@PibA zMCqdm4=4O+S+(!_Ts1!CGqd=ccAio;kmTX!=x_VWzLj%nZN%NzBF%4knG*AtwlyD2 zc8*@ucts)MORd5lgA%!uHrWSG$(o3HuQ=&%QzzJUwxQ8AQefR;5gWUn`6o=Z#9BiN zat{{#ZW2^wN_f}Z-~J%Qc)hutWOu?0|9kTo56(W$kl}Lw@z+Bd4z$Xa81B$Mwo$CrS&=a1Az@C!rVL;Bb0dNi66^!Eb*&6&$77m zoqf-_MRqkGFTboP7k}dLPMDW1T}If|&$`jLQDBA}H-k~g?`F;03nmvNeEh)LldAAj zt?Ajpj2gksyxsE(BG`RJY)aTX&M)G85Yc|z(ZouE`_M&&v<(}ik4kc$Y0HyiaeVcE zjscIuFOz}-!CryMhx7E*s_zN7q<1mQ7JQgs*m~@cfLp}@HV)(911-y2A97#sIw6>^?3_Q` zJ%Z#c7D&`&Rp&0|{3Q}2!Isa<^J0a?G~*W*tq&jAGz2oLsI^XzZa?l2T*AaK>DFNf z9~t+0PA&C4b!@A78QU7(nt!~p@ZksP=78im3mzp}ys`YFYP-tg9CO9wM}ZRsADnpE z%j@2=xb{S)rQwB16}oc#2R^RU6#sDeki$Iff;d@2#a{~#r8D19464#Md){WaT<&89 z=cPx*?uRGzh}u4F{`yC{o5fAYg~jFJvA%)|X357<6>e-5Q6C)B-5C1SJr_(!dDO<4 z@TFxA%jG=QMi!anU5pOr6EX}!0v|nNV{&Hn<7PBCd){-!O7M+;GJen-{~mbqa!zE= z3Jg4Br_IL1^&r9Og4jWaDFF`-uzqK4jLl~jbm*DD+GrRVz{1+x!`#ZSfstWG+7pLA zCLJ7?4;EO)eGF3LU}jiQCdARqbWkQoaIQo{)pnuw2QjlscGRst`fAU5#`Ywq9jcx2 z4Y^)xSwjVDPFmlz+*?pDaX^Og!Kpv?45t_u97um~prUSt$b$BYb?M%I%?BKs7#}$p zZE$D`VDE2y@Ie00r&TK*-jpdVv9bH$peN5+{{5bQi2Zl(eaeoy9tQm{E_`PRRygGG zuR_3asy4%!IeObv4IkLn-CdPvo zhW=E~oB!pl(*7rQ;*1mGdR$Wu#OOS=;bSj(lElv_)2qyN;Li$?7YQE@2%btl*dU~| z;6f0GgU5MAcJ(F!{)rD-SfVFAli_HH=__29SA5T<#Ug{BY0}4Ye9r7rJ0vY+SiJif zj~z;!eU6tc%`sqwD3kF$?)DD}-)C?o1~y;WAo7;={Fk5{Ui<9UL=K)E9-=o-HY&7< zvMB`4`w+z^{gEf=d#i#^_#PtzH|eQ@cP^|^WA6Ce;?Q8EZ6gqT-|es|^CK>~49Pve z6q*VfWW++Nl-LXowlrjD$gVgb$m_$IBOLk+&M2o;GUKolkFS#<1qzw!p%&46)Ox5uH!zG=&)ev)d#=$lGk58 zE@Q>iA(Qiuxy^a=vOdNOO>SRGoE|qbXh?i?5H4h1@j&RHf~f4H0}J~UJXwrdcskUN zJKpGu@^}8;EX&{UVEaK0V>>flHF=iZpI5M@^UDe|DTWw4@H^yK;9k@yajlDLbqG z-*;wy^icUw*t0K5cJjCEgdR-a*ZgXwYj{TQd^`443-zy5{^+&~kz8?j)je^B10QD` ze{|shkKjwzBzA?0;=|@DBJ6Ao5gK2eZZ>=dzVvu?kGRq)US1oEBnkF~!NMF0 z#{5>>n1kjt8^m$R&00FankR8zZ%3c)!2$`#8T?gxhE9E53>ATQ4>oYW<4}k=udu=4 z!-B34RZI;J!i4W-#9nMZs3IX|_bDK8?-PXssZSL`d+tRz*RtMHm}6q3=f`~@gE`-- zfO*!3GZB_vPo6xuvHRRCR;M}2yWF@Mot7Uuut4S|2XEt{d7lC@SP#E?qR-Y46TZiU z**WfW+V`f9C)H&{87?nl`52+c9vEu()%Hpa+uRtLiWe5Mb_lZYRT?hv_3-KlFw~Ke z=MY(x{40RFgL}b-VFOY0S%K8sx89*|*w5ho|qoTN^_V zpP`G`PKV2F4EnK81&pf?I__1B&@g9euJB?EvVDF`>}lcRhq+f-8t-tlu-$yM>iqB2 z`KgsLj13p|NV9*cp1^;;)J|Sce%16>E#9FUPVK!ZIQeg{+LFeP1;%dc7aVgoXkjz_ z(8GQ2$zr7@6}2}nIRx9dUAP+!mM}9!WZ!d|eCR{K zJqCv+JpQ9x;pi-*#C%9gtRh50<9i!3$A=qQT?Y>f#LeZ)ka;k*@tXvjgo+%~j%20; z{eV_Y{(ud#FJGDRC`1XW7A$gfe5X~(BFe(gGO_P_Gv^(43o$0;JEDw^w^Rx$Y*Jl6 zPVZ(mhk7W9*Y9ZSy#mgj=kb+uYb^ z)RC0aF4}dk#_bpP^1U((8ygn!@PxP=tekG)z}d9t;BsSDCdS7%ZZ}R=xOu@Ro&TBe zL;b5yo*ysVpjq9;*jcBs^znaAx%;bvx=cLZdwk&rl!5)rTU zEakH->UhNCzGZeg8#@|2eRV8ua@PTF35F`UbzfOel)5UqxGNU~GR|!EE7;Uc^7&Ar7oUbYn`j$@fzt(n1V-nob20`R0(T{v9Txo&FDWv1vEov7 zxB1bgzi66gL*WKzQ9TzOX;urL!io#*6Ip(9Iwf=|ED;Mj*w7>i~HK6r?)7j0(XW~<22U&pm$LWUm0*~oC0 zpuBkk3l99OkJaRL4K7H&x^=@}LnAE__QTR&Tbr8?CYAnbi2m?rs$Aa`1q;Jk#)qmG zybF&@N>vmjJ)cm1`QV1mUiP-xre0EvDH_2o$vp>;yw9A}!uP#zfg-CrSBI0NB=bGl zLo0sl@M2}?v9eoJDSB)xgTcneJ5mC3`JX3#cR%&{EMsexO>=Xo|Lm(GB1d0r;paP^ zaAY?71~=J<62Dfhn(-!?g^yWybH}&6gdxd=5G+ zP3(&D3s}%*tHssS#AVdEd`*1+k z@%Du$zw!zsqVIJzU9~(VD$UL>^Vl)`hX~)A-~}v`eCU z=9P}N7J96u7m8CHHgGgM#=d87&2V3&5MClvVIX0==!1v4)0Q0%FE;ZYJ)qZQ;l$Q`?=XjuBO-44TB-4<1Rl z^taN!P4Vx4HKPa~ouCypa}5k?`SwW6G0y3+-}FQEg-n=r!^%|$eh9tL>b!bpt=`q< zjs4%ueD_W4x{>(Rx~jV6;NR7Y%~$BZtKs`PgFQr5?n~Q}|BaLQy&HZVG6{ED|G?0M ziPKqO4o7=s(Ej>Or(C|bGic9Uevwtx!=N)DE{B^nKKnK|eV_HA2s2t03Xy<*HJTRF!rj%~)=)JYeM)0~Yj=p<=eeYCy( zL*$zvuEaM{W@7)Q_s zEF6s-Tn!uFFe*7FzkLu;qizM24V*9rnEQKDZb= zE>Mw_F)(xRkQO|(;IT*%_c>;!J90vQk30{w>SC4oF3QStkB3$C?G7dLCa3o-j#m$M zgiG!b;(9nkk)xkQLGm6~gQoR8{>D?>*Y`A-@kIwTG@O0-*GHFe>$avcM>W>dJ0Jf1 z>(DLAEG4vJ@(Z@BHLHbpYntxU`<+)&uj9ccR~s@#k^f&DS3~o!weB`iXVMabAJ0O7~IX}T<|YFRP@)E>NmdrJLI?+jUK%ZaME8X z`fqiYg2eQve&O8hE2G}d-NWoqp2co1EzRr2d3=EcE1Tivr7ih6qAsir7496YjRG~B z?y?#B+ti3`4O=WfNoI-fH|7!QHyi-L?11)rD4aX9GlR5&qa zm_C@oEa|{gp=@-q_~3#hhU=YN%?GQS977KUG|Q~7JR!OFJu9mmM}u*?G|Tc*hCPpu zI7k>BJ5;cMpTBV9djnN=Vdl1m2`*NL4jyr4lZ>0NqLbP3;HE0>B_THAlG+DFH%^+f zAVc9-c)5){tDn_}4DG!S1%fYacHB_I&eLb|(ZHheTyeiR(~j)PbELZuZaJ9g=CVcH z&%lV=X+a9>cgI5q6&jt6F{~)Iu!=d+;Tk5={7}8^p~MZDsQNvA!LA2BWPUw1mz}do z;f1jk&%YXDo`V8ft!$3H6DMA%;5p7{_+W#iYr3Prn}h|&3Y;{LaPJk!>TviFa-i#j z6JvqxE0%^#&ZddyDo?E1BJ&_6>3F-7z=Ll*+>UwjJXyT!h5p$GpEhF_+VWlgve1J+ z-tv5Vxa^G|eSF(tVHmdl)q2O4>~O(`39^eFnqAfk_D)~%y~h5-OU0$-2{9+0P7=5$ z^HAbbf)w+r$=lx-xMd2q)_+;NGeP9h6sBKR2QOyq@=nf^Z{-iQDybG0W#&$h3AVZH zy2OCVxtJ$quPon5Gs&(P`Njn^-dxCA$#U`g$v<}_=ZQP)5p-H8Bb&h@f1>j7%h(8! zx~Xmt|6ks>_^m!0!=!{Wah8Wq#WQx!ef05%qL$pVJxt8M4%8@UZ@R)N>h`6l#LEA5 z^Mc@xE$0t1)TuNzMtpl4X16J$!#2{=u;Ry#$~X6(yPB6=XHc+jvHh+eo_Ar_;fNrk z2Q2lRyJ|!jJ3clRRP7a!(2_6^KANzB<6KZe0rQ222T~Q|v3c#9m_4>H61V(t@LW=1N4n!-Q<;Fc zr-GgDc^P`2J5CVcvVB;xa9ij}F&>SThYwDiF-7K;1?ypHmxU=!TUB^OE9@3J_}TGk zs$G!!#L+k}#L0uBC27JY)?H>7G|mY%Ebg>wQIQR?IjN@7=fpm*+Z^MU7A)T>MxHr6~i z7{cVTV);q_YZnA0EB+O>n@#_JJ)-64tL`iJ?0-K>Xr1cuLbT8PaQcT0uey&c`e35^ zYJ;J(g&hk6&;O~b!d735XP?jX|No+*02_OuBME7LuB!j|>(sISPGH*d*R!@4G;S*R zr`)2??9if;f4cp~%pDy+4A@u%l{L(!7k0nh$;Ncm^_9NeK}V6L_j*lSr@xG|7YR!U zU=jSG@N3ncT|6b86PQ?5AN+r{Q)YhtAw{OmZ?{II%rRhGW>(8#CvTVgp8t8Mvuje& z0{dc?()g90>!(Juzfz9-`&s&M!vcm6ZM=-_S>26JDi7W{*u~i}o!Z+YTvxoqzM7SBUnzj;De8!{%THZ$%EOYPF)Dydt{EnO-rA$X=g;X@_=9OaLd zKa?hDudi@sZp@yi(9{_4@Lq?KRqG99551K~qM02t1%+HV6vE!~FnBH6;KQUR;=P=-!co4cvhz8b51zXf1rv+_lr}Xqv4}}r{jS;QoPki z6ck!y)V{Q}UXtNc;n98K$a#oEwCNdZKTmsM@EIoa7Du5u-j`S#Hi|Nf-BQ>fs={%w zs<}rhpvUm+9&7L_HCTsukyP%SSbY<-A-A0$nDkM#i7?&3-+iaoDpO`qS)zVVUY09V<9i&5`K1un1{C&S8_TU z{NfFGp`R2OJ?CRWrBC5w4%1VCoXqzQh83`mf0Z1^<|naM6I^*@50r5?MtCs&sM*0kwVCJqb^Zq{ls2#2+4sj< zTF+kpH`%QqF!tWQc-S^ebMyc!UVqH%u<#EZol+d8NRbSp8LK-kf~{VYhb>xrG|rt zMu_-A2QH?Ag#v<|hZi2@TzPqUqd;Rop{0U`g!p0xodQ3>3MFPIJtZU2Ic(~4*n^n1 z3+Xeg*!u8cBJU!@h%}Gz=>pM*ZgDyqI9zOQWfBnWdUi9AmFZPCBg?_^C0fF+CwLet zjyo{F+swj z!(h3HqPxga?p+FN4;>IvzN5;t?#y?M?VXLP?lv2^TIZR`GoJd)bz6~P!oTv(KTqYj zGRJc9*Zt)@Q?R$C$&;1MvR#5J@TlVCeKlve+ZnoQJ~lB#JelF(AzYUu;n1f&PlQ); zLb;%0<#mG#P7>)$R5L6zj4lXF@Zye;<7QBn!@vlFB_+Blt+ zn}nN=?+Ic)>}q{ak=gm&dlv%@0mndQgG-#JJzL&$WLdrwGZAE-|3qm+0{f0DE0}%X zyO_Exyrb}Nc2m&OwmCU3f0#xX>hb8uvMzIFynEQON{=;M=D~vm&X$JXjSeez?YPI{ zY|_}o)S#z*P=K9H!A0yd`6fje<Uu0nj;9_i^S0G`0Zay!IzcAC55P4?h z3rw!8uTM7A?tL(Ulg&m%AmYOYUh8`u8tfY;DKaMhvs6p?AgQtE_TfWYuSWEBALhE$ zta;;&?v8Yx2}$gZZ6OOXjO>({vL3GYysNPE68B5%6+$~~niTl&h}{!tSkuqp5LCW{ zF`A)JFuZ(8L(YT^asqwd+9oVWayS>@5hlZs#2xo3L5VqkITMEnVrD0XDZLDH*VO@mRF(5aN($%Op(g>9a9>9-?^c6@Ss$C`^sonH?BR# zE?QC@3KIpKl@#jaq}WBa%#nGxfL%58fV+)?Kwo=FU~l7&%}f(=jOCvTy}rlQ>fCR~ zV{x-#d+)ntw%)!M10O2f+k`bU68dFhcB!L?i+T}`ZVlC!0%4<0#HY&g|v@ri~N zT3^~2oeaGgR>YcB2=0CEn$&WJ<%-~OOFr8NFXTVnD%+I)@a2Rm!Fj))&t(kO$x(iE zL$uc^!DP9HMM3HeBZX)eo)-s>iZGiN@yjy?IES{oo|k0XcyAq(F{gXjv-(8Ei+_T4 z-AI{#c2-4q$a|TO3gJOrx20U!+ZY|QXE>Z>`SMFajdi7rjh*Ppd*3&Fbm4U5TRzV* zxk_n)LX+b<4rS#-+?5yPzV8*#;bLkKZf&%9VE%Fau}4cBmYiseQRI;LB*1v=Lx;uF z#R_xyIob{#-;*J*aKZIG8(O2>**YxOZ0k7q^YA|&Hia2;70w=KWV|%xt+eQd5Z*b* zSWYu-h>)pJXw>L;5niFg#%=p#!M5-GOxle%^yRn@Bq==DTd2v`JtrW?*p)?tX+iGe z2R&OP^e;2+TyP@AYUP3Ig8>g8aXxbK5_NgT+HCM(4I6WpYw|%osl7K3GpqbMe5%90 z@}bqt?n@$X*BCD_3CXf*2;1rC>D}L>@zw5c!6}Dl5;BTCVSJ4VpBj#RsBqnwxTt8E zQ+Z$Ol;EW+uE$N|aa(p^3-|FocFcDflC&4>XHUDB5TJcwZmgd+LxmGt%mia2hog*w zY)v0~3^rK!=sb6GcVzpq^u31#H>1k3<##5yGMn6K;ply)Az6IFfpt%eNZ*o$GuFH~ z)ZgaTEYQs_!^wC|S$=|j(Vo}m+7dgg=T+phMm%^ErJ^C%c+>qCSJT(j%M8mdzp9w~ zvwI%z>%)&+86G`oeUK2y_~|Rd>DB*_K4=iwC*bhHK%PZ6_^W`I+@rp<`&X7NySBcy zW1b14fhMcM%zKy8j1vzQEZ}SkZ)@4|`;M5KPzdY7H;N2bTa70&S2Mj-*f61mbQo%LOsNe6Pu%`kuqVSoTTAF@KK$iv@?yNy@%Y%m^`LeD%FqAe?17Q-ENT z$>&K-OiUaM4aGOA8FXYA)YA7{X#21=WP#0z4HAo)6I>W)p3@MKST%X4fWY#Wh78|_ z3L2_aI^wRaTnsU?e(ViB%>4~dWsg~e80-jo-rJTU_$5!X^6P?5iy3+gvyV;M-SdvQ zbKX=VgG-Mc=W*Rj5&aTjqWJKgj%tRL!iH9cnASuA3E_$sRwq`*^_&b9`3{Z^+}kHK z1^nd)D+G?M*ElH-he$@WtVChu7PYJbGxIlpe-nR#zo z$;9vj&!_xbqj*Pzp|D`Wni7?jzdF`bt>Dqjojg(9^HprY4WjL2;9U7?ZmS_Y7f%4w>gmcz6zQ8!++mFf}cB*wi@t z9LJIHJ*uL-wsWR%zv&AB}q8m2It>}F#;S14d$&|%f;r1G32;at<( z#srg9kJ*_NdcI0FHnTBUm>e`x?_ze82%0N#Bt+nNzyt#!<|$@;23$?M?{zm_ek}RQ zGWYz#$d5fvra|q`?7F@k^gnq?LtByYgWi*bI=&OjolL|%@7+rDRWyha-?`>Q7QtNhDWb145-ESUNx zsM)vtPq6WupXq0(t%yvl&EDZ6cdXh;u(H6Q`)Q$tyx5B1to8r20+#QU@BVhV@>rd7 z@QMi?mO63k7co41d*0#eB85*TCY~oAb~Nlr?{K(~v3=VT4ap*JkE1R^#>^&;HY?Uw zxf{8#HX1D0d)&D(amE%6=Jy^goGb?Vg3JOth3;`Ua5GKsWpL%R@O^L2(zL$vdq-2B zI7@hof`iUOj)IH=*C%S`6DCAoWLfT$BoGjNktM;vBcV`1P~pr30rO6V0#S+c8m#6` z3zRthc^MzFJZ%m-{5U~|lc8dLz=~HTQ=Oc&CknKC*G6!)#YoIhW)qz+-h1g_U`CDy zx4;xDNd=1)X?!^iPIeQ7X2`zbUAQ12hDrRwl>h?~(Pn2k8ODOi_a+M{$t(^u5M~bI z`EbTaW`lTu&=IBGb6>h}=$>eGTIu3tRI*s*#3XjrW~PNcejhxT8keuz>2RlPvy{RL zg92uW77pi+iauZUWiL42Nj|mwo2z)DoQ!8vk3lIn({=7<$AjlnIHeWY_p~zevndEM z%hU=u_b>!;HwE{IZDP@wc|wuF@WCRkrs+EcHmgW-Hg|oWC}Dk2fSWORiuiFp*F*`? z!03x9E-fqvzVCU#liKvDLCV6aYloADqJ@*Jh={F#tCUk>zDk3Fgw;nDt|?lg)rpP` z{2V)!B*b@UNGO$VSnAr^(YaS6rR`9Iy+g6XE{Aj7jD?@L+e+g8CP)g&zVMR{%z9`b z&Xn%h>c`W_$Yt!!P<)BQ(ILgi_9d(0s&JRw9)=G)LOmNj7F^$}_{zzt;z9cy+lLt~ zf&P^zWHjGb?O7GU{LsH3fN_#dhr#wH4k6=-tR;=f9L|D0Uq#OtDZW!=tZH#u#{9s> zX72MjhmX4Sai|{s|0lpE@#Xo}3l1^`eDQ1vVozCwSkG}dgrv7I= z^*wJEFcERq=W#f=LhsJR8wPS8TD%YPh_m`tc(FDezvq?to`+%80WSmINlLs;6J)sM zzU*Ei+9koTWL+5R(Ip2~h)LWqEJ|F*?$pTKIqAU$Bf-YQu7@VS?LGSBO0biA=PCm& z$u@l#i^mJJR&ge5Ntn5y@PVhS+-HV}dj%{B|D|li+1io|;`WHN?tK|7(DhM3OhC=} zB3GXm^P0z}8+!6qKu`QeoE89wp9Y-N8eiMD_J*{k8x#_#^k4npSjzMtRr3YI56 zRNxW_n-CY^=zNY%xoz(mp7sRR9*#`rc^-W1Za(}=HiRfDs*5aOEuOqY^j0DV>%w(j z?QII${KZ#iEOasx-qXTpa7Li<%!3Yo$+N5-j?5kIOG6wjLLR>Jbar$Q%Hm$i(&N<1 z;F1{SSUKf|n3h6PM^iaB!wHK7zXU19HwiT!OcvGF2U!HUcF2b>c*Hk_$FVYjzu-s0 zF{!S1%pE#xV$E}MyqeB0lk3o9Qb=Jsuy~$AJ8#e)6-F;xg|?2irp>`j=c_MC9Bi;= z?mWd1+m^DxjP>4!7KPA*8Wz>_I$ZcX9JW4~!p`x0i6N8VI>kJ82FY$g_Q!(7EDJ5p zen?rie>GE_P;1+P6TccByyBXnE`A_SDxmTEuRr{KvtC?D$f>j1<@q;Dl$qN}Lgqlw zN~Y$9^p1ZPYtMH0@jrYe>R=ScqpN?m)n&oKnROq1{Ok8e{yy#V zjg#Uv;}Xrc7Pn7Yb)dsDK%g;VaomS0h3K<#g$8K{gbo~>&|^K3CE&>1rjDi6m#PAU zSy_1FBwW}h?RcQ-XRGcqHR47fi_i0wO%7{LiQ5UaioWxZFbrfY-=oODZGFaJg{dk=Dy6(nizeb}(>D`&&c7=>ons#d3jHCloUTLkY3IM^^AH{5pUEU)c} z1$rJFj1zpAk1lzimIA}23^q;@{cKr#gu5L3n;HclHn8b^ zIKW(e=z;iYzV?$oHV-Brtg_(|QfzW4I3v2~a6<3vkjiF%$<=Qi`vU1E-FZHoI>Ga8KR>PzX}x2yqxSd2@LvmDW3SZKC`Y`1 z6YBT8Gq>WO!m0E>rSIQg{b=mpyG`*iv%SUV;}2X4d4H^QF8{y4VFlBF4d>9Qz6(|a z$EPiQa7JNzko`|xMd{P-9}A{G)IU&XbW=j3(ebPC;q{ICoi-ne>a1BBYIoP{8H+|M zyNj?ui-5?Nrh=rVb{5AgZ-hhz9&#!ilC;s_X=ic_eAZyPeBQ$5#eJR5F)|NU{5;9| zzOq0fZHHTd3Geq>&`u~;N!ZKI==Xi%jMjV?{)86hk1-q$eu9OH=1W8tCyO^M z5mubdu2j81)y9-DtEC%d{FHK8aMV)VGoUAw?c=+5Gua^-OmH|2Ztj@*GDytS9 zGDzu^v`8@#UvNNSru~QHFm`EHMmBb})Z=VCAI@knc6>^R_{XOqDPv@?VfXW<1cBp> z57wp%T={XA^~U-~6Is+*4!1QuJ<)PUnc3^Rki2@tDK%COf+2ZkFB*m;dls7XyOlzLW6pqM-da&x^p&m|4}(T z;YX_0gwwC~E%>s}PX0g*=gXp%weOQ1CrpcBocI4t-{zms8!Ak~tmj{@|Fkr|i_`4F ziFyVTo&#U_9T^n)otQShTJ6kG!T-TYz~Il0{ptrl{Qu3~&~U|@;i^})m(|8Y4-)wP zZ{Tm--@GS7qC#b(yvtVSwH5U;1+7dR6CG#rO!Z&IY>*Yh!^M!#DI&S}75A$B=Q*81 zzAQL%FHx|(;kOpscAEtIsRusoT>C=D;n(_=*EAm_>gKJ_ZogbWk;s4`(?R)+Q3%=Cm zPhHwt_+Zhc|2Md*h26_nDqfX;6nM+{)#l8MOD_-n3p(@iz}e?j_a|~42xOONp3MBYuxd!-EzKGIedB5R+#p_n(CTFhi zTbd?_vaI~RM8MI*h5cZaR6`%XSAuX{SL2N$7T0yvH#80jXlb_^9w^Y0`)=!eupp$E zp{PK)Ire>lqm0%=S&p{d_de_qZ4?(?uFev?pwC=|=lDaWH|dt=s&rYLIWi;|zE>$S zb~Ic*$RQ?r;7};nyo5x530BTIdNqO!D-^gd+z^m3c2KLRuy`-LM~-2EgA`jrxQl?F zgs_h`A45R!hF|`L?G4g>rBMeqUzn-)l;xff!;B<8cD`b(Yd%dZ8B{8Jl`wb_RWFt#_D?C05U zo8A6Emr>#ThPlz*?W^)xV{O0pKhS16P#VFa*&x8~_tx&$gLl>qo`o-JB%T_{ACYun z%iCb1$+LXNgggW01KHtr*0!J7k3Xn9W{_5Y_<8|ToOEN*YMuk{q(7hQUl7H8&?9XA z-=+hn*RNy$(9rx!IpN&&TF`9Yi-6Ouzu<=COf`<$#-}^zNAtZEULTLF3UoVmu;N1? zpM}2Mgo+bg3l^kQnDICTW*!WXJ2ctnL)5~6#qBMQt~#1Z9OvYV^yD_gRm5;<-}`Wa zb#Yt1g~>1OMQWVNi4%n#yW+f_?9kO?N(_;`7|MG4@W(?1CzBJ!7G+EjU&rAz_aw8y z&JPJMCp9Hl91P%IIWs6iOqx+ZdBM)=V@mCfE3)rRU6RJdP&n^k04pzpj)0)6w9}TR z&8m)G2|G;qBm~buik8_0(QRBD;54oH+e0*Y1DtM_5SbXAEu5gzU=UPsbLyk z!QaYY!Ny!t`$tgu_~DOg{S9fWL**MM)LVBd@>HEj<4_6-5lB$1?>y7#@WKAmf#$^* zuOxhG)Mv@^UiJ9u)zE`~M1uY^^Ea_H+56Q-7);FQvH!6{At0b};sS>cjvNK93LoV3 ze(Q&euKv(v#Qz|a?bn9P9OeeG6?G~M^%G_YHMTGEb~t{(#*4##&+p@Li}Wva?UHQ& zP~$ChaLRj8O@kF82?vs2EN)!i{^&w#foE83sm1x)1&8!lrWGYM$jKkL+|0tz!o#8D z@c%)Dm)z==OT<=vFp%dk<7eq_G!>ADvte&+sFA+yB=9q^XzO_`_QwAym3O(=?=gSi z?LXDp`u*QpHpf4Yo3(@(n>ZYV3M5|qKm759)DM=%hYHe%U-7duR2E#25OBZG!tWm+%GxybO~Q)>uQ=NZW;Hp=h|OV~{O^N@f#btOenvizPb#tx1EhB8 zF)niKWV7}9Fe5-Dy`5S6o@iUR<-r%pY8iQY5r$$GHgdB)_a8caaieJ>!vO#;4T8xkI|`h%Y?~g0*vp=m7o9MV=Rp0dm{%X(v4~$@Wye!_g~_M=V~7Ob z??;vricLb>WL8u>)DYndsf?S%{voDNVUP4Zy&r~0>x9@p2FzUnAN}Iu!*xV7 z*ci4t9KLb+fb|F0g4BvVQth8!YD`lNeEMz$n_AcYL((60!`tNSe{(kfP*~*uy#3!* z-v{Rc6%#`PHnJbkd^n+&=jqQMlAQ7Sa@;Mu|C&E&Tg5CF=*Ry+m%-5a_nDeYfsH4~ zLZp*H%fLg7;X#Y{rQ;r2tPdL+w!TaWk`dc&B*LS4^`U|8mk&PrkC&vyE!w@pfaky- zR)HhM2NSs7SBf&W@31qUbRf1Z$+72j1ef!nbPGK}Mx!e-T!&Ax^4!s2l(2koBD^9^ zh(~hSQHB$I^SKzJ3)C1hbZf=5nI1G`IPnNqSPJ%D^gg4oy84JBo51^kA6mQ|jqklT z7=XrnG~6}x_#FyabaWrB5OkDmS$9rgo{uww!<|cA58PNpxGoAkFsS-9!@AP=_=n=A z3t|4he*O4x_TiW33w{K!to+;__4cDintdY&$H9uH@6BxOR{#4cT9GDyG)Aau@jIcC z9rs)f8!KK+lDCjQFW+3SXNJJ(^&Kq@P8*DwSN%7doB4$C54W!)&$AmTUTh2vd=;{l z2ma0evUl;St8K{-AF%HIXCr_3fc5c@k-z61K2TJ)TXxF?d+`TOFTYB%zgi(-w7_`N zTh)p~3>wT1T5=&yUmPuDo0--ZoZ(5;eeWV>q_A_Ml3>8S56&{S=M~w^TNGFhJUz-_ z!rhi>(0Fj~gBCWnwiE?fhD~jsr`-GA%2K}Nh=SyVgvBQuIIA254tFRd#0gg45%6L6 z%ect9!8pO?kbnr&@kxwCKmq5HReTCj!XkR#_qH^KI3-+i;;wAqX|Z&SShv!;NkC}sL4_V8 z&p8r(a)n2yh)LRfY!G1Fp5@5gCEnP0A#&f%7NfqsC(?cS9~5i3hktH&HaPomgPc15 z^&R$14D*kE^w5}bZ(?Dd&F#YmPn6E{hsMrV`1Zg2U3>F_x37~L^wP?^c=;_qoUm&? z6MI?pplEo=*{a3w`46o2v3$T0##0zzcwd(P!8PVhlO25IlM?MWMi?458~oC5j0xZ= zZ~6Zq<;&XkNsP%wjs{{XJjXr6m?v^5Huj`UW^(9=zRb_zAj4Cs=U+WTl39_5`C$4E z73P+T1oo!yD|@(kIGU!gFFLSdYKKO8-A`AlOeNt#C(BOO2+z|1_oX4}nF}WgxFRq8xbAt;@ z--iy4DX-id+?XEieWFm1zBD9BYQgut3R^4$92xH|SP^*8%aOsviPgy=O{~Jnd7hJS z#Shknj4hUr?{geBJ|M>Qq`$~fWR0C5L(B8S2ONJfvCS>8XG$k3qu8@PR#FR~tHQ3#Y1Wr#`NqsVY@j%bJGb&Cb-y=2vwG^|wEHzA7KBVmSU z_2qyj=4F)z!Yp^5G``)iWwARjD$F$&K zpAu)Q_C0P^k;ex)7Vl_c%TIjC`aGl{I3VP_r`P1Z=`Is&6*CGo64pBwePe5gZM^Y| zm7(hM4F7L^ZR$-Q0#BafwBRZDVBc_nok_BMrX+Lx^z%7A+>H#5;lq>>h_hoXl6|2M-ST96C_t#_Lg#6=Gq+Au4RCVh~{2cxaOn(}Raejc>#z z7%_7^R}tn=ln`TY->a(3tZ=B2#hN$B@`Pi;>O%%v;d?c>B@BYj1x(IZaO_LuBsrNy z6EsBF7^G!iO4ulIEZD=z5XSnB`#==yswgIg_d92gnWUPJIAlh|FuK2(WeSzj(6+#^jE3A(`DJ^R}+`L}8DY@~5MK0r)-*XPE zIl%Iz;7QBj8wHUHA687@KJZbF!y({&fU#SPf{pu@6As^7g!(>CU~HJNeBq3>4tLmC zMGrG6h%`=aYbem#ah*c;` zoY!D_R23l5%IK8Ax@b%5!6Ob!K3w1x@c9s8;UHsL(Zss&gw!_^CvKKJ9tRieJHm{{ zdmk>ajQikWkihR#aDgwF{Su#uBBMs&gBI5BQrq_)Y!KsSX8NGj^w{>DM~oxOVaA2` zB-nXHH`s_xwMdiuzGv4Vf4io)&v{-aZ1FgwEf8>IO`AiCc|nTAWFZ@Y+2=fM-+SoD zXfqaMoMfKUQOME|QrONeEWvc>$b$~EZoyPTh8cWSecVn-Dq>oS2}YhG28!oBA`Ws$ zNqrLg$idCj5Fu7|h#^jZyJ5$z%vhD;{&mZ1DcVVM|M=GG##rxCMbEBE#D(XL`95g5jW4LGh)^E93Afk zal6e+n5DQvOYK3hf2-5E5|$+$8nXQAJnZ%JIh1O#2aU*?~!!!W?NU`Y_V|mStjnvD~^RnnjM#mwkXI-J~-g+*U%!yu%c0;Y^OyC zvvbqoOx8zC0wTseO->7BOjrv%S{Ho~6A~?OVY&Nc8rR+jP5j|34vzCg1KB<#OFD!- zZ+p5$h*deQ$5w>(P!h+AFOgviyxo%ndK_g0SW4CxA1ruSJm2O+ThQJ|4y&y82)1kA zapRW0C(|OuaH+hdK}Gq{0^xg~g;@P8lmyOs95Rp+Nf6NbGNr(Y>B9FW32~0+a=v{Z z*ydlC3y3%@*~U6UKBIk#JjWCExDPFga`H_K#|s~St!Hl9!6W(WF3%i$9wt>5ueB5V zn*^NYJDL9qnsdn5En(ig;Gc|uclXr(+V_p~ngzZDfAv~Em06H~%lqGoHA6cVIa#5ePwbyug~1hK$GqEo@BfD#Gn5d`AO(I1XGe zR8&ZBQD9*>`9zWTCBwzLZ43teN@^cox%eftJy2s)v0kNAdt24m4q>8+$V(s zt5SuvEsHdCWn{Fgxdb_qDuQJ1J?RkObZXyY%#nQWNn`KfB|Hxs7Rt4pWOY<&T+_{R z=d%X;;`wP#;j?q^#bC&G}$b#KCl1t0hlRw#t8`EaIQK}CaSa`n4U ztLnd8UwUx`YyZQB6gAE(K0M##gbMh6>PR$XI13pucx}G%;RqL_LAs12kNKXg8!8%KUhs=zw1&)kAd{2OG;N#%%yfeXtqm}VkWdpPH35BFz z9+FDF2RYh`6d#`0u=1clhlz(m`yy@?g=JrwBr*jQ#H*UVbWDihI&2^#^MCT5Ew|f_ z@JleJGav8>@J=}3tLWnK+{HAI=|IF`r%Qo6AzUA19yYK!?7VpNfQh?Yi9(~tIhO|) z9GM(qKBjOVYS`o8X2*3Yy_4gbv@DC@;TX;&$@j&4Ss|`2>S|0Iqc8EVP`Ee2fYpnS zt@+>*O`Fzz2e>UvzAxfB$f;+QxT5L8haY@=^;;*!)|;$JxDd^H(6E4)rJ={``A(IT z_9+4mdg)vZIthjkHyOX|Vso4)+-&>&6R+K>sJh^Ko*zYW%P+O@u^3;U*ej*dnvfu7 z!sM7A#$zG2!7G7T_tiT&?hb{SdleNT1cLS$aGc|C=#boNpsU0vF#SdZcY)Is14RKL zivvoP9sI0&U#55{91>70aAFMJp(v5g(GbJc%3Gzdp-DkU#@JRxL5Z1JW2KORqvf5g zHo^{D%J)8KVs)u#ONqXx$yj*R39||m86DIroFwN7v?yOPY!cvq=OW6~*uZr_=;fM_r~IyS6?QqwK4@ZIu=z?tl-2~t#`G44AZ?B`<2f^fWfYb6 z>Lj#?$UWI$BG9(e;ETsm=DmsxiXOVm*8D}B4p!-V4A|UNCu$rFOo;0|#Btq7CDx@e zLTure=7kR2kCrqs^cX5}Efla&FLaRPx^!Tp!c3k+()T_Z@H%)rF7RQO+B9)A$+xvr=oAz-sMVXfHSha7AR&6hN6JkiCTU!lTqu<@9X3=fNe zMC0Rmfy|1HRUcZonCA(!DPL-s;mKGb-gF^CyV#+|fRWephU6k{7Zb)0;orXW9^~OZ z^L&YEM21qspYw%ZgqfDV_YaFS0xkjL@-~P`-4+0TGUSQ?AP48&LmZ*33*9G_w=qaE zeTdTtSx_Lt!^p#zku^ipi=|26;d@zzogH^1I-E8ie3(#h^t__km&65a%m&{rS~;s? zf;Q+GNPKT*;AUdj%i$_{vTf0!AYp#j#uv?V73P=-I9!M-QDty3e6QH9aQ2Pp62XH- z8^m*X8Yc#DJ9?-~{MP4UFc5sn@@hgrSj-x+JFH!o;}vB9jA$(?-eoS96qDZIr6q z6cidC2p1|g9s1DXR&8w%A=2Q}SLNd37@(ubSg^d6L3r+orVDWgTtpbsq`ovM3Nj0P z5@3os@Ir4w*G^+@R~8k;z^3MN1}2JJ+;a{~s5SP;wl0@3;4$dIWqd}02Md3+Z0W(R3tr4C= zja(KFoESUf1R8wOn}puGJ!pxZsKmw6njg@h#j}X3F=GSQ0_6>9A11J{Rw>k-?C8+d z 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%0A#aU4z`jy~kzY~wl75OdVx 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� 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

gtUSuPwsVC` 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

R+SwS&08ng6|p1x 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

7q90zs368A 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

De6agAal&nB!fYH@??A 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.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�&Z_ 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

    x$t{j@Cxo-a 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�Id!U6`$wIIpA%&%%lTH7Eq^qE`5?5oD zLI;n_t5xA#-OPtQYQ&okTWVBsKHAWcpf1YNkf9-B(D2YfoVA~aiG{zTrHsYAzs1GC zB3Wjyw_^^Us1(ON!A0RNDJ*SjEY1cN5i!0Gth(C{1sFB&a$N9mr-bE;Hue_9nJ?Pg zngm3Y8!Nb9PZV~nZc_ARZDwrjbBGggmcFQwG?&!`=ri2FezW8YT(d7Yix^ zoX*QLEHH59Z-08=hyCyVCZ+{WJX2Q*I!@x2JD4=}zzrp#BP;cfCuB&RcKna zhkwM_9UrSCh3b9yf1vtPe67Kz)#1xRHMys(`G5YFgY>xv5&}~LzxA(%Y}D-~Y6FI^X#_W(SVRH3poL6xw^Bh2`NowLH--CZ-1&3YQD&uT&}(-BBY{bv83t3!g(J~Bpir);UU7s%gCkhA+FQQV1k@bxvjvCkO>0$ zF8s2G+ZYVO7qK5n=v|ahr0`XQVT)K(3Cn>AtgQTTvVsSzc(g_P+axxyIp(*-Vat#%wQTA%mqZR}<_%zog( zdd8x7?(@M6vcJ^j5BM=SAF#hOp<~a!N<*#<37o+WYQdog{}l5-U}5H4G}U;@+C_}o z!L3{j`p53sH$32Qcp#|uX6gYEJAL^>Z|5967B83ai`mxwd(X@rCbC>?iV5z8Z+ATS zVWIi|wq@*lslp3l3TNMQF|)`WxTz!}t0Qx^Lq}shhr;s$h3(=|dst5-@xAUh7w|~m zQz4l7c*h}y39O6KJXG8+DXeH^Yc@?N&|1Xlw2X!APKS@cK?_k{*5^*`9d4`)TSRTo zEaB>X&+cH6{^v&1ZSO^GhXh2M+*_0ycXveJ;9|*9uu?d%;Y6{+mzT%XYy?D-8c#e~ z&BwfA#tEb9OI$qM3@$DGF8VGi+=my4x5hh`2+1#OJhT4~r>l3boSEdz15qVPYc$tR z5s~(qGNJJpW5bhbHtxhs5ho`Bb*6%jkJ*P7y|2(@O07QO$W#@}B+&QJh1=6~89>q)>Cj`wA<8yn}uGq$)olw;9z>#V85#cU@@aZ1nKR3^Qo87W-#x17n z*7ZwP9htQ@R`3ePWR4?i!q{?oYTX`*|D;vJVoR=IbSYke-^R_)+xoeIY|9O5gy z7$4g{G+;j=&f+vd{3c`F11DBT-UB@ei|24Cv&wZfZE0#YWO~@Z)lt}yRiGQZdX8S8 zf*@zpboLTI3FfJ&L3^!A=TZv4Fhah9YhBGVfF-3UrAM|_N(ss{Y^pLJU)4v39 zsopq_;|^yZDzG2%oBEVtsk5MiCZo5F1iOWW=< z_x28oZ_ZR7R{X=pz!D?De7xnsp{R`-2J8+0?peq&|K9&&MGJEVD<}K$55@ucp<4Sl zws9WfEG!9R;#5EWC~$v6!haL5wc3_H85AT=)H5A$?3(&|KEwB`P9DM^K0amG#PrJH z-vrx5><3sia}0&p?{&_+NYjt=Ps986BaN(V|~$~)RdvmxS(O@!3iB)OpOsLY#SouzVB4H8qEGs;Fy<&$iYg(73_6AkA>0&I7mF$7-kYY00K6?&LOxj93Ik2_#e z%gKUW?FumgKLq;@nM>IzJl`^T9mB*sY|1_P&GPaqZ&b!2A~v{jF- zrugtfw|V8~>-m}4692F$oaAqoWwTiGX-DC~KSsao7t}mwRyeeWiMddUQ^-G_jrEn3 zM7{-Q<3tWd2Gs*!7#UdD@_FV=s1VR#bdcAum8eqXcd?u}Q9?fpIAA=1gQOv!OW0FU;q9L^ql#)5E*l8gi< zzy1an2@CZpC(fVhlVMe!k|NpuY5f%0Ddn%&X);=28*y3 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 z z?}Lt&QMo3|_rRXUBRt6VMRp0TdjI(G*}aQ%!A0TiZ`)Gb!diUvQ>OQOKcSNukCRC%r>OWyj)uHYpT0 z_V64qR=$ug{@lLKZaa6)(u@E#De=x|Ev4k#Wsex*+kRO3{@k&(pugtMQ>z=^33YZX z@+NVyJM%xRQ?%3h@N%J8*&MzG33m4f4eM&xZteE^>)8~*#*nq3?O1K^+zsnl0?u^k z3bpK4jZT+-^dZY^uG%UWPTu2JdGBODWN>tI(a9D$*SyO~vxob{5$6{lo33x$?G*aq ztC`OW$?l#L1z)(+%DW#NJX3JJ`L@!5N5Yy{S1x6ous(Ce@e1d6_dhQYe0KlX{qo*z z&*jh8yr0eT=KLS~{{4^@6v?@}kKL;`=9sCeuW=;q8^7=WUq|vEzukT8_kFqin%eze z4GNBk_ck|H9rC`-Q_&ILc$i6tudjw(isgL&o}c^$5tgs-u|I1NU1tiKCTPl^`yhh5 z<32l6&8v(P^NL?s-WS|f`*%Y@(7^*XS;sgQ9Jt|i{_n09wSs4KaV#sNPWdZ(q?T@*wD+a;t^N-*0Z;8&B+c?=C3RYqof)$t5m# z6B#4UIfz_J+4hzwbGZw#H(A4+$;%eJ(_g+e~FKXb; zKIr%8!GklQAHUB(_8DB*eE)FUjE`gf+>H$u6VlvQoRMi`)sZn^xt6m)rk8o`{)&wb z>W}K$8|+RsBvdY9=d!cA{iJsLmp$i=??)#*SlIlz{?{Y9<{cV8ZcqPkTT^Pg)rNqZ z?++BHMG9`K_Exs-5B~OJW|;8L@VdK!D)#+4_8+s-3T{h@n0@p5r}ypHEgk^}W0L}o z4Zq^p^qJ?o#9c5r&J=Ku{dBkJ%cUAe-O{hf7lJ>@KN^ z7rur&b`_{P)oa}Pda?8NS>4RtI;I(EA{~q~*ks@Ah_SwU#CI`=nyP|h@4Y&Ai4(7W zmC0t_&@+j*x7HC^+B09&uJT3ik-FL0EpmN|i$ssxu>Pz)xp`{Emm?Fk- zQdHJry>Zf_^$=t1mtO`QrvjDr{bknFY6{kc$K2fJvMNJ{TVRDnC-asEGV>*Uvn-Yi z*d*8s?dUu{xo^UUq|U=r*M_bt%z9XA`J;5hB;JO$1CF8gc5DgvnI`7uJjfSl&uKjL zI9Zog&cGB z6xscn=XRLQyAg39T=QpZf1}Rh-0R1F*GpG_vbp`EcZ*W`m*le!7VKPQFT$;BR5&9d zehW4|UO7cZDDFF-9h<{TF4yQqZ5z*TKT!CMPg11wgMI)1x2e54M$U?=>T~xoPvD%( zE^;AmW8=O5{kzM%^=7F5F*|4f@%#3B>^x0oe6|OVDhv20?EY~(|7C6Ss)rqGnUd=p(<%rxP8v!v->;0v7G-};CDvG zP^6&X%mnfJxNM%rB<{Hv4lEIt{J*Vo-tn9Nm+q^b|NFs%hzqf)y(LEM;rlKW@QZF$ zcpxKKQ~Uh0VMSWNv!0v!jwfOc9!medOLCp|x8`2vIX`kGEM~SbPVoM0H>K5jxdcDU z+Yi29GM+f`S^cxS{qx?zJxq>%b<&Sa3I&$G{~vxwbIoOW1{)J3u3Z)$`v! z+{edyx?b+@-wkyq81A|lh!~VC*r=AULHtvR@5kaRocn9S&+qaw)^IWsHgS59Ta^>~ z@!9|5_v*vgS^fGRgU;V@-}(Kc-QoD^Zy%Phm#CK*F&>c-W1O+D=VXHKmxPjq{Y+*a zl9TuG*`F#){~!M~z@q)}oBzlDgK~Q9_Rr5Ru71I0BBSwZhDElHj0c~^b&jXq-=6=o zx&J$(Y09e~f9jc6SiHF{#vJ&e`fKO$HCxjzuGk_FBzD^I*g0YO>BYbJj1s0Dot^pA z=jO3%-~HP-@11penw83wd7ioDVb9b<)4rZA<)eF-{YLnOMthULx7N4JV zC+5KgW+vHxZnLH53CfCJ+&FQ`s|m-==7ec`F5ncOwoCosIng%1Ws;Lm)kN-_Kc}*! z=W9}lK<|lJY|I-h%&$#n-EeT*zN=3o#Ff6bKMGp(BV1fv|Bbv4_w9YH5kD?e3C#Aq ztzK|P&4`cn;BBTO%4<*dy(|~5(5vG7e`s>TzF_;As9-8i?9(VrU-}kZ(e>X6`Uhw#b>;*ZYBAeU4FLK(w z^m(Nm%I@-}^+NZ?{r`{ME8f;1!@Z5UX?q~|OC@$tKYW&?j%bddM;{80B*;w**(OYidt_83f z@>KMJSA2Gd^e%noxzIenP2qWs+mEY%YM)yfG1jpDW-n8)yQy$SmgV|3K4GJ%o(X{q z_#bX4F{^H>zj9bEFuJDUVLUsleQr|VM4jh68%}a=@SVrp#R}eGwcXP3#5K-MM;bfS z9+b1KZ+H|i{l$rcCoGxfHdh26tk9EgdfLq3|7-iP|Gdru1>yf1YhyY5j>g+PoUlVi zqayU%(TCCOAOHVfv{g!vxv}V2?1BvoJAA(y$W(5SWoB*7k-z=_|I~%bIa&Xt57-uV zSoHp1+&#Zdqw&Dr92ssw^Rw64*^-r9oO1YB8_utulklkg!%ojT_m6-3ujkUnJaGjt zuWZhOxqsv(xy;l5$t7!;oPT!WBx9w6jf~4L_vdo&@2Tgo&#%{K7c}Erut92n(;so& zcb_&?zF;_b#F}{;>*pW68>XM*Js6$y{y3=fcF*qikKWDyAM9?Q`Tf|b=}&H^s)=?y zKKk^t}Rn3{9M}KAj3E`Ywhe7 z!FeToGG)$3_iohqsL}jH)=5;H+n-;!PulcCA;b3jZ(drioE`M&|D5W;mb2~q+_}zk zKV17%vbil$x4QbJtIP2jX?A@_cRS2F8CH4m23zHZudOQzp1C~O_vE_g^4XHwa@rw% zJj{k(6D2i23TtiLdA9w$ctgqRUko3L&t7%!?mfOBbm^kxwbN^xxQ%v3i@lD^XH9bY z$i3iU^s)1T?{chkYukLMd`?z;(VE1tA}wy>9M^847N^kE%K^N6(>o$|-8IpaNU3m& z_Byvs%85Do<73r*uJ`t6HVG*FsDJtXUY+C0k3W8gI&N1!%<*!s&;3*zyNUCs*Ge8t zt?XUbHF=vJJI~!|YTOG71fs$xF8jBOz5D5u%ZHxr?|B|$ocQAQ-CW-#h0w z&kjD8+sFRZbF;kP-*RlfeZSdz-i^zP*BhVt9bCodCRkIw_iLVX2jdanuKj_{7aZ73 ze$Di-`NEL2eHWhw>-8AzA3OK(DgXGL|1x)e`oHH554~sbas8T5Z~y<(^lu*?s60&9 zUGSiP{;&B8mJ;gQFBIsPyUI4@e75_?ZG7hUkNdwL?y1~;aKqGRpiyc2W8dp}AK&~_ zz4z<4e|(w?rCA%Srf~hcVIeO3YL8~)%r|_J7ml&o@qSp&G=JqE>mOPF{+VBzzKc() zChW82r%$#ADgr>Y)$RNTvn82(ZRgkXZVD)T_fI)TrC!|b{NLQBVs;)TGrmO+W}mrnr1gX<$853&P^SB8l0Qw%=yf1zL#g?jg2>(a-KZUZk>JW-XBY; z7MbGkl%0u}ZWmi_;=1a^XO}yH%a6ISEY{lP(0wsko^9Jd{d{jS=LYL4g?VOk^kj3Z z_&CnBFnzl4;mq0Nvy(b_pB-_`{P(MU`p)ZSPJ%0}u4>KAHM2bNTVO?H!kWOYnvXdd z+y0r)j+RQgcEWUFXy(QporeW~wCpcT^h(-$a!GDf|Af=&v%meC8-3rVpi0qyy^NW@ z=hvu?2gmJ5p8?+OQaMGKG5j@aWRGeKUyp{Qe-gOAq6M~-ZN z#TTeq>-fpf{C)Xs8)t9-?BFTJHtGxy9Jl%8HBS^2`|;8K;(;?-5?AK?x&5Z`(W^af4VOA?%SOodh@CbZ%*xUUf(JdwE9!K56yN}N- zy~XKU`$488EQayv$tTYrIxN`oFC>&>M$f+*A)be?zcKfJsLNn1PxSuzGx@&d(cFEl z@%)c($E8)yOE*8+Z+!Mo?)Dqz2}d;F&X#EIugTrDS3jXp*j6QeGiYoo^y9bt$@TTU z+y2?y{_#2Q?MZE?_a!dJoJ1+pB>L(_8*JS{J(Hb{J@#U z=0?k%&VuW2voC4jdCeXe_DXQVj^?jYCs_W6bH&-6|GTk4e};vzD$6lGw_WECJiae~ z`%iuT$7kPfv%D2NG{e~H;EVnLm5QbwNSecPfBTm8&QS(-2ajqmRR6{LWx3Owj)V;s z-w)@=9`vtgxpBnrQ257f_s_ma5ZZ9Knb}q4ri6u|NcDx2A1n-BdR{wtSc>!W!r2nd z9T6@!|L>73QhxMMUPYB%prGJr>D_~OO{(8tDA>{1wP7cx$JOSJe>W@=v<^J160hq% zXuYuh$lvCUxf7q=KYqJrO9;!qq!-D(hQvIc9s*KR(P>qT^9@XlDHJAG>c_o?$av;#VrK9aNYb z)%?SO?c;pa-M+Z9nLR$}X}AU4 zt^H=#CY&kvN zqRubL@v%7Nkl>kZ%;wSN@4u&I#rajL)3z^}Vk{zXroHE*bm9c&OQN@}dcJMh7{E__nG zV}g%Zf0MM&+U--4gn2jF{MfYT;E9QA9JD@H-1_)|xv@a4ruO`v%J(1N{6BWPeE)^n z@(CNnW%HiMu?vPDpLXb=TK?nnyOYWe9%{E(yN!FE`|Vm#UikO>!GpLB1?Mg-XKtI< z{Ph6)hYc1>gzfLkpZ!z2{ljgRckg*W|Ndj%|Nhj!rmrjf&OK@gU}yQCw?LA$Mn-af zbF200?qfFgCvN9`nDt<9?l~WygNGU7p5M5A`|;WR^B)vCTz%SjXnpUte>VbmvMF|M z3aV>KWpgiFSh;AT|Lwp7g&LO0yV?wdjjqT%ui$g$jQ!x-+_a2OQbD-BKkc8mq!fGj zn}6GzboeBMw>H*)KX_nQ#-Sd5TLy`RE&Fq1Di7{&jBi%nBU7Jn|G@eK3CrJ=%AZ~N z!}VaIxa1G zy5tnM)pEXFF;@Z;!?+U}q#hUfE;+Pq=COw#cDDRWD>-oO*F%|nXWfOyZ~u4QKJvZy zS0{L2`<&VBJ=Om|Zl4cY3b^f``RyOy-apRWd3<*H#O4JDxi?s~DV47m{`VcUBH-ul zLkW+}=e%cbEIOE^ACq~YVuwuYC*~&q-fd6YX9V0ob69Y-Qo=*)C+6qB-vF1Wi<$ck z${p)BST+1`|70+|xuN2K`me%0_m6Kc?*|?B^>gF*3vwO-L0S*Bf0)%inJ^vv6S1T&l0{*wJ;dSPjAS?`zNQ?3UdyV&z@-}~|V{bRrDl_i+J{r`9HP}#pQ z{^$SyC;NU%n7+p0`;oJ~@yCAGM?ZM{N2ykF?hmz-o*Xm3Ti#y(MuuBp^2^-4pfxrY z{U1B@@4n2Rf4BZ(<8cc3w_AA(a?#(|gX1lS$;D>wjhK56PTh}seTDL!? zdkRa_SEEH0KO_xn6Q_li=C4=xaM7By{cUSD=UI8Ps1*^>x*FGyOw*h4PvrzSHhQ=H zSrpw>oT&Wm=TDKPzW1gaboYtXka{h*c5~mlom!6BR!?U#&SY+hmoK}1L1Npg7gzH) zw6S{EpEG}8aO2yxl#=YG*4I%Nm0q{3dRH(v{#O=X%ktW$l*5_}pIwV-aJiLltfjEh z>xhWu)H4g_q;8xriA(RR8`GPNDNa|z_iPYjc*JOBdCHibWtsaT^O-H~>at!g(VlNC zZsdAcrt~0Y;Nn3<#aS`?qW15F(}ZF zun@OxI-vaHbN<`rHjOqGoved*SsS%)ST!98{oWh5C^O z)4;5SXIgXg)KqsA9Oj)WU>+zZzFIa*@=)^6--m)&N))$Tc~m7jF+^bYv|tzp`f1+tg9?fI9GuxpbY}|gvyff(he?Z3_WR_`OZv7MC)c)}zghOR zKOo7Um7OCr>xq}!l?1QU#G`Hw5!d%eT{ZZzciHp5JYB~R8*b;#3BO%`?0((3%R)6< ze#{E;?uxphet*~dM(-5|t$C}T3-06W`=su)=+~8t#eb%}UH#?2qu^J6m;`xNTwT-3 z5u{!7qIRokIOD;NRj*xIOxHLZ2rN|(WbSe-NozPEwl(n4sz19X>wXP6e67`+XPdHL ztn|x+8=M)Al({e^eP=v=WY(2mw{|^N=y>w<<`0+nncUKnf!8kuT@;jEG0l{ZeW8X# z)ta4A{XuJ@9A^nkN#hb!KJ`Z-(d&rw*Mvp<+urNgNM-v>uV2gD(egJcoo}0HgMozi zrnKJs`pC#^)CoWfYW|8Gl_8aaNcUsi5KF->>m@fuik zu8}x2VfwR#cZEVKO4FF+QZAx*oxIS0~^ftFXx8vV!8~^=<4wo;_ z$uI0WZU>M2kzqcxe>HQP(zf#tWcZYS&Cvf1>hC-T^|ivkCLH5FP_cIN?*&f}R)75S z|Jc2H_l5^Y)MoTw5!K~>;eL3@B0LZOD&HPL;|O?FGf@9f)P zF`>1&%is9@2J!97-^V@vyF<2O-OO_ywH7+(?#6>wOa6Uf7G6{rvtr(-ecNuHni+q~ zVcEe679ll?%koQoBw3aocvl$jJYDo>q}}{i72pu%cO0V&44^s?z+o z*{n|eVOkubn`;^rTdo&r-s~abST^;bFaOG{{6dxqGJ=5;LXX0QFHY2)$Jo_cIFsLS zzRsq}5tSUlLFJ&HKBD?j3qA z{mFfIZJ&I~OTN$D>qPEtoF&QKZ2lrbMtk|TYdJe)xS3yXT5;*nqCf0Xw!W**itO7` zn>g*1dT4b%drAPH50-3y;;I{0X<@D6NEc$D@`-Oq0G zwrA&bw73}#KS*f0zs}(PHJ4plqWz4sS=FWQp4h~&#;~tl$Jl7?!Rdkee(Yz=)_8?& zUGQLycD|H8_iQfb1^gk?Tz_U9-g-1}p`Db2f#;oX`e6|=6+SUs)^nyU6yKrYp*-!} z3yT>BVG}mZ$*yZ|OsI*Optvgh=#MYfS|4OgMT1Q`ZoRlyy>a`TC+Ro;{kviF{r{tR z+y1I1OV|8g zFmp-owtvDgGXLivpMO7$o#El?gjakb26Y*Xb-x6si$|m%D&w}F(c|TLc*jf)QKT!Gn zyTii{kL&D0dz;VK{|nMS@Muzp|CfY9*@XLd`4Z9+_eAa&Y18{%&-Z1??+BS3F&nA+ z##&9zAFkgI9&2;9(oXm?f$@tvcmGBnLHyq*iZg-^79Tvl z(B`m+!}GtJdu&vAJa1Sm_*{P|TljK)FuMp(r>p<|p1|ggHT^dKexCcsXLa!SKlPls zf6gy>T+1$O*WBBb%>Jf<_wR-hRSl8C#nqaUEc4}Z|CHSRU9+U&xv9vv7Z#rxi?=QO zp>zC3^tUUv(}ELTXw^0w6d4-ZfB*6Q6kpB!TGsDpemd44I#&CaXXBeqp!3XsC#HQX zuc+Ru^j_cRmyW5W^1R}^$+`Rc&HkCso}KC><*_zw!F~Pyo3FD}l;dpmV>SuNyH}d^ zcru!7O?jh}&-lNCYlr{M7)>j7?;|4HRkc2z@;h@_WdGl~RfT6)n{4_LV90i$&GP^0 zwJzbUOvPvV^TR~=896+EEofW)t@r;aJ_7?AuZ1&NQ&uOhm2?$l%58afc5-)|mq+P4 zDJ>Ia?Pt?MR9t$Vt=KeKV`fC%m5b}%_f=JI{C@w~x4I~$_$ga7mM`7B;mhiy((7J! z{NB5!_no51{u`g)zx~4A6WDoEnq7+JPW{Ahcb*-1u*yoPRMB1Ywq{Jiey#2U-p4Qg z*KRG7w>-Om$AUF$dY6cfm{3^3{o}7!bYBdJ+;^CHuHB6Y4kefHR~rSsYG^cH-7tmy zpkv1J#HhOtLLH*NFUoVa3HNXQ>R}NU&H291Y|+B2*<$QY?)+cv|9T2E9W4y{A82$= z*~v?YkEPmZF?(=Q z>3A^1Nhs>{{Gb+@w+fSwznLzR<8#>J&YUGDKgeXrdUCWd2`H?17`doRwBvO9KmV7h zqOGeYKQ0Kf{AIz zCQhP2sr2S79$uFHqW_LD$GPM;H`@Ez-Tr;x-J-}_&5a3K&u>@+-kc>+p!dN-Tt|Kz zgYCy{_b(hgzJV`Bz4E^G@$L5C51y9VWAgn#1jB>Q`3GL`DgU_r{?YawDctY(@L4t< z*q#2vQb51j_(8})3Gv%Y+L|RyYqlB0TnIXN)Ry&qHM@}PkK5-TZM*sJ*zNCYHx#UM zyrNaZE?ASl|Lb@cFw}T*-}3s%FPUl?Mk5MgIm0Ezo3FRIK;=lVtwtp&Ps4-v^z|Z49%{GJiY3 zcA$u1{v*5d|9j8_q&}2n+2T*^AboIrwV1^nG=Q`p(x>zyDbM9 z)N23a|NXp&8C2k@|M`CK-+ud3?oU4yN_lNem=#*-cgTxR$=~4H`RSG~o?C!Bc-dLg zSIbmPn;8DzR__w?%F7+PUl~R1m1mo7UzL5PMevPY=&$b59CntiaVBhwKV5vcMX55O zRCLGNNe7eEj;cl5fBLl1vs%xRSuH&YTpq)+y3TR3Sw&tofjW@r@&$*O z^Bun)kn;bf!u$<|!k|UQ_x^J?x2@g3y#Ap7L+yWNpEv4$-%xNw=1*04*o%7mrI8v5 zPV-xqvQ{4oSh7?sp!Q0>{u|*vKc9W;S~%tUvj`<_ThGUb8V+bY5W6kE>R)Q$YsZVl zuN&&rS2-Un^cP^Bw`=1=6?Rs|3{U2>#uo%k?Bz5Y1+^w0H`^=JF0?wg)=fix!>zKF zIja>|J2f3I91w8yxU+kPtl}OQ4aueQVlkPHiyux_y(P|Bxkqf97Q+GO{hLAxmdFUT zPT*nqD$aHAxY);nnjKcNRYdp>G3#tw+v>}nd%>++*+#n4vvh6CdhXL#{m;$I;(jUF zb!&c6iHe~x|BM8)xtccTTY5`2Te(TRl-2$G=GTpT_g^JEi1}9gMfO5mEzdvung5q= zzv0y*!@aGpWZR)T_0R8oO9xE__=xlGZ@;0o{lvZV4-MjMe#_^XKH7SKQ8@Qs|zM-)gX= zcR%l+p8Q7tEB|C)dRR4mx9`2}Ci};DkL@vyV~nbAzsR*Q7@1!tF=@w;C6h4q3*=KZR7cTcK*|SLX(*L>jDZje136@w(a=)YD{A}#Y z|H-qHwlaE8kzRH1SoB4<9X#Q`a$a}*;9(NkA(XfJk1Bi7zS);H+9dt>*1L3v#}13$ zEi2Y>WjZ~0#B_3&-OP7;*UigooT_vDfr0+!9U6Pr@_C7It+SoPtaQ*N#k$t|Pphmrcyxpz0U&Se*2P1^F3BSlQaSV?Dtg@J~;z#Thdxf>CFHXX&we&wi2b39m- z{O!%5jrE+ZYnIGrJhV_)`H)M(Ml0dz{YGCNBpllH>=>s@t3Zy61{-t3&2Jh;Q+9-Z z{X3P-<_yD|)S0E?T|b&LH5LTT3`xFZaqxpvp=Lb{57eE$9T?EbbJ)=O1%|AgIUx!?QlAMgB|Uu2BUw0>>y`w-p#Cw}%R?%$^l zCKzzWu{^ijVa43Vw2klOI_~oYa(v1)+d7O@VhoC7V)!Cd6YLx(87^jz$dK6)dON{J zW{2Mek$c^(IWk6~8%jC$x$)op|Bs#Nz5U{e26g%WquF&t;%xuTsowr6#iQ|14xd|( zaP^-5OnJ}ighg$h^wO!5pY2}fYmITq+yAlN=FK?1{=p-g8{)YF_u4X!n(!(8xcz(Lp8rQ`=htrI z6K`YD6}aBKE4%H5e{UOm-3Ke4CVj^vi%Hi%6)!`|{goX4;Jf}9ukb|?FVO$U;M z43=*=6X#rgtZ949!8`0he0;Xne?&Hv2tWQKq59)~{_`64mb1-`r6+FZecX2c%=yi4 zgkvY}2aQbeZvOvAIQ{0`&)b-fCCvK#&+gw--Oq3SA4;%1yFdHrWk1u#C0xdW{!dg( zo;+T>at36p+w8it-_A^%Rrq90>dAJ`?bKH`O)(6jS5?%T{T{ZOsB zr!4E9`kyso+Bg(>ad~t7K8ZlS>9c?8&2RiZKk?a}N89gb+8@7N@BK!87DE{SSq9z5XZLsfxBI783mRQnzxlcs~H5_wr`_#5eW`Eup&`4?SPwVG5C*Jr|*ribJv|841;_cKm zmnK=guxO2PyXAJf?&8q`j>@aCs$5Zy>>|@MRtlfnkUDE=ULN~u+pw(#1u5Ex;`B`4 zIIrIDo>6hj-u8-)DU+15HSFNm9=cita%rf0X)Z+Q0=-BOg@vz&>qw{H$M;B2&ijwz9#OU?bnx+7aWdbK6u2lUrINeQ=H4Dr8{ErC9XM@@zRxl z!tQTxuieUhQ^qu|{C9os67}{q9rkXaR~su1TJ5tEv%NjZ?A~lQn;G9v1sgL4E_C*t zdB4VFp>vJZqAsUf&O5?A}J${eVTU@ZLfc1CD&`pF%9R_D{dEB7rFwptN>^6T%Xv-*wCFOOF# zJ*~8^zGszqP0_W$AUB6cTXJoBOKNhr>*Q{KdxQOg;e_y49}LBNbC`cE7hLgR&wGXY zvht<->~8A=huGx^Y`W53A>$UW=$yNm|LQe{%`p~=frI8x@kAR z)qVW-1#$wDT<)JW*)wd-|35kZ7_>#=xm@l&>EpBK=622em-#Gm(%u35ilJmLQ{UQZ?6X36b)`Y~NA7GJz;EDc)g^0wwd-xNu< zfGaA2+R1HeojQ+|t=yjJF>jyM)OvQ-3hgKP<~Q!weMMa%qA#U;=hp#r=>Q!arWOg%b zx+-lZrhL#uXhGGhxNUa#nYJH){OAACl8^t}Kdj$(>~>AgrL^O`XC=Gd--@0bTkvop zr-l(1ORMOGGX*D2Gj8YKn#5swHP$r2|DxZ8rfWZLFP*kpyx7D1y8B!^rz7(F*KUyE z{M|S~ub%M)N1brl`3*DQ&p&qmzIV-M+Yk5I1>aYE2Hl9-p96~B-0fes_Z#2mH{T9w zk8itw>|VX#n`%(lZlCk`eKn|z{CUpy^N;WMPDIF5@BLU_(H0TJ-2Z)_u)W?s>F1xH zoRK{sqj7LX(7E5oKVLe2yI%C!`9JP6)`C_$RQ&%TV%)Ae<)jjt;dD})?ubUJgg?TStilTY=5oHCwWbH6Ok;n`8zBw--FXsRsp!vkVB zOQs)+Fep*2pTQc{qRfzZJ(TZjZ~k|?LpQeyM(j}GR;W~KQr(;2;rYI-ikY#jqKUa@ zjk57m=R0Xi$9`{{rOGK$!)CfRLL;?mS?vk&=W{j}MYPG^UQ_w})rD+rZx98+;ugGn9{PP@Wo!2kWsP?_$ zsq@aLT<_iX99$27-1q(X?908|{%Kdv105AtQ26cs@!3Vk@0Is%Uk)+x+5P0o{VnIs z{>2GevK;@o@9yLC_UjFfWF2Zha3H0saNGTJw;kdS9JO?8+B=KykJJN8?|t_V>`v*u zu$(QMxnur;-3dSb|J|g0^zGyO(z$=s_;3IJmsh&4w&{2Wt8~KypWk;GA1g-l^w}}@ zDl3)9a5MBjuHSw1?B@I4?{>@m`27A!qB^J~VSK*N?*5PORUg0Izi{wU*9?pA=YRP0 zez&;&{_)wJpb|0nw%prK<#tD{6*pGjSu!{ONdHf7(=H>&uyeJ&+y3qj|9E`6XHV7x zl>?LRI~)<-e*L(|dE=X(Z13+;^WeO_zw2{)o!#eeXPKF#O(*L8;4ZH#TES$Ww^|+SC$G_^4VG(op6s~JOwI_0V-ZPg#hB*hmAIve?g>PAL?!}L%ldJu1IP%S6t?>CE->~LX#`(l&)%*Lm{d23F_x`IB)*#iqMqiIX|=$ERv5fwebm`Q~UG# z$L({4&+Z=sU5p%5IVYPZA>=SaY@E&QX=b;7r`&GXm0){DCP?F_w(oSj!MoeMgS<^KK0wY!xo_Z_=k+;uO}M3a_jRA#W03-xqU|TU7|TyYPZO@bKk?u9(~TG8x){vs z_*_J+kKL}9`~N5R`NwZ}9wz_a4Ju7<-UD^u^9r}$KmNIB>L0r)#n;_ut$o!llDP6k z^?kYAv$EH}x@?)f!upvpMe%kUI70XX|_=sm5>LA1w7=u_k;QGf(D2jfqFzrfR(xZ&{*x z!029A)S)v?ZKpR^9GX|;c~@1X(cp!Ih>}g_dX?a_ez)d-TDP!h;Y`B`jzW(Xr0%Ug z*!NOVc}W=$mjW-V#DDhEm@lv9^nP3TW~QZ|gzfAf7Fn@ol|mW^zV1GhcCF0MzRGz&bPg1Me178g`-kuNgtvcue)sX)orgfDGH&}VoqNxG_MBYME$okTK`Gzt z_M3e3kK6ud=Jp)YWjrwVBV_yT`9JG;&USvY|2OaE_X~ypJ2yA{jsL&%((M-(H!Rc= z9{+caxp9&~ZCmqxru~ekVm>q1Gwo+KkIVn?{=rcz9+3y2vs&^S>znp_F`BIpUeY~z z8{dM*@0c&t|1(tko$#<>WpnQ$&IpSn53Pj9-`wukf||{L=RXO%ZU5!l`Olwwx4rkv z`ECEP`py62pV#+)`!RX8{rQc*wQX*G|G59oL-TDvLA{S{x1?*Izj+sxwSD<4CKs)j zHWyrGWSLGpc{to8cl(>Sf%@S#*X6cFomJT*6@Fahz5C5?_S*T&cYdoY*>?W(zsa|Q zJ)|ZSezRY)?fiyq^0&UOW|KDJdcIZVuiZiBC+l|m6`q~QaFNsFk7y+)>vDrSo`wDY zx8|44eyFe}O!dCc|3ayYhXommKOS;heslHrhgV+OGDY&V&PU_9=Vg zI2j7H?L$|wh-Pisys2YSX_3GV9(E0d#{aI#AJ5F{?B5zSqeF}1kb#L@-BHb{nvM6K zZ!B05v@&SP%wv0Ja;g;Ua=cvZ9i7AJQE@f(-^2774>hF{Llq`I>-w_(OJY-tpIZHw zFl~#6UAOJeZ~pG|{pPPalkNSRfByNZZ?Ls>U(oB;U6L=KEmm?WwXj&h(JlA6+-_M& z_=3lWo;q)v{e(?1A}zDyv*X%aM%|{HI`0$Q%BIRVr~4@=F9~2PXsA&cM0zKo8{CS_hnSGv z-mU?)lq>&KU;g1E-;O&%e6c zH^2E;r}7=dR^L}Y|NP5{|Hps+s`s6re&1=D*z<4GUd>F*wOc+p{pUBa58Lgd({FyO zUCDDk{o%78QHSm^{b-;ZOS6Ftj2}H22mDwei zKR+=y!#R{C!jR*&gROyJvxLwiKH;bRxkr+wT&~!-rfFdYn+e+kr586`I8*1&D@u*{ z{nALkeaV3j#k>FB+Pc~)Y3;1~-fh=&9e*dcMx|!|@Jo<>dC-Tw`|4V5MUDja#()0; zl7xenA6qXMm8M;E-TZXy5efe)o;ea>OWFLSd->ROGv+de=;n4<_#Kf^-^CNZ>>vNe z|8JQO{4YAinPKsc$5PB8lso$2AG3Gz54VT1dD)w!y)Y`gAMina!NH#$yoYr+n74d& zU+XA(D#JMW!?W&#P0{R)|5d7TCh|K?V`DD3{6wf{`@tz&WLoR`qxfP&M3V0*FL=ut z$B@y!VoLX+7zy43Q4UGRw;ycRYUp0GM{(7>=c&62FUlxh+>%@5B`V4hp*(#P*QJ{? zc0K=)bobJVWVS~w`8gN*;^*FfQF3M5CHDXs=9Lqfd9NICr{`rLR<{Z(fvi-_- z*H)A)I;+}pMxmmD@k~jH&9}Ns+v+D2ubB2mkTKVK>BgS{5jVwVA9{E}I>$!lrntj~ zs2mwCkp?&Bj$;b7TNXtqsD(^6fBfy{?3yE6R+;R55~Cx{+{hsHMTRTo!D0TzQvTC7 zPoMWa@paeU)$cyO{ZOFc-Prr!7|R|RE|Ug#HlI91aVwR2wY&BcbBQ z%*4R9F#Li0g@j3B{TT)wzal0`h^_s_`{}_GBR0+qIrcw7j}snAvNtx);csRXV{Ef$ zKieRGA;E#e_C?(aiKH8LIgC{kZy4xmH9bg(+IH|k{eF)e8D|jf!@vLk`vnIi1d<;9 zX6XM=bAu`0v8BPPv8daz$vaxES*qrdLsHof8~*RF8V|;^H~#x;U}3_>8G0e{0o#Ji zSw;($rbsF%HZ!t0?NaDJ&?@D0q~X||`|OSX-WpgYBur;M@V{z>%m(ie$p+^G6&@^C zn+#`PaANq;s}#le{ovt*RZSXyEEaoM_{bbwT_eZ-`x|d->Olq(9r2F0rdPj;NC@6A zkYf15-qPS2=M*-((J&zCsq-GT#Y>I8NcvCDOfeb|z9!Pj5T3at1Nuu;6MptD1O zFY4{Jgzu*hn654EaFKL8oIYiz^ij5iy{mUx^vS->4Jf}Y-_)wD&~QU?ZnE>T3nIb( zwv1D^@Z10Y-SVKu%}2m{-%Pu59XF+?jtOh*8Zy|#8xP*Uno(Mw9aK&C^7xY@x6^*ep|=CE-_ z*zkYXYJKoHCD#4U!3IB`C2S8m#LXKY)bCG_+29SLeZ2UTYsGdkeMnU>XK_rfkYoS- zrQ!Gge-A3;KO9W`b)Ta$TkU?cCgTpxJ$|>@8~?NHEQsLY_+Z2TW9h*i7HO%+BAx2_ z$|gTJ<@86?>DU*xD{Ti)F%~O42%0X4H(O()hV$o|~LEl{wS{owz8_Ja+f+jtZ>lQKJt`&WEgufx-?+pq2LlyG7`gpeYfBwv3 zFMPn@`H>HfEnhaAu3qSDzhK%`#R+>kv%tDh@8yDmt1H=+?OS&#ztqrSDBk&h!*-YBH@|)U zEAiWY!^xNl8+&;e|cl-Q_pfjQF z^BacOTTg4)-yF|8Ww%+w{>JzRMboRp!2=CW(|s=(-7xfPo^ru|)i-+;i>vPU?ax2| zeDd>~-}dJ(e_Z>~+U^&ht^f0xGym0oy>CCyGk@BFIt#|y+?zix-wiFiBU#zcp;RA-l-TePUmgb}x{6 zTEgs_!?DAkg<1F04bCkJyS|7RF-84n)nmGL=`$DGyxYtbIVuZWzdNeNvMrmpm6h9M zZsU|)PLFl3%Kl=C4U}C}&CXD5wwPUH?ka(s>RTk(4%A4nM(+~1)uhK0Tf%&+#e9+9 zmL-IRLbAld&7qRr_OAigH6#F0=DI7Cow1O;pkb&9l^WJzk})6YX{Q_Pqf1w%){e) zGQ1moZm#O&ck*|?)xMa8*~?Pw(81)|g)b)A<~ZnmzxsA{n&uYSmO}v!Y_fb`3hWua zCikbElK0wSAiS+$gV@3dIVSdrN_^e3!_FmUTi>~-7ZI{i>79VKS8P)6$GpgMg?U1Y zEVO2-X~?`kb)b>qP-)e&-xrh0PE8MEmlTd!>k$%J&9o~2ihih4Nw3qfsbU^oMF|I9 zIh-mGYnoiMu(r|Q=-F55+uHZqbY9(UYn`t=ZBdMf6i4P&@&2h>PW(T)I49dH{mG^` zkLG<-QeHgYBlN&RcPXb^4<7Jygzu4EvP!UN`)Sr}e#c2o46jc`3SCutZ~X6;L7Oul zvpBP1;|+yBDfXWiH5>4#G6wS3AI`kBMMGj`a69J$JNN&pj7uF)n=C#kowz`vjGysO zeUoJQkwnE+5vT6wC;j1_K8KT8J?nH=;DUQ>f*a(7|6Q68wqb`sh$!QM0trQj6a$H* ztDJ438`j1K-74ecIusNYc39Bar)J6LJTE=gD0X&Kh+7H|lR1SVHXzeg+W-`7b z>A2-BZ-}5{r=3a8CdbEVu8tg1M&}L~Y*=SAMKU;!Fb8Hg*_2c+;R##4Ih678yGh?5a{aJ9>;=my$hbV{8O@1eI<(Qcol>;Q}^0}Ct zc$h2r3_2=Sq+JV`UG&jd!tC>mqPv0_R~Jesaz>cRYeh(yeK7D?&=+$|#cDVZn!XX-oaF(o3At zpefary5Qi^hJy}n5iz0%G>m87pwF_QOJ1v+IHW z%$#S;CU~?d^SjI>%Ie;4$F@>DUD-@~;bQJwLjf@tV!sUO}Bci2pHk1*V4Tbny)Lc$+Ooz)$2O9dxP zV?0nJon&BPz*r&up>RRZ4|$;nSJ!U7#K*j#jh~y*ugP%A9|4Dd?MdPfPPKe+oXY$% zwXMxS)%&fZij=}ii|-F_B_3F^PE&2t&e_XuoIe-S?A-i-Zy)ojNoyA6SE%2y@LH;~ z;Ka-Y>&~@&TcOyR!fV}IBGsp0Bg3qGE8v2A99#a`tC#qrSgReS+5f2rGMtVI-6;9! zWD|E(cgC5XZQ>gjgkCbA(sn=7IMXMs_t1oSJk}g?vYqmGwN@?6c;0CXUMnl!ER`#{ zmi1_JL6wY=fzj!vOFA-p_bBi;KHUG_E#sH~d&7tO-&-R@4sUq;nEixS`&PDt>-au| ziZLlhRuowA34LzZw(3Gpi#_|P2K9>{E4mlmVl_WJas52K)s767`ffa03lFri1pZ}7 z|7G*u>lniekpP1R9`D71>wE6S2dFR~uD_=zY4=TBVNH*Zhhd7@UEyV1%N7*%O8-sH z&-FdQ<7KQAULaF`rRnsV1WS&k>ui&6Z#sWD;i0vRQC7>>gX!;Eb0V}GvvVB6uP7Uo zC`~+^urGCo|L?XFFW>0;yXiI;<;Vv-|HI?t$A6YV&u-mzL&J?Z#}>W55NBjofBI^Q z!y~CRujgL>d!g{2T*iadc_HpM46_TCq-{{sH1aBc{m*hIn?U`+85T-2lwWS&bn=Q@ zQ-qA*-}*CZxi*6D1v{TeI4(Q#jGdeNTpe?3!Pc*iZBHZ|f9OUSJbzKr`?a9%{r~6d znz&yk&z_5@}Fk8qsjjvUnBpAc4pQcMRgn|bGv2kI9R3HGvunL zF4PO=d{DpSM`O#`r4M-94xaaBuwz$RYZBgWEiTU7v{Gnh!q2lyAIb?I<4oGJCw@b# zjOcv5z_G zckLHUPUMOcIQfIIL_#Nb{_)d4%4a!ENjGVA?7tv#_DZY8zt>y1GoSd>m)>^%v*veV z!(~5i36Tb|WF$yPk}^WPE~<|C&v3|QBG z)I3Ka{?7fbhDV*>W9qQk;=EB5juP?LsswIByU_6w~eQ96nf``%k z`}oTEdrlRtY`Qs-sVRBK&wQp7`NPdN8_rK>U3VboQ|s)@_kR2Td~`$erN;H9IcJW| zHZhFQ^5>p!{I<{iz^Ox=Wj?-9fz0zW47{W_NVv0zD1JD7MM5=7Ysv9;8BR9CZ4X2* zuC$)FNR3zezz6%A4Y^GFB&$yGPyc^6AeVW6!-4n&;f2~UudO6GbQ@(Q_PA_5c#Kzi zufP%e-s7(hHp-luy>=7p?SBj6Gm@NlrLJ6Pw`}q`F1^F=nW~v1c6c3#IexoFjGj{mgfcYs-UU z_uJ1fGV^Yzkbio7g?j|Y7YWrFJRCVM!}=G!`04Ynq{&7u)Y#~Q<-||o%h}9b530!< zu*ls1U8*Bcd`fMd#)R*ioKrNI8%*jaIy9_wRBUx@5!t=UTgpxQVAC}j+bs-+oudA) zBwj9^LGtRn`C;N3ouCKmsmf*=zx@uvo z@1Lm*79Ba(%nKIAZ8U6au43*8xpwu%U9Bp9!T&q9t&FlwN&jVPxbg3m*rw8>k-WUp z=8m&j>~+^}bPJI;|G(X_Jwa+`G(+!)gy~l!1G`@d)p4aY&yfu1ILNw1{>PO~#~K>j zUdXZky1@J1YKGu!aNq9h11XtRY!YTXLMvCzbvT&Hf3;Co>fm7phr=~;?7u!Zu9%%5 zxQ~DK|J&@1|K5mfk>qwb&~w8s|G$O9;lz+>O!qLXd5Heq26cE%bogtC< zq2~U-0vrDC32m*>484v`F^h!HoaZWJouIr}pg-V3VMEU|PzO*!j-UH~x3lKL&gqVm z8*lJ){;y%ru*iF}&_G~`e~*G8yKcJ`$3wY=3m!8{p8ZfE|K7otDXz)FF8_Zq<80D;@n+2vjGEDfh;$WDLsk&Q4+<0;@3Oc2-~Z^t^b2k5zj(|S^e@y46bR3B z`SEnab4MBFD~W4Z(#;pNF+TXP|3~wdbL>nUvJD^R|7=UJ=@OJrb!)B6PH=Z@+v+BD zz^yn(hD*SXpZov3rX$%351cs^KJ5Q_tGT;n-xGx=Kb~$-UT`?pja@(@^d?sJmInI|sg1f()$@-CH8w9WeD>~w(}F`v8xmGJRA}(zN*gn_^-pB6 zKP_|p$qbV&&ba&kn1omr-c+__^okukap1U&!vPuYX&f^>qAvMJc^FGg+xx%8Vf{Bn zqZyhTgzJ_#h?v;L2^0x@_|LIEh?Pg=!X$E91Y#-TVv9 zP1_}f4f3p+3va%>Zf>BzgE_*SSETEPxrTlF|DUg~n+xvryldPTy72T2b32(`a=)Ja zFV2`djb)d(J=2UcHhYV+SbJD5NTn|f6OiO>JQAX_x47sHw?N?;i<}D~r%h(Db`)+a zcm8F%VBh8Q%QwG0^-yJ(x2DMoF2z^1rZH*u3@e+C+UBLr?8*JXYIOW`#sglTZFY~R zG}>$rxv}=}XNw;PldfGpe_i2Fu`xsXv3WacS3Wyksj*gvVQRslH17WLI}ZDpt}IYH zJaJk2$DbwVdM^~(1?Buc{zTJL!&F=n*^PAuPai97A!*>w-@%zfS z9L9R4{Ra;EF+OEXMf4}_uw!U-qFWumf$&Zab%WV(6 z>N-WNVAJUb$9FtDcX;l4#aCi?G@4dw8J;hF{qMh<%M#mn+zJxkr~Zo; zbT@EOJdh*7=F&n%HrQ#-^WQu4FZ@Kg0PiJJ2HJGdp^ z6gRi+4_>tXSTBc#`lL0LTTk8y{$hMJ=E37NbH3U7ecdPa&Z@6=24mgp|1yWpPq-g< zew+FATTgy`e!M(~<)7`mPeOD?wW>eP51P^0_&mo8El3`R9Jh@2BVe zO`nt`U+6fM8A`Av?PBLX`MiG7zGYwX{S0C*|Lcq1$l>|gY_V}%bEDnq1%Jf;@HX9> z5)f5%irahoK|k#WdChZ9%9F`$ZcJ|!{p;$;cqQbGX!_@)yX<)$SiEPAe79gW zA5-@{-HUJe=v_c74|4tWAje>hs2=5TaO<6O4% z=*H7(^OdKaWu7m_*t$pFp@_+bZQ+7~>+EOS8N-<4ommfkKOow=_JK>wEvC~B z936}S5?>i}H@Juzn0UNVP_|r@a3h?tKS6gJTWbU_*9OhjD3ua6#t@0$IlNp;WEdp` zWfhjOHk$E>CFt&K5HvJc<#=GzfsUtOC54Qs0%8%o4)d8Cl$cqkux=MzevDg1g4G~F zl4CCzdP#}~e;%avU`^ZCbpcOT#1seImkxlO(No9bGtS%+CKFn4U@X*_aA z^~b&YkI(0W&M3L}Y3~fCx6Ev7nOSvY)Xz8=T`=@^IOre8U|^7voaDv8z`($`ZTbUG zIbpG;B9+9Q1{NY}&-vO|SqwI8m=ov2a>!92Kyp5#LG05^ZV!j*WC{^i?HTL=1Ra9UClfh_^eu;yxJhU_wQV-uI@4tq)o>4;$1=n4K^Zsz3cepS>aK zfAuRihsO*@mV18@iAy{5cM8Y+aFYW&0u z3*q~aqStd^=^P^mk(~m^T{-*irDs_w!Odb`jy`d3*;RiA?EsdF#JRly>u|2TJ#E<(z4HM&vJ1^GmE1#8No$*j3x%zyAfRIe<7oq;HgAK_H9}g5U zeTd_{wX=BD$ zKxbFyKEswXUwk#xrm`73r?WDxm1$#sV0m1ZB`M)UL{IaBSzPU#4|*nS`Na7nB0)%R zp~>e{0vnRP&)0T6%6W>@Q_?lk$V4=xXv5nt1%5RW$`v<$l=w9o6)6UY%ZA8v|KE72 z%Eg9hwVte(hOVL&&;Hq59^#5=4IgTp@&v>c7af{%Fv5(lj_Z}!_q~?O-3~VP9N5dR zb>zK^RzL~6frpXI2Nm{1Gx7p2F&f-Cabbs=nH}feoR%C;HjU>yM88-F2cB+abv$Nd zC-KxVLZ2&bw#>1P;|E*#7quPgFt#g{ILcp;BOb`)xoQJH>%rHXL>n$7ZnTJCTd}8A zP{M+Frr|0b9;U!;hda)S&8o=Ls8l!+@?o2dhMBJV6_xxVrxHhoCnEFs9)xLl3ApT9 zAn9OZ!}#Fi{6EcXb^1TP#xUKR#~Q)^LA{yW> z*3QZ-{A9s0rw@JtE4^74Cml*>e#q-sVy3|IVM~arbBocz0;{=pjEh(n`0%$bO87CW z>BEAbo332yK4|b*Y=V$1Gmnb&OgDweJxvoHt~b+>d#AqOSx2J*zve*;7q-)-k4{KE z4|HgVlGw9IjD5}**OCPd3*^4UX)snTIG@nlr|7?jeUFgi(&~#k7sR;sFWAo8mXz_K zuwjQogFf3)WswK-3fS5FqfU*B6{l9ZD9S!$EsocpY`5_z|~h@SU)&lXkn)~gZa8s!-2`~y(bC0kk8AG*0~$jNlQHD+qyZew}UWN^qqNI_Toq9db&O#1AI7fT=P zs8X1~+vMO7^Pzz0gV*!6g64~P;C6nwcFwscTxv;rPC8ct4MS|nKziw*&Z$Gs$;ef>Xmj~*@j~+5(>~=kF6dD_5 z6I}FpV}sFx8GI{u>o@e2-+IbsE@Nl8^5GiRmlDd79a8E-zFgc>J(u?=&Ixd=zQpZt z$AVEd?z4ly{`YR&lSLJ_2{i1L>k(@bgjN$11pcWEP z;nSq@VL`bhlcV|-ZQ~7YTq;fN%yaG*e(2>2JZQz}tejYLzVXMOpx)&7aOxW?uLaH;Rjr}j)u%~V;f_3Wqeperk4u{#{&jHV z|E;8}C8ZU{cBXE6w#8vxUad|k&C2uh<C1%wDU+XHuhWPS6EKcu;NfqK9sm`67OL)4uuO%4RU-5oePx;_+^+B zAA~y^8Z~tuIFR+|i$KqzBT=~zS2QoY#&`8n=e-W0KxTC#);k{Jf*N`YGs3iaTM8aF z8OC)VRuFGzs;Jp05zg$i+%dxMdG|`@X2&yv0S5{W?0g)N!prUOj*VBk_=xh%tIr(l z6#i;{jJzP~zgj?ryE!3vix|7I5W|ZQ(RJJ`8lC+;scx*DOe!y(6dv#eo(R$4X^2*A z*uvQmVo-PEiV5dYhb)h_g8>m%>|9#PEE_Fmm}pFt+@W}-rP*O&Y2rlBK#369R~pmV zSQabtE1zdOx|*?;-|LPxn_w5`I(g1gJI?2clOJ>W&2X~g`mC_N;Kqg-cA|eQ?8Hnf zW286_Zs=obl;}|9X;NieV3A{G#q=XfoTHV;Bu$><1Sj8JkzT)^{8$;gf*TVqNQ7y# z9XNZS+^4yVbDjb7i-hEc32ZwTtO&YLP?aOz@S;?}F-4xY<&nVJSbr-XLFUf+uAHpK zi`?TrPS9rB&U43t>CK`&FASNzzRwUb;`BaH?3rkN!qK7jbs5uA9T7%n1s;~elJD84 zI-U`n%lf!Q(D~r=N(txU(-&>eRlF;7c+XsYQzt6gex>M46e6Uw-(I)!{M2eyao_mWc<-Rnk6g zkhYum!jj|sLWd7UT5}tAS1L*#6p%CS`^w9;s!74&`84Jm951YRx;XOf6v|F#Y`of{ zEFs5z!$6#q#rQ;5fr@HDfYm%BX8k=sRHU?B78|4qaflZ<8m!N8G}yk!fTx0wCHbMk zg03%)i<$&PjgKlss2o`NTxcq*!i5J1nphX?d@zBZMZKwsGtR!np+fd=Vp}uE|CRq4 zyPd7-w8FP-vi@NqvT)XfWO<(UA{}1W9~?d%pBfWo3nixcXYFcfJN8-JtfoHd)W3yY z%8m2CdoF1#-B4*#{Wdz|^`3`s*i_$F8z$?^cbu7iLv(t-^1Tvc`LhDqegCYR!{sWB zwEZVbxhT(1F|G*G2z|$Lpx}I!M#m=QCZYE%3J=W}NpLfAocZFYq{MYqc&=zcfS0j* zfClS3(PYO1;_Q1LYKZbyw52+&i|od$Y>V#g3;>Z~nT%57i=#`91wp?-%7)=(qfl zY-M6!W5Tgq^t`;|!-9u*o=a3*;Njr%m({XxGO#KUVs76l5a-~;%=g73punT>;Rl8X z!VFu}SLij)>u^YMdhY7VDo}gg#fZmw^Sud72h46*3s|}FaWq`K*U=%+;PsBf!F-1z zlcTwcc%KBr77>O=!TD7l4J&NlbFoH!XpuM<@VRw{3RA-lV;(kU$AAO{3-N^tZq+P~ zlQ<78ZR7cHMupLH-eijc%R5h|9h%{ypi^Pg?DaWcr?pka;!ERg-3`@_a&A>cw4%Yn;~AyDTqNdJ*f4s=iA5;Pux00C zKKf95il~T4&onmXo6|ZHtq-~HXc1$0@1n(;(fZ(?2v6dSGs?_A-^V6;zg)ynZ{*72 zwNIeo|JB-f?y2>a4doJV7B4+{Ra|@ir0@3g11lpodK#C6zOq*O9V6MpqayZvN#KKI zFRsIRmW%>6)2=iorOy%N`!MtK!UGQVZ0hWv+gcCmeb5VCyv;*2>cTrm_Z7}U+${m8 zH~a39zqU%$_@6SH*nivUTFwiOJ~*%-qk5iO33F%*Yw(|6?0>%dG5-|a!pW<={qQ;N zzi+>&e_Y-qAf%DP;ozLEbb^O-1B7 z4~voVybT{h9y27&Vr6^UbRa=Qh`Gy?=~4OvrNH1LiZkCE@Uu3|(X!&4GoeCJd&VgV zhN*E*NfiMGDuoMMnSu{9_I*<3e%<7#9?iwq);yWBk9kgr8DGU3B}UhW3LM{;=zHi0 z*s)J`h;8oTJi8>Y&8cgx|Kz0&Ck-5Z#8{bGIWJz!h|!2lDahbkbf8qMvqkEBRnWw{ zii_G9o?96xZeMVWf2BjglLsvdORGw*3z)MlTHc}Dr~5?Yo{Gq$rtK32f)5GkaP)CF zZ0O@~Sa6P&S@21l`Ggr_l?~j>n>fU#US&O!uqeP#i0i-!8P<g|UO>SY-o$Ohl@XPgwO zb^4FmY^T#|UyO@($M8LR@rT)E-?_4FddvqT_l8#Qz21DlVH%IX3j;@eh8uQl3=eg7 zU)g;sbX9mx>-TE2{K8XH|DRg+|8~?2Mcb(L{O-Pj%|DN@$@4du)WoeQ-zRjfVuIb2 zBR>4Et-YdE5^@`8ks!Cam$w;t$ebKl}gP(bWGJ5-dL? z9Z1aoC+Ym)5BGu;NoK~a2}{_SCdixr->WBoAkB_zL1IP<|MBF@tPP7leJDvfzcQn5 zhbjj{uE-w6HsyO9iU+F?a_;mtTJ%nYp-JXT9eE@mc#7?LMFwNX zhG3a#1~!ah>XIx@4mNMnH*y%TS~n{s9N!bbC6!VwAr&Gaw8^o0i7>MW=)%n>4h5SR zDs15PFl|b(Dc`GnDB;1x#|j6y*<}I`dMJs8Xvw8?341t*sPTG8wqD{(yvX_>OYRp_ z#*HL-u_b@l6~(!Ba6NR`kYvQ9sbDeVz=QQ-oQ;RC99B{Yu{^wBi?SAL=X*iNKtJty z6Eq4IFq>6=Tu|74!9&%HM__uPX7lwOntb6FF3zti1y(mXB$!mGDJU`ANM6|B9LVFW zlHiij;2^JJaE|qWyv&66>@Et|1l%va?6NX=m=fHTe&+RI!yQh%%lj^z`gAY3{jt)# z53}aKG|6Xhi^6xoW-%e%bYMCW4 zbLkHk`%g>b1hd~XoSe&^-uN@ZCMd|7{al0m2Su%P#wMk&3P zey#LazJ+P(D*g7)F8_bKIsTCkt=i?&wDQL?#^qYyPac`{QoFBAsQJgMc$bYYjO#8t zIc-#SY`E~JGPs$`rB!{S`zgLJbBx(PP4HfNKh$!5OTyxwIRR@E7Vxk7@ONKO^}Z$T z2mid{`H_(MSr=@ZLZ3dsWTf3dP0+YtMUVaH+6d zRfrPfaPWDrVr()&m#fL4*+z&Vy-Hz%g%eW|(}(XH%xgIvi)&@Zqe9Y?qt}&s^4m1s-zYRZ52(B&I%NHg9Rrx@gq& zVBwh%U(EzRGnP$CJcS*KN-aSTQ<@s$1R3^-b(}nUP;i6HJb6Ze&5qSQ0?eJR$p-ppIh$jrpeW$<&@mnFhfsd!84Bqa}|rHGad_IVrNQp_`teg!G@xTNl6S+F5LNi zthXv397yJAW6A0^yE7UEDK%CJ9NONL zAmn_obF1JHWkxd*rvw>6J~qpP3KGHvp~my2fybs#xDw&4nLeVQQ~6J`de&)t?m2|5=4#%zta4F zKgi+qkBU&%rUhFVR%X7aeEdUe;a4wzPO-oL0-m$^vtO;t|53+l&sgZ+d?IN#gW`Mk zqKprJ0-Ma5VlThvIruj4%h&ey#QDcv>=^p@$R9q^>UH{RXq)+i7Jh z^K@B;;evXrUs^&;90pH>g`}w@0-9pku98TU%|**}V!i44WoMEBAA_S|8-#VS2tyY8tny zppKEE!lGG=ngiB+Z*y{NWjS!DkmC&(WAS;XA2JtKL~%cF6=< zk||oe3|&lH&IlZJX_?pUXwWFWN0yCykN7$zgL1A`zOZ8_!g-n*Su!*|w3mqWi3;Z! zs0ny9KH)jVlP|+OC#s<6?Ebx6jtyG#T(mk`796?rU=2?~ob5r5(t;F=3X8c9PL#4f z_PEXB%;{j`5x_r5xJ>Ml!y?Bb6|qw+oO3*~XEi#jS5M?IbP(gLm?7#RWZizz)%Au3 z(^Ct6hEHCZmxP%YxL@mSbJ)v%;FP3A(wtrwjfEj?1_??G9~Q8lc`}iI!GnqmQq_C7 zx6eNy!!Pd7bc2u0?d;)$GwholY}51*j7+}6=vQGkeZ!0Yr`|=ZNxvWv_r3XNn5+Hm zK&O29l_wXz5$xBlktor5xzl;j4FS9SxX3+46P~Q78m5(8w zB{6WBNtDEq_my0-&rC$V?`>^nG0+dUk#l2Szw1KG1z!sxhJ=g~O<9k7LQT8x9J)~? zsoiYe>L~c$MM$aX!-EgI=IAV3%OSz=A^RAEu0__~1$JF?Ca}yt3ljpogftF|s4Z%_8zg3Rh|$5>wbiw2qQh3j2YWR6 zRz_x8Bz*|8I53C%d)uOkUrM+NPM*PlyRtF(ohYbAr_&0!0!i3 zkAee7>p{iiEdnP#ENJg)UZ5rSeXrufmrS2l$TM1qF+JIk;pD`}$+7j2VMbro(bj90 zcb!A;3Lae0QV{b|WC>@}b(=+#?{RqExp3l;@I4`hB{q4w(xS5WzPBu7IAL7TV)3vc z<3kdc?#1SdEbpcVEHGkjS7S~%@gZ)n7MD<;5C`YH4l$(&4Za4a^yUs1hB-5x8h1WC z(9wAE;H0+12Yw~e>{2YZ_^zn2GIJeVu!oD=B12-02hlhuAl)q^g|W(TDY zCEk7L;K-)j)F5#2zyx;V!wo{7tsKoF0v+!H4!5v{3PdwcSYU8m!c}39$cANy+$J9A z6!>`X%fk(m_RQP!Ly_;h-aOdquHrQeWb=1ef;VdQ1)4A>FGbm2mr zoQJ-K3opBw7KfLGB1`&`W&@ooCMpG4I!>z-9y1pmUa!Q=Z+l@zA1d1Dt zn;gEkGc=yBN@8!&cUTa{r&*D}bd5Ffkir?68HO(0k^*tUtOtBna)*m{IC1P>(0604 zK&UjsMF}mwi~v4~X0F3Y-O5XqRbIxGZb%8x5E9ssHYFiNA@ViTfe(fk5@N+zLrnQP z+!#*q@=D8l*hw)gP>Ry4oM2U=eQ|;t(}FlNqfZwP9%kI2C#Nox&Re0r$BWCk?|Ykr zp<{#&JD+cxfFl2al@AkmHM|?viqBxWeQ8xkgt+B~LKcNW85_oi4MHrt4AffIaIq+@ zaADio6i z8562o6Gf7kJC8G!ce(TN8t_!8FgoV1BZtHuV-H={ zhXULWo}Gx0V#;V*CeUnbe4EQ<)#RxnDIO)Uj1ET_)fpCez7GfxYZX%P5q0Q`-{kC& zeXK>wVbhBjNAlg26d4QNeVCx(^3z3k?;D5QEbbT!#u)J>M>)F$Q#o7siW@nOS2(dN zH?CO9E+WYE^&}4uM?*-{Qud|^aZefyLR#z_8d+EtEmS>tq z^Rt6Ns!Ge*rq2us=T`)%Ihc3^PGoO<;lenh`cy+eW5t)Ih5!S`h7}KHzVTd^z${hM zxyOj%gqBt{i^D+=HfGzS4GYTKas-=v?sczl(x{%qeQ=S0l!nS)fgO)H7EIB3 z&&gmX!M=#CS&6O0mDNe1goXQx_@0i&9s_2cFHHhP4j)1sE5tgP7=>Eprt@<$JYziY zqu_dn)92*E3KgZWW|a*(c1{&FqKmHYS!58(e6O2HOM_vd!2u5kzYk|Dc$DvPwc6Tz zR5(}6^h2P7`yNM|`z!_>-S>(-f_puVCG>g9Xkk}~XuvgJBy-7&s!xU!gI}@sv z7HtvZI@BIpJ7@pvWg2jHiqj z2`Eow^Kar%Ve1p5s;iH!AV~1ned45i_SsgZS$mn7^ zk}yY*M?=X*u&pS)*`Pz4_4TQSwC_!YJ^B256q%anP{QNQZ6fEeOaIN*Ik7f zE3{b`>~%41WRVM>WZong`Hdl(L34?iVMyG=d&@*^GPoYME_na!&+1>@&7!Oa8$R6Y z$UL;8*?$3Ro7rVc)$Q4}Yf8GWO#aub_(vflRDtal&r%1IQ;hd=1b(Qjmi_9~f1a7^ z{O#A8|D$YV&n`&Qo0Pdfc5eP*)|#~zUVH}nthvGKvp89}ogZ`*rm!FW|5PxOhlPzH zLWzyTQb%SA>l}pzZeJWVd=-+|Rx%sRP-L_?pQ9_tv{2!|<%KM4;atu zXXk6vA?*3F1ZQ19E%)`+}H3ph6*x#SZR`Gci>2kvfF{g3d<&= zg1D_NJdDl`5h_dv7ppj|5M30;%20VvLr#>xLXoMlpNn1aMAITxrOkH~8l9MCU*cSN z(Sy^(nb%8>W6H#79G&<2obFxF;&JiNsc1X{y2GWaG@jvJN zFkM%c*ZuI(UH-p5>N(D3XkPH|_<`f?rwkuOwbwNS9$xUzy8m>8{i~&VKi=%xu&F%% zs-|qMK!j>)8)M6YCROb)9&7nphkpi25fh67?{?n(D&=9%&w6})!576A)#Fom^jP`M z*Pr_RX2ayozKawJY}nE#&v#k0s9A|~ih#oe!zaq-Jsf&GYyp2xvkIswuCK}yXy$k> zkf6;Qn7nkC77d@MAC@@L@dIW5O=qpu5e3>FpB* z`GO+$rl>jU)qR}8UfdHKq%>T_cL*Pt+bqS|SK-3y^v;D_qhp2yI-qKn7r4Vunke(vDaJV zf_;18hiNLEUJWLD1Qh;;%1`I$N|lgdIP_3qS3_mNAJ5PQCvWW#inR!^h7hmO@R*vTnC&PbRW$7aNu4?>|J5eN}**eEB^aJ8B#N+E{3lPN!wi^0Y~+4`*S-uGOLvS&P;*!shlS?Ta7^yEwQ zoRTPfC~}M^jw8kRPC{cBpLT@?V~xxce-;H5$wva^ZMFiJmbS4vub$JHuz-!-Rv_fS zf|Uyc8b!E*CYmz3-Uw(gS6rlFDLISz4iB4wzGFjp#f(BX_q|&t_;DUwSlllyA;ZLY zk)_D(Lkv^p@wS{6MMhobITr#FBpRO2UG|_@rMF?Zh=k!I4h077OWe*ElLQ)kpC~Zh zv(V#i>aS8#aO5s>l>0};diy-^*i&WgUVYEE1s{ZTOjh1|6AnIvPt}l_s;wH z`_42<*f%qA3wDO_aIanSC1y3>&ZiG#`kei3I2jJC@ZxTWvs`cS;*Zu2 z7o$Hsq70tTn}1&MV9{_{!^~hBVc!1j1iNPcydR$g7*BU4?t6QF7W?NN29s3(225JB zr_PR5C#d+m(5kHovVR-S#@SyGN#3C}mwDHXzOAL$a*{=@*=J-p-$eT>vc@NiwNA~Vz|6h@UWx8 zLw9MR#)JpSp8XRVBN^5>C~`7fuZUr}`o1DSkbiaehK=1UX52Ss=&~~UeQrpYzDGrn zubJVELlEoXy)XGKW+*gv6gY`78}^m_ZayI-VZ3`apTf4zIWG4?xH=oF4x|c9QW0fs zaR`w)%6Oo|A-hF+M~0HEKrrh8E3Xn&R#q!x`Hsd1y>Bk>4e#BQ8p3mAd*X+Bo>%|Y z1^KI(*!T9hpSsE<{HVJ~%P1 zYD;**Y}DpBxzU5W`P@9-1MKblpYMLpEX{N9&nngWBaa-|`H#;JQ`Kfa(I8V(BYluJ z=78OjOG~ql|2KJ1#mEtQPA^l`O0tPVwE2!Bm-IyD<1QsZ#xvArtgmk3E}9tF%232M z^&J~yhe*QNrwnDE6y)+fDzrUx*;*X5910m7d+cIYdp%b;DPIUfi_k*mh-L- z4mvVQ-&rO&i0nP7;Sr!AEvaWQQSgEzW3Y{!Ly`ekgxCVjCoXdwCm#|JH*Vq(WT{T_ zuzADHyh5+g`3$FxBEt;B0}oggw}fa5iZUItjrpO(l*cF8-O$?jHOV}o!@)*%gWDAK zB@Yk0Ij+P%7Ksm})=tCyc&v^;wBK$`#O@sbzz9XiMRGtbZY z`|;zoITimT8fWy8=&fFG;GRHNKcVs%U-uuY% zuzJtR=GNAxElnE^Gba~Laz5Oc;Bcz)p#nQ=m1E?k5D)dGj0YRo8jf?eBowSa5W~i- z-S{BE)5&4t6EA_*V<+^uFYeg;P%*sufT4^L%Yp#ryDxV+794C442WZC)ZBD(wzhr^D@Qw32HFRd3zrMOuIPU3#i%HpBFgqMex z@f=^w1o0lu4g(ee@dZ1A51)T2@S&QeSt&uLl1D72GVn!;G5g0yt~@P^o_%~2f7Si` z8SBq32X63iZ7@0aX(NAtWP%N2qa$09DJSC%KFb2x=H>s%|*+`W5)a=tfQL*Q7`-cn4+^aVK6I}T;j=kZ(O`Sly*RvnL zHoe=H!_3H{n0ZyJhP}q*&tZjsM&bu`6vPi+c#)*Cq9x%VhX~h|{Ml{?6%2kcR93CL z#_>exdijA*2WQ-=5NV3zeBOP0rRV?lc^w+epG5o%%z8PZZxpdS^po8C$njkDNyRoZ z)?ZRh4K~w3r@KS3Bu|wK}vEjo4y1X2(&35QS@c)XHjCl zH-(==Aw;Aiheg7{&-;SV#|LM)o%V7ixJkB6JoHyWNJ83$$Mur1l}W|B!ZW4p3+tz} zMOFLS$oELC>f67=W7CqRuLhSN{JI#n1Y`*0=Mv zh3^n>FE`M;$RBFj!^aS@zCwlR)dbPwp1iyVO>dPre9-9d5a(;`>f%1~;uKqG!h(&$ zM>CejHfCNCZ*LM-^;)n*EAYzW_O7KO+AM7v!aW7Q?|mpU+TwNLX`$!wjswntq3_ub zXiCjnFm29+0EtGG>WjQwN(b555-h}a8iXXWlouE@X6P4pD5O2;y7!dj;DIC&*AN@# z!{_HIiLwaJ`Ju+eY;unMvsBlrq@-U7JWHF6oHbUK2`2c+)F{YlDDf+GRCxEVk+;%e ze7Iajo{M4ffV+>gMXt^?rOMs~IqA7_T%^58-6d4QpI1~?@J;}p#z=@sXLlc*AbA}YBUCrn7 z1_sO`jfw{&?zkBKt9-_6?8!6dM;hNVkDL6v59kECoL$7YuEKQdf)FOwCF?jUYGnO= zUc_$szTo}hfEP)&55&Zd>nkfv{oG$**T})cy|U=+JiP;Fn2t=me2;&*C$nK5Z zZ8j6t=G1$0R@tpw9DB*&*5>0&AHV$gAeF;e!Gj?|;Aq-P%kwU3Cl;R2(0pQG!D)L? zL4s}3k{+=o4o@x^FjiZ-Bxn>lNF|#%J#_KlzEPnhBYH8wiOG1Ugxr#b9SV(sa$QYQ z3M+(|6m*hLvM$)7XuhOL<**pTg?oGtuAUT-W!>{0B##_fBNyJ#3J; z|Co}cfeJ_4;RkKC_7}Av;4IEq=y+hk+~YS?m?c!$ls0G-#F$?Gbxx{qOVPm#qb{+xjju%j(acA5#DLS@I##1+D(_oJ@wZ3?57{-V-9J*nYI}j3C#g z@_7ZGET^8cDtCQvXVBxajTd~#P{)`VFOp%neDA{_?(^9Srd~L)KW=GQ>+|Ce#2XjS zV*EIlBcb`DhS#bEnvskf_+>*DRGqPD#i;iZF4m%lk9u_C@C4wPZOg@j_B_%R0eDg6fdBJ0U3v>UyDh3gfBAYi< z$hU+qzh<{!BBO)mBH^ZHC3%S$fwL77{XdMdJ^Yu{OnH4@!s5Zd={u7GYelEClzKDA z&rp|Sc&ISv;SlQi5Xad3pjCQb zhIsJV&kGKV2JG*$Iqz}$PYnC==*5l?QfzsSf6(S;)KKU@{co$A*7P5;^W|zJeoX$T zwYt?=@Z!gt8uje|;^Kd^hp=detV@t}nUnK}=~-igfgJOn3)zf&?1E0S>F~h39ObgcL0}fsMjEpO6*nb*$HXK;|KFho0Oz#8xK=k(^p}ZiL49_9fC~DWCU9j z8;dWpL@7kAlu+PesHncA7|hDa$9keE;fQ0fY8H3MiwUcg7MAfGYV7&4L6`MFO!yvS zt`^n3r6(g@^mDo7iezOGVCy7Zubm%@WLw)C`#M;Rf%8 zg^wSeN^N-XCQE|hfQX$~bd8c~;l>l;vdspC)(0B|c&ZfIlRcUaH!Ci9b|S9xl~uEf zi;PTy1mn5~9#)snUgRril8oU$_Ik_AXY+X3lJye`coI5F;lS zS+Aa4(Z^GFKKwHA;;+Tca>qKXr+q2)wb5Acf_w8~hK31`Erpp-@zUKn`z>` zJwNIhI@n#7I)%lxJ!;MRcSR(AwaO-bH+4gQIR0 z@9L6@dY*zDw$N1>Vz-wrQTQNW*c{NXM#7s#I<&84;n%>YQ!EslnOb&K{&$F8^}!^} z{$)u+_0>i3nTGZI7B6}DhkZd8KO-}Tlf3x9{*>r~wSpElJS?iO{;c48&%;olz`uNt z^>;>%eT<0`PQsjCQto76V3!^Pwz35+ePqucw%Zt_&(}PdM>?@4+jx?Ov3?6K4Vu{gPC2g@pdxi4ehXUM;3TsRm3-l!| zA1q*RYw2i?5#cdDxIjwuRbccP0fUbm90%V>J@K(pNOIyaJ|rdeytP4k>U#-?k_Bwa z_d0ZBg*#nRq{3OA8g_4XW}j=Lwk<%(;Qzm+A{IG*k?nFH|Acb0UgfgAm-eiqYR3H2 z4L2lZD<&kL+r!4i=CGj4Lf_7>C#8+?l+S?`1%(e)cI?ug&#cEHc;knSNP5GAxD|_- z6wa{;GVB$IXJz4u6FJU&eQrg$#j67tptWf6!SG7PoXwf?=SD*M2q|iCce*6u6l_xbVMjOz3r8?&)yw zXg;f|+?U1(UX}wo=?$M2D5#uph~N_u3v_38ah{;W81aH(NkB!oI>AMSF~CE7p#rzlIsr$)urKbs9@^}a+S2ccGE9-u zR%bI7nENi#AW-1A98VHc2cN<74GU*3_uqTq0C(%Xj;O$->Vpofisutp4Vsu1%5gQ= zhX(~Z7BKfbaqQ`QaY5!V$BZAcBDRkdn;Q*^j~`6V7X#yTr`rEe5g979TSBwr)-j6tJ4;=($0Zr6QfLGrsHiwTzw* z85--W6!tmZo8ZCWD8QDup2s1ezd((_hb8XA0n0nW4eSjk(mp%~PyMucI4_)deU2_Xd^SVRi$Y_!;;%;A>aqM#`F zDq#gX(-~$)Gq#zL2I3924>l}5SmBru`-Ue%vWcVbBhRaz@13q1CL((uv>3?PTsZLa zL#Kq|EH*yw<4brN1346Azc`$*RY(xZNmO8SWLIL>5abcA($dm9l@P`=nqE}V4ay$}|R@_tBxaN2uTkdmq2`Jb{J@0&<)VQCu+}Ia%NERj9Cu zzGeInpzz*;MfzTc(hNa{872>$7?Uj(Y#wwdTl&dxMp*EORIC(e$WpqC1&=`K<}VLK#NSn9IX#dJmnL%Z!mUUBep~= zhDV^>fR$OHjdi;1whr494y=0@yK!?UvEGwlNZ7jEfI~xzgYBDd<%LZ4rfUgjpC4q= zePa7w zfDO}T_dHcQ=uj{tg|q8&nvjklhsMgrPVQ<34Ou>qM;qcSg!tI|J@i>0EMQ%*cSDpC zTjI)qs4m7$I((cB(aYy`h&6@05!leuzNdwC_C?m@MQo`}4ZJ?wAKU~Q9(Es;aCTm= zvvIcBC(e70laB~?3GncoP)NyVapvJZ;#e8TJR!TW#mQlX5<`ZFjV8kd6}K-F1e=vO z{r1R;h#pAHZc<3%Y2t7w?l_R9Rms8AZa1q%K}+z&;i;{x3yTfZxNU6Is{$mZr385} z>pp0@(*Oz4>NJ#7zHtg_AX2?6s8&&yOcyfdbiFt!dm6BEK-R33%o%1{l z-X_xnCa`{A)R=NrCBezS@ujhLU(bZNmu$=(0Y;x(T3s|GsvL903>4*Rgqf7@I5BK4 zQpoxytHgbZiy@xppg^IYl18kksKS1i2WuNdjG4vQk{)PqF+AkF_hib(03m*h_b)#r zX-xTjkYm+@9!{p`dlVVYi0$#*y;;I5RS@LteOK|Jn5mf^433a?*^9xCd8zW!X|r=*b1A|P>RV#X2)G1gbQ z9tsf>>x`A;xP-p7+>lqv zcD5bRNnvHMe*_dSc!>LUvJ8u~2Z6B79q8Ye`)v2fBU2w-IsHDF;};}9dk zX!OuZB_Y7tMv*Z?aj%Gxa?APm+8L+htmfVnaf@>CeShwU#qTAu+Zyz2KL1|L+@v7S zCRvxaT6X14%ZN9UtMg1xyq;vkbkD;n;+JEFs~}^Fiw8r*dG?QT@tTVB`gvYDUf;XW zfT=+w)|k2BZcOOpwz;q37X1?5D`4Qp=9tE=(89c}s_%ddVp=S_J{@XZag$25n;La<+N4 zCr9_Z(Miq7|C<@|J?ELtP76-BQ2E#G3fJksW=SV1s{NP*15fO|q@mEF-1ITdgeOh* zji7-Pn`3~4`27vZvtzi~tNfPiezlUxF-3_frPfbFS5hECnRy!DjUrYC{qiLfS`4!1 z+-ZD}QhiS>c<1@R)-)IAMXoNQ5+V)@?@2Oov=lihE>SoT_^IuQbCV;BFn>|#A_un$R_RGD_hoKs z<*(9qz0tz>pupHwLZtEbE|aPUb}X+X78|@sGmyzBfcTajK;`GFYovXt}@E{9!V;_t1>J}C8BNa|e4enJ2QG$*K7M@pl&*3in zDv&8@NhJrvccsJ`RZ2G!ViX%%7S2B5Fr$2e!wJbM#Zw*G6P8FeOUT=OXKpZ+lbFQF zkWnkf&;E%`UarccVAkY4#x7?TL_F9T)8XKe@50%k-D056C(^smp!oc*4;hP(XKKy< zHCNI2_>(C?3wX{n8Qn5v-jKg$&fbnCUWO zO^MC2&hx7#ot~2Q#fgp8(dX{+er6{3B?c}{hglAYDPCU0k;bHbu;EyhhJrK8+=nw- zxFtjcjB^)>YI11EzI2?##@MlYMF-ot4$~<-6C@Qq9~|Jgx6DFcz==yrPN>S+t3xNn zvGSy#g;TE6;+mlj~!2) zV>$F!Z55O?+fC5y!6HK0|gRuembbmBZ`e({=vlPrtMku& zKR^EXeKGz@#Ij(95Au&LRB#AiU8Tns#CT7({*n2t4==A(?2Wj2(Z5;2g`M$=1^)vZ z7KWsc3U#Xv*sSLiZ843P7r!|tafQB~e6#7l4JJZO4D1(pIh>Csob3!}n9RSmshpd6 zf!?1c<{tjW1%KV)8ch%%@x|y2WK548&0TjD6BoG!gyiD+LNqVb2^l(B5Y$mT;ymJu|9axeLl|-(HZ9x za~prN1~wEgIouo4>%FM+9`}JWbM!gpnW{XTd}Bd}_sQAEcnY`fWDEFwR-{|Wa79{* zOvdM~o^yMCMbz9p6)N}f&n2}zUO(h_vuEv{9a8pqHRFa1r@I+JeRt~5H{Y}iO^#cY z!uWnd#nEGDH7Y;U*&Ob6+uqZ#SYehPvpk#iA%|M2xYgC_A&1V|7jO%8%5VQx{&|r) z>kZWhchByqSDF8{Cmn2DdsZ<{v9GLiFw+0M za6^@Tm)IrC(CL$VGdce7C$HZiA-uPFLc$K?pU<0T*c!MAzWi|J^YMbv313B+Xo~$2B(m4|w)JFy#NgKkdg2_6tqC_UumK*9_uaHfpmwKm1i^X1udu zX>;_2q=Y(7`L{lzO`WsijF}f4h-#^qdtji+<{VIO8kP8RUEO=fu#Z2CCRAjwgere` zQ)H14(RyH`!lcN-;h636sacTuhf*WcD*gQzfBXzT*yJDI)Ymsf>#?%~{||*m$K@+4 zF|NZtYGsF)cFpMmi#FH3)>4vOy2+O}F?%eMUCr-)BAKb>lP}2N| zdA~sn4+ra^@PkvPYyZ3L$M4v$rT1&2a%g{d%eu|~Wt+pBe^_1G^s+|a^hcu=mmerr zuCkZE(#5MCB5?X@m3T!BSc1jl3h_7Ok4XE&7dBVoj z<+^HXgn=0Q$p-lcwb2Zx1e>j291Cwb@F(Qk-?q*@){&1Q6q}hAC@?=cAS7_mnX%DF zpz%`z=Z}{Kpcmx|Cob5Bm{E`$SW~S`YOk2E5-MZP2q}t!xufP zFdpw}i3+3r&HP7Z@vt#|N?;fIr#k)b{+@l#FI?o?uc~;km3j)XvnBjuZF{ONIahec z1AXD%`B7eeS7um$>D(1W z@seb9&SzH%f`>{n9=&^e6x(1#+)B1R!nDlK9~Gd zHnZbu541km`|!}@y^kDKi#aAXa=Q03ygO-}($9Wjva>7S!^evsm+byIp z=)7{^u*|OnIZ-LQ_bC&s3zHrypWm@B`NNMl!e^QvzL$HWQ6@L_z>m+x+kY9cE;8&$ z<6FM1;`A(G<_G%)3NL(1R4|id)^by3T9U%2_QBBNLqX(m!3?{Wxj9-q%?f9vBF?^N zSKe?Y?L(H)?20trV_%=#HTzH?S9oB8;JyrjUMoK5#s9?TvLBR=JF0T1%9#D2QA@*~ zkBko@Z7!#rlXJWrrOGAq*&rm%;Zxh@qX#(w;12)HK@-236HJEPsX5vDhxg5=!huTa-(k(QMb98P*+>mBT zoUp>U+EGW$N@4902VEs0S?_j>qA&d&$-?;x%RUL^O)*?CBQ?c>lPU2`n5fMJm5QU6 z6wY{v@0s*a`Rp9Yd6gV0{$ew#rR_dV2v(_>Ru+BOeAS|pYm?`FDX7u8apdJe$F_y7 zC9-VJNA^DWQDkxYo>1e7?~9`JN*uE$GB(ZY&`*qz@@%a3vx#Bfah>Z`!BW>kEqUhY zs%lQ3)Sh^0Is98wHI;L&iHc4L@V5 zi&g8af9V(HeO)Zj;`R6cn^SD$_O-mXA;PKkilCk#q>h$JkOjDlejF6 z&npF5SaeK1FX`A}ZFx>>L;21JCzvPMyja0$DRa56bFM*w*s&rz!96ctSe`r1Ym>yK z%C=sO>DezQF4nMP3vRq*xFRFW@{!~BLgRbf2R_eIFFshJ$xyvXU@ptTyYJZrR&k!M zQ05bEo5y>)JI1uakXi6O+rege)_xnt29FOpoQE!WNVxa6IQ3@dOxXKi13TlFX?x^d zgRGmb|H;!Re89+P^?g2D+mqxXHx9=$zLEtd#_QRGSPvBhuzYBccifbhV4!pC(dBdejAsvjW)bkKSn;%C z#SK-*GIe#fgAWV@585-9n6O)9&v~H2zo0WFL6-mX@*@ljA6$?I3VSIz{J%=^o zPD*Kt-wZY%2yPZQ5XaXvBgOg3fi3KgM{AXuBy<`LKD=T3Tm1Zxgc={4#^okW{mMJ+ z^ZtKvet96r;I1+|k7q}xgO85Eh6zGPTiInkxMXrmD%^;9@GD}m>xHD!X9o)0Cp%M_WiCFQ{~t$&))J-&gY*j)JWl6Nuz%^3eZTUy z!gZER({&0VjB)p-DJ^@x@vvUf(BdUn0tK(4fc9WdhT|HG-QQZ?MiVWM0p6iOJzXj-X$2o5DOPo~Cr6i?-(t zSlL9(Iz3{F&n;|bnG$!8CoXG35}(C~HfPJD%=wzUymDMl#&N84SAu~R~0rPFg3LBT_ubKX31C{pEIl6=^l!*!8`4#$B#T!#d{ zv$8ySC~zqF#YVm^P6wNb0jaD`id+l1)G~PZAG-4Y4UldQNLAkSYZh~(A7lA}AN7A% z%O897t$E)!6{#CH8UAgt)9P)rn=X1cT43Jd2Z2|2dUSVxzWH@OYrSg4jG0WmGKD;% z>2ab*C6CSdaDa>1k4+(BYE!t*fgXtt&nbb90^%GFA8)uf3FfgVC~9{otwkaF|LBbS$sJi z5^TK7S%l_Mm$-G1HZ2Al~ zg|p)Gnl9ctpu^a7orhKM+~G4i_a3(LS?N4)O3;yXRhs0Km^s0~GgD)R39I`IR)=JH zQG*gW(OQLyO><9$iA~&-qt#@kXWYKSK*gj$%%j=3&uX^Ci^4}4h6gnYtsSF}9`JGG zj*(-!)MRvCo<;IZZn;pwx}fXwJgutgGn_s=NHY=Waqm#N%=Vd0N?6XIAo8*skMtSo z6LVy^1Cyo9yB$lLzCUZcHvrY3JyX_Yp)b<_}R8VGZ5)cuTJs8pB;qgpBMp5oT z3{!HDVZaJoy)O^8a>wXM&N$nBPvClWr;2~UKaMH2hc`3MzK~!P$M+-cgZ=F<-@k1A zFUS$D!2W5m-v{>Jk3Tf54J(XDiK$R%e9zD5q|*N{#%_jk*p+gYY@^??2j6Yj*DSH^ z;l)3%T3*d$*tFhjzb*d?kzaL&jIN7Q&YpPC7PG=@17A)5zq2Qk0z7j!AO0BA>$YX` zYQ<&k-%^651cMn%ni-DdT3i0hs4lrOr#z9ZJE(YgaR1CaW4!ik@IR-i|JjWehD8^J{_95P4`MkpODgtc|3)orO za>SWcTFjd@OqL&NZ*o}Y$A3g1igT|9$Az}$aOR@-%QKg6xUiy7PO|+lyNHkg!wK=O zqvgdNjhYWXZs+SfbRe#2Vw<$(fk#Pf?G4F?3!K#1B@Or_c1SaRw6I9wY?#2iC&s#U zR+GXC>os}~S}ckz1s+^B2MQL*cuKc;%NOYJ$xJyWdBKg*v7nUYfEy!Ip@G7pDaI9x zc-U9Ud~oIA%H%$j_?>@_podMnoEcy692s+)o;ikW!MpoyE=+tO7uuL0#MGtc5+=mF zx_!A+54)>IlmzpXjhi191pd=fl<9UpBsW*{VSIJ)A7gp;G9ET*HgyZ#D%F69v~#lN zd!DS^^Fzg8g@vHpkHTd0oiZxs^NoxO&OG=KrW{akgxw;ABTzuRDPa%4_CCQm1(VqO znwi`B1(~LZN@N`5aN5YIaWF$8Kt_1)N$x|252cTPaO^qkFMe<3#J=v(?)UG)S`w0H zB^ELMadFOCkW{HH*Cpz&k_v{C1 zg!Gu(Sl(MPx6b8ZsQi+cu*XiA#b3{0mIcc><{gI8Vl%m!+GA3FoH608+;F3Vu|#Nv z-<%fTlRFNGo|E7+u#mkV_kFgsFmvlN=Y`$@y*Ctcvi)0|G}L6nN)$SxI`}k|t*Wm$ zD-;~?tI6q2-@j<#2eH88{2BaWZ`p$k!lXEx6gAW(r4~G#pd`oUkg?dgapT+v$0y8D z<2f(fl+cm0MTpVi?4?b~hlC2&K3)4V^W%YFLB6jHyqwJjdJR=7fd}NBnVUWxT=8S| zsx;Q~R=QTa&CL-Hl4tP*H#@{8Cv-JM=*QT|g;vb#bBqvcb-dT~ZVtOc$9l#?pAIa2 z*zo$=F8$oIB_$-XP>BetH`lp?}JSe0aIc= zJ~_O5#{qr6CMEYK0|T8IoyWK;6$B@okv}3}C3f4rp3Q5G?B{D{<-e9YPFl_0{r?Wr zmt)fMrtN<~_UdD;siz+8EcMrGJiSvY+gS5KtHVF@V{BEw+mCR?GIR46ihsH{*|||*;WH114#_h@C!!AtamNU>Sw3)L zdN?m}gWN}nju+aM0sM`2^DUMJOps@8P5gz@>Gs z&o>@&Im6u5&zoTpB+10ex5u1~kH^XDVuI3~${iY2T9wyZ8f9KsbyYEP&vbHl{LIrQ zfU_dOL{*&6)bZHCL;q|hOg`G!Y0G~!C7oriK^#ZJ(+V5brmtW0SPpFM@Smq*?#JmU zI`c|_L|OnRw=nyWS-~qhyAvX1`Gq<3O4y3#sVVN9bVztH7wZET3wD9NHo-X#y1cA+ zV)9yKKQUH32<#TW>~vtwb44jG(oxOu!qL6f)8C}EE%Q{X8k8Tl?N#Rg#PxD+Q00|;`|y{m7%&>>S#`5939=O!C@y)l zpe=yY_Q3*!L=7E@gfj;$sIY{ z?66qy(LjkWz(>*dVb2+d?>x-xOxGm@4oXWGB$n*o{tw4vWPt1*tat2;7*`nEX&z4e&>XOdQEqHc_&Dj~L&3D?XRvzDmPWj7|4hA8hcvc#&g*RvX(M{RwG} zH}u52?tPjh`Ft`P*B(bv88`F24=+d==-$d-WWwpTuCYMwp}~qUp~iv*mPPJTEh69d z7>Hh6tjy}@s_PQ&$@1WVb<-AQZlM!=trqGFK3q&FG$`@@ETYNRXz-ZTK;Z*Qcj@ZrrD*YF-b{NaR24{Kn64-X*A9|I30yA7nl$Ic&A-ovq6F zh*SCa#ff|tc05`fmllcac_nmE!^Vi?VDwo|5wSxK{<2)f6TdecR*pkPagp|(;`z!353yy#9^W*Pluq?kd z(f$4VCtYgK*6GV0jjd-;k-PF|#}>_%b5vFx)Y1+=;4Ht5b!*qTUYnS;bC@@!tUWJg z_HT2vMAWu|xr)I{cpgvKU{fQp_tDB*ay-Sqc#7XiI&W-ed@g6-!DA4z``gcDZig;D z)ju<@^W{a&h-s?)D>NP|DAY(WAF#f<-({QdPyeN|mrq^xsQJgm;y-B@(7hT~3&G-JB}E1y-6!i0$rUKF-Gm?6|upta$|%mXu4FZ?ipIiR`8 zfag%dp291-FV;jmmA4!S5f3Pw-mGQd&h)&sWr5+*q}^@zlnn(UJ_=+WdSLKIC}|gG zt?&-vRt^631wU*a@f_6M@bdI*&Q5U!I~fiMH=%ZCzE6w=71o^dI30E*uXFJDkf0dp ze8`wZ^HE}KtR$+TRkb)TC{jEak^1D2#_|cGP1lqAY#|mxUh9zQKgdMUyjM+3ig9P@hIC#(^PL$)oG@uQAMh1nsGsma0CMoA}!nX&y*gd!8e zq_q>Df9UZNs<9XHZutAZ{@r4p?t@N?-+I?Cv-O^GbaC^KgdNia+#g(EKE34s?w%EF zVx0;XBn0+Y{gqW0X+BWj7st=Y#22-!LNsTQ8i$gHVfo+lV#1xu2X$&o1eR8G#79wjTV$<@8UFRpk71htTF{|3C5mXECr}g zLh^zGasqz@7Dotb37vl4Ham2>+m{c$pBewKmpaI()YLZA$Z!>1sL}s-uu0;N;;JtP z5>FUxkx=YZ3i-B&nQ>)3pXS9ck6V&HC;wn<2;pQr@IfG`li}1s)==5MF`ggJ$T6`^ zXyIr4Co#<~|10N&3J&Q*5(X10DzMqjbe2il31wV*)?p?^_dPBLvO(8QE`4;t^>7;Ii1Eg2S_pXN6~z*$z1- z7J~};9|u>hN|9hb*vO&4mhf+f4GZ^z3v$fA1zJ>oi*`3o(vI7#*w%#2FqG-gm5$=kaeUh$?+@x@Qv8fhz|kA{|v9J3QTe@T?qntLDM*gU1df zN*GrLNcb7>H?4@0V0hZJd6C50XJ>dDw%idF{xHE$gXz%>$Auf&8T%}(m}ULAFBLf~ z2!FWwK*XVg%f$|Sn3E#jq$r>-RCtD&CBb6B41H%triOVc%rY8{nGdyu9gaS0>l9PT zNODknyu#YKy_NBBv!H;)Bhi<#T`e-Ke6EgPocHy1G1Un^^f2@(?(2=own~YmM~LT4!ER}|Ruwb%Qd;tG=MYsyM6=gV5;WNe$=mT{m?)KzYqZ}vYy^SXs?Ztv3!9SKK{7!F$ zUOR{>KX_uVf`@2Z@-IQoU8`((PB(m5u#1^3QpHcN zJa8X1lt={6O>p4*5en6daqx4+%Lpd=QXq);M-PetN}{SF3m) zJxJjA`SFjG6nj7ghoIww1l2zFhK4_KY>YdUewmpvyb*6WriW(t9DJbQ9me}mW6uE_79NEU2BNFp`AuRz;E?Ua{%}H~jy(JSfPdTv zA1F+gXUMEt|G}8Op;1PFv5BLD=R*aDqW8h}qpw!ji7-6)AmH@VC%-d>pOJBA!Izy6 z?*D2yQ_sY})z)Awdg$jyfrrl>A1GL}g$RT=Uy6`irT1&P_Wyq705+#8mk6df3wA@N ze7guKJ3ciJO)eS7V;6 z37@EZMMu@{!;BXXHiR`NFBCXpBIV*RVTDFPj6|}-<0maAgYU3&dv*95$@U0Xecxjs zVEODIb4dta;gR+QFM1?oorN0WW?T3#ToB)|wrRr;r`q@2^Oo_Iiv--hn0@t}sD>l! znGY*^)XoLWC=pq%DUc8p!PIzR;TMUZUoNt&FD)$QurN0sc07L2!a!Mumz9gTb-inh z22YZJAA47_{~lpR;k^$NI`|}-dzlo}$|V}34;w6TvHIY`$90r-ZR67Fra&f5H$NN0 zE=Gd|7b;m9A82uO^vhRRFgy{EGn3+fys>$OX86UbBJ-Cgeic+(?BjYdgGoecz1*o6 zCGP)boc{H_?`TWYY7O=3c@sPu71$DA?OVgdexV}9pebP5gI4b2&-PV@gnw}UwN$1_ zPfWg|o{2;J#jkZ6*&9CY=dX8q|KQBSi&NMZL|fR2Fg%|pbYQ3d&PPqW4t&>DCpa<* zsIo5JQ_py~@d8t7h))bpg?L}}aRE>FPKV=58YX@G!o8MZSq10AX$&9E)Z1_>a_jt5 zm?Chb>7hz(Mah0X@wyc&o%G}7!=E?55Z^J`W<{NfcBbdYFS6QyL^PPE{m_>ezhHgH zfm=`Zfq>9VK`R+&)XPJt5#q)aUg=Gbc(|{Jv<=uz%Ngz+`vziQV!?(MSRrt9XABcJ{|5sbi=B$0N z>InNmfl_VO20OU`?kXcIJ}IV$i60+$zOZN!5-=P{>7^` z)b(ae2@u;O&Ge;+hr3RY`}o1*1-DGZSg`(T3eg+Fmzj8&<^9e(Y753hF|xWdJS!pC(vXH6|at&{xR0{^tZg7ZyfF#g7e)AGG;3ykr<6jN1|w zxF+~b2x+`HSFEW(M}VQdDI-Mx>Us7Ct>@=HFSZb8aW=GYQ3yQfkWf77Q=tgEB+K`S zI=Wm80SXp#K8P4hkns`gZir&oP|T{LlVy#9rm*~2`#b{`x91?n5uS9n5i)&z=&_E zF6RojLp)+E&9Vn8N{qVB%CI#l>i#w3XMSPv@sRO@+bRtDE=&$RD<V4a4(?tOjQ#9Rt@k*U7Q|SX$e40AA6O#L!#Rh?opq(h98CcghvIt) zDSTE!?YykNkE1WLTuXSbVQgsIrFg{xF?{Oyv)v}2OZpU zd^YMlS01$-dNJi73&(I+!6(I{pkv+UqSs~0`XYqKAnv2U!KE5AEEpS08!8o?_(Y1dp0)V- zXvj)DX8Oi;C{W?JVba4F%0m2&=T?<`Zgmc5+|Jt+P_XfdK*~oQ?KuHq6XsX4-U~=9 zxws*j@%e#@EfyKeS&lg*pI?|JC*cvn!pfz2{;)_aR0sf=^AI^@9>) zLc4E^>~qJXDu)kO?+bm$k3P8(MuC+prGJ^U{qO9bFYxj~ zjPkAo!K3L1-pJe$Wo~tQV3Cr;-StaUDWa!@H_=*n8n4@fStb&!mT@!W`N9txT=-?+ zZ^8M(a>34)2mAQiCHzu;bVT@c-tk+`q44C%dLD;{1cQbSVY!eDr3H@!6Q(3OY>{QF z(vrOV;E~=Yjwk*F0m{;9u>u@%Iua9)yluK5Fug*9sfv3;$L@=^0@2cq3l$Oq`W=r= zE578gn|aFJrV9sH9~_^-m|#+KfRDZLu!{2`Mverb3Zp)O{y&`kokw(}FU)B6<6Xq` z)Uc}}?i*)>q_aX#Lq^({7ZJwSW!M`hWVw7;AfQ;KC(Oab#>tj`T1Zt*h=<8BRjTbl zh8DYo=-k2sGc1-QFds5(%&16x>B8Y{qruT&qaq{9+`%NoEh8oRL$6W6VrFBmM%afd z(grfM3nKP(96EYvLc3tog)`n(JPRH!{5~Z@>-n5RP7f?vQl7VLSohq*aw$7+Mw52& z!9tA|Q*Ln{W+nsu#)gCJeQlfp8D0-R6wfJ`V)9^z%#*po5)zTud|YB0r>M&^HufFi zXZg^frKcv$8t|~SB!%Osgp6U4^1%sQH$wQtni|AbR6YEt=rU#b63U7S-oi z%y;N;Jgm*R;iZs$FXmjE!d|{sPHwm7${YtfPedPantEt)L1L$Z?w*f{%I8=bd@N*4 z4Y#}TS2p;pnX9lwp__-pHC#oUX+sMyZ^0}9hfI^7&sWZpJNKZ`gZsFn11~G%(_&@@ z#ij=vlo-xc9AI%Y=WlA8+4y1q@5;%KE}oKO4-tC!z4^kbgxBYL4`ld=H6%=ptU2G7 zR~S2c&i7dYip7%>j9e0)I7Us;nIY`3WWtx?^J2d^-x)|-S+ONHO*zVUT1J-D-N}l% zZG*bcZHS`cHqP?+(E6KBH&$D^*# z`q}+??r}5rXsHOZ2C+IhbZlth{v@z~wY9*4CrZ4fdBqCh=FaP;OO?}YYJAS@NcdF6 z?B1k#N0?`WsZoITJTo%FF%2X9D;vA)=$Q!pVt(A)E{f}@5-N{OL*b>oLyJPFpe{@tzV_8v;F3=7=KV>x$uGY!0JQk>QWjBXG8<1 z9^r7Pcqix~$0HydC&nWEN2JHmrQb6~O5)sNv1y`4g$;KfH?|1&O4*8Cko`HwEc3yc z_)pw%pA{}2dz2=}=Wc!Q;Ny8!-VbdrxTsejJv8N&xs5?#r1FyY+^x;Mg4~Qd(kd4e zPG6+j+Vrr)x{cpcaDtwcr^HmIpAT8s9@&WaIR-bnJoj$cTA{*x*sondre}gM<6-k= z1`S!)hY20OxG!W#&bDlL*m*$LM#;;Yt)Y-%M<}O3P0NF5$1-8Y$gTH8BtO*XP1wW6 zzFuC~C?JN9A**mfiC8=9!80yx8v34{d!J7^Sj8tbt4f6>;DSu!zn)`>0U{D7^qmuq zR#;5=7$B1{FNFI;4?laub0emQKav?H6dY@A3z3L;ki~jXCcx)`6SI3Ir}@mNg0v4G z*q9D4%24Dv%h)_e)kAd37LJRC!e=-w1)G@`a7rY)wm5X3Kjic%D(CZAhKln)?jLcU z5U{24ho5x&5(S=@U)tL&6x#oYmpCWU#|8-xepsYE?_%ncI`GiLLMDRyM3}Y;V?!U0^UtXdp8p9kscuvd zVo`p{cD%uXm+{Sqcv($eX0ChOjsBk$3N|fgITUc{#m0a&f~u5feL>XAKS(m+xqE$t>PuY{jqParn-I6cI6p zXr7C#2Y-4c?5XfElr+&`Q!r65EpRlpF=0~pX*PRtyT&W-CR>5atsjf-Gp=Gg`!n{$ zt^}h8JfEh$zjEP|n#$C~wa4P*4|*8LGe2k&$e6s~#)c^|%UCooq&BG3v9I`?9%9bN z|7!V{%5VV-*9WF0S?g-O8&?EG6!3Q@zy87Hn>00Z-ivLW2Md(g^CVdXHpo;=ZsTJS zD6?r|X_DhoSkPagG{r{7=S%xV3z25UgVsMhxS1F??$A|RVCq<=U11_4X5pvA7||oc zeWZyYQHoEiLW40`iRHrr78T*9A3M00Unu0Br!XN!@Tm%0>v@*uPL~4TFbJJhYwN@rp!<*M=(zhDUhRSei6ed{Ft`)yC*$c_5%g zsIqB_~p^CH(`!I!|6*2VQJaBT!bvPu=^gE z>8xbUnouWd`;cS7)|1Xm4gwcmWU#gVN-}Xea3If!Q9#4O@YY2M`$haM`!S zObLIQ{FdF?u7>$}f^t{gqk?+t7A?D&C>4H&0LMW7e?M=nJWz7rpX|EDudddI=FeME z$G9mV@MEiz>Yj9$^8SB3Pn{wrimuwnuruUXLu&JeKWD=VJ?4V?r6mPQj8(m-`I{6J z6jFK$9F;5t{Q7O4JlIowP(|uowUi*^!2=0gu89UKzPA`#&zsH4ykfxuAy(f-ZWc27 z4R7rNxNA9@KQzlM4xe9Oz%C+_qBp}Jj&n)ANGsclJbK&J z-_XA0;DrNwrpTBIFZJT>4oW@DywK(G7Vhc2%vLcEJhZquIgTl;(FoCHS-yz7r$Ad_ zC+o{cGU5kJAAWe|HRt6$mc~p0hu((MgX z=kX>uDCizae$U5z)ZfA*M}q5gbJ9VB6&}ow1bzxQSJ){o*u!{W4s#=iM(o1^L4!GB z4>cXQHgx2&Ot2Bp_T>BWu=yYNg9RbAHP#-?9Y+>$vMgTkg0PdO&oiT^L|;;g^? z;9pma${#O1J?008A2=|4)UVzDU8MR4fB*j-4nm?$5`C+tYqK%SpZzE?h4CQI9%eh+ z5Ee$yU^yYi6$;Z^4ArmHsIn+()Q2(~pO4}()$`6U@?o=x@2+SOZ+w_|!A|_YR+E6) zg_ae2yyf{tuU&KTSi0Bmb4JsFiH#=?323A@7xq}#JuFD$Q4(l<&{Pohk)>hB^vO5Q zF(uCtVrxpM(CTW`wUoTbw4U{bPRKih2ulu$7o7YaNn$Jtg%ejgSPQG@3-f($<5Lk4 zUzT$4ZiSl7hhyrZfsr%LY|s;18qVeDWzs{pV0~N-QpC8`YWQaF9a2|Zm-{3KAZeuI!w;dmDSp3)$ zV<0;tMCHH&74ZchQdnPHxuMtfV9!zpv*yk_9gQ8WZF;V2m{p5A&-bhmXu5D--+7ZG zYmz~YQOkl!+y^}P*%T7^5}FPg7>JzbZc$2jQ&7?J@qum!!&Y`4hXOmz1A-MZv=|Rp z$a5c3Fi3BDu;Tk=MuFm~(;htd5M9(DzbDH4(mIR+QRn07HT%&^|`z?em2<$Iwk&hvTh9h0zcY4O!d zn$mjt@0yJ)5%*rZIAvAD3rhX8e^$crMF5X9kP!*^LvJ_uvusy!#q zu;;;t%*X%iN@}!L+zaGbk@{dVvq8N~^Ls~@0K3Ic71oR1Ia4s*c8%16>M1`AFVwS3 zNYp>5;Qx5Fnei3l0crMC>qWKmmfbzvyn^laH0x8Rx0O6FTJ-RTT)30K-_?g+2Rh$c z_o4ce_N1(qlr@Zs0z9>xjvKff4c7SNY8+)S6jfq<7}Q`9eUODsv7D*#J^SGmYfihY zXFrfsSg^#2GjGj=7b?sT)SlfFoogc5yvsy}hw+67$DcVde8PK9m^|-kCnfJ zD2e6{ISsCb8wxJmxDgc~&Tyf?^5Qb7HBQouD%G!#EOvNjQkco%7sBV~@sXp8UA)gn zuPM>E(cnnSkw=~#ysVF&_qWPCxDcnPYV%==Vi-@1+SIPV=6e==&g@-BQydKn4mde8 zAFuFWV`bD(VLaX-6yn)Xa75-q2S?iu54J@;4Fa`L%|a9Mh-<8QBj2=ha(SHuzStWvieZK_prf0pYg`(5}A^;maGSH*6oSizqr%c zC%pOo<#+Q+<`p_oYHSuyU3j^S6e2u)9$eu!yfF1hvqaLy3k&8XH5I7sF;FaT|ImGk zX;ORp?JLI|P8>CqK3Egs#&vnsLBsG)$9eJx53_KtlNaZI)f0BfsPC(N z?))&wp=|frhVA!4+n7%*NGfN2wxcxqrS-u|!SgKNn>ws&e%Q~c*5ehO6K5l$e22|4 zWZrT9XBx~0D=TY)I29TMPOrDO{2HEoz+m^|f12y>YnHF=dU$_JihaWtv1ajxsttBC z<4W6l+Pjx4e{gL6V7F$^4wpG%%oR1f|LeaW{*cFid65a1#cy>^rUVW7mV}2LO3e;C z6AG;xmn_v3XKq`^%23TS=?Tk(kp7C85}Bf2IX#|tM;jAL4xD{3gPUzRyJX?xnD~nw z7E6A-;A&sI(96HF!D0m~|8c9MD+Q9$W|;A*vutlxXl&S1;pF&^wXyk^nkefdHil;h zk33G0_~56=r0^&1L7X*LW0mj@7lFmBoPy<&?5R5+T?ln&m$rM5BOz1yPLIc7FXLUe z4+m0}xwMoHB@fU!~rWs2E;+!eQ?b74AJ6T)~;`Y{?T9k{J(1AHS%fvB9{y+3-UkPw{i3 zV0)hCAGRS!J3@1dcD<1 z-KTH+A-Uz?pCV4y1D6k3)^Z-%_@$vnqV%i0%9b}xL7QHO{`gt#!sh;=qG9U+yM~+( z1{#elk~_QDA5ZW9FZrl_dP4@AHpBf;n8DN9lDDh^nve7*Z&}B9W{KGxwgU|S?9}LR3d@TIL zIgjUsMbWR$i3vX0Tb%t^lEb;?@GqY4;KF!FV1<66z>GCFIF3t41Q}}D3G>}&IT(;( zyE%j9V1d+nm7YxwQf$We3OMkRpIdfy|!Hg1%#S@M^;FacE!QGZ@uraZ?+4YH` zM1)TDK@Y*=^_&a`Is8xPWV_i{K5svG=&`~XT~+=j^>Y^|UNo?8JpAKLzTxJ>UlT+h znEJmwmGDJ`m*J@2Yu{gi?EbS0Da)%DU-2 z*Z<|KCcQm2|4=T^!5_xE&vISUEH_CwxS?7idin8x;Zd#^mol`^kv|^5I*Y~nf~D2T zw+s&g`Zt}McYU><{J$V?>6eQi{ByWa!NGs^hRo2OOGsmPkghM>1hZ_&e!XIop7Y$4GPFX#^`ZGeZ!oGR_sm2HPyX77h7;W`&yd%twE0cxFes&56Ofi)jzcnFY{$5`ULZ;*k~~>uw&|RVm@_nep4-voF=2^MFqca zY>I162r+!$;itW-xnthP4c4*mm0h#~O4+-ao^#HTV^m>%F~2b)fK@_S;&9VbezBd; zURf1Cn%?xl#6b9{vr|LFW#JhUR(@|1?0S&Hw4L#Rj_9%`hl2|%zOX8Gl)PkmSh4Vl z;r2ZbTT&Jlgty=G<6_}s`H&`YXdl;{kfvY4!cC4{oGwm$j}Cey%=jQMM}x;{fu-!B z#q1}vJ{g%Dn5W8o*h@;gLW|jXUVt>)1LO=C4=hSsD14|vjHT(IKpX3`#S=P&omn}3EDU7&y$(7AzUORI zY^N>GS0s&n5oSs%h() zFLrWu;e{J%pMSEf*!9%zu4<;D)%uH_-)A3Yx_oM7>0;K@zc0!RJ}sNt{P_QOo{L2~ zA~zV59x{BewRNzY9`Rf&ESA~$15?Xt->Ub`NfVL-s#~ zdsk2S@JEFCX+l)@x!?zX6xQ*SC~AL^EqO5E#+n0mO|k33R_s1Ff9}+j_T+zQ&)tV_}gDi?P2$m-BZtQz;-ZTV$$JdZjC%r%m?bH2{C*Ikrr{HLxSJy%7Td6&uj(0{9bP3KTyXkk2{Rgvr{qf*^0DDnE> z6e+3Cek?*v>CJ^5dHqrx@<}^OdFGyEO&hH zf^WG&5}z8UTll0rQv1u;52Z5Il5 zyfi#`FJ9eMp(XAj6Nt(&icTJBjL;|y#?#|ln)*j-zgZP#dp9$ywf4BL(|f+ zdB+TagGby?I+U4l9MG{~7JPEBqsOVRG02;#X@U3-nUn-32^*6gAGb(x`^Xwd6lpDc zCRgzwH%hX`;_jT7n=|MP)L}1Kk&wlFANja(tmt>;k1Fb)VQ&a>7mN2 zl3A(W4KJ-gb9)e4t<-#yG{bAK2; zBJPGw){F(}EGp#_HXl)3-c+FWWKp}4#zKV!dvchZHT2|kq-+G7?qwW2E6{zBbwe1_ zV>{M&7734|xHnW;o+y#2kedb3-?PI7db4D znG#jelz#B2%Ath|N&+4lsC6-KIAxiz;gOQShV#qMH#2C66a+D~+I-aDz9Y)_e3CHB zX9eYi#}0eh79`FSwGlYDXzzhG=Eb&09X4zX5o>h_Fn=qv=qpP@PsDJS&;I_O_M`H9?vC62d-Bq`zo%^7t-3P)Wm4zbw^|=P{~i5f zTHPck%f+rZv%*=n-=H<%XPkDR$DtPm@%;JzZ0XJ)1aCW*9!`&wY<|FVfVckq-UlyO z52mV~nt5pA%mM>N{`FNJjER3Z8oX9D6xOh1KR;j~QMSVU>qCiYmmL)**?Rm|WH7w& z&xJ$4Gv4*+ftnfnnnYO@Qet?xIJn&39g51SXFgUQ78Cyve>S1+PO$gY(13X!M|KIde_CMNtiZz- z!t2tI__JuztA!Cphu3EGM)l-RVRN;*$}s<%G)n`MgYS!(90un(oSLL3H5}QYuWjrth-VVHOR=YDK6OSA>P`o*!W(WCCkkr;!sZu>*a$79tKX7P+@u| z%BifO+jURiK#oxH5eL(Q9_xghR`zlBb2vnaR0J^nR0vUsd~)c4%_}KBaoGO=0#;XUa8#f%`oXswm(y)T# zu5brS!vr>7M+-@YPo0ffyv<s@#naBoZe0eO_!J!&ks3$J29QBjZyB3nfXmMHX+) z2=08O=~VD}y#$w_hQkM44bDd8gCdVO=fxyR1ng^iqsExr?sT|O;DaBpLtJ3R%m)i1 zB4ijo9!qXYQ<&f;p<-m^)x;QlLt4O>iJ|3vF*D05#luajTI~1EYMJ@)qO-sO+1SIc z`q~AgQ)e5hyOkaG=YPiC_&(j?m}1q;dfwG~q2&hdn}z28+L|TIckg@KCFbh2v+wOb zwfk7&_KO>o1m~!5v8=OhOfe9Sd%+u%_Fz+J;dfSs1xX)r7;@MYR(^?-KYB4Z@#XoZ z{9EE}dHe@_Bt7C7vkn=Yv1b*HbMfc!I$*Ff+F|N1-Jg#H{#nF${BRIDvU=^0mlZ#} z1x=+7$?D&$dEfs1-rUXnf86$%D9z@7=IY4m(WhFs!Y1~CeQ0KV(0qpT%r##7pJq(H zB6aY`OLxoT|KbflE}H6fu(SE+4XMyX9_IFcLI(`$Y<^vS+fqFk40hamACHyV?7X@Qdvg|?_A98rkQsw{qZDxTD3s=HH7C9!C`oKF4 z#~mLi929b75O6S%aMRZhtvRywfW#VR@6#*ZhVSDs;?Qbo{L1Wgu%G?2z`p+d@7PK{ z*s$<}PDB1s!Ttl(xby~DbofR&-gN4SrPUB=m|;XrUp zW+3AUZULX#0~1(3$V>1&?h$V;be{9MaWXg4f(Zp3Gh{g|l1gS2D70#*^tLK@zAN;I z_~^2u()tjm?Bm2aDx%zsMPH)2b{J@JEOQL#J+O3(!_#{_%p4yg1kP8fS}6+{F>%zW zDCJu@9b4Y2KKH-00=L$SL+Z^3PW<9C;e6iU{NjR4*gNJ+4qO^$>5hE`#&!aYnoH8> zFgn}_6Kw3fqsVixA+6$qpwBF$2-fC{cU0Ij7Ho-mP^F~G!^_;Z&YWGX>3VOBGEbxF zlJ^Qt(ifGPI5|EhJaq6XU#4KfCaTKL!^qKS&Z2PU%j(XCh`u840|(ae-Fa>!%CL8q z2$!=U6T{w$7M3zDo|*%kEDyUB8X6tsRrpsM)TOni-}(69060b zXf>1mt3KY$3BPQf#VsiMBYZ&S!xVR$Z)^^y6t+A{uwl)6aN;lT|BqiXub$k{`_Mw> zuyVhL!io^aB8F>@M-DFFl917_2zK;7Y|eU^%_c;${bRGnF6}RW0-G!?($@3;Io$Y% z;e(ezD5sOtYKGs95A4r3G{xA>Shd1IkBvp}2YbaHk*$k1CT&ePmB8S1jDvG09e6XljOH9kbFY1GX?#W~K&a#|QsEU;4#0 zv9b2kqJKu-7av~u7ZAPR@WU@ccJcrEMWfd^M%b_jCVa5J`bUwO|6qHA?8)~XkBs;5 zI@ky}b{{`*pn`ePqDN0_UfhV|XJmfi$llQSMnd7@i~kpDx0Guwwc?-7V8Pa+kQ3Z> zwVvTzj7$&r)%cR?B=hzUjS2}3{ESQjIxxP+NO|@^0^aHsVE~el6zRygU;F%d=)cqmV zisxconX1*A`lk`>SJONB+4`7!63%!qm@q83!0nLesG!O8L1BiVj2H*^49Suto|HYt z6|Tm654uP#kDK7kJt>G?&_w!-gPshQA4kK2_o-jTGEdj4*dlnqHVR@2cm72%`#fA@E{Fc&ZIlJa@ zxA0fYP!(t8xblPlA~(n3M^~IUZ}T47#q~HzDlpT-hkZ|uC|}rV#zF(JWQH3W2P_{P zDpW9TTCn)^p@f48A%YeQZZt@>DScXS;ll>;hKJ34XIT$%=%2F?=zGuppjDFLyL6Gl z43iut2G6;c3nMH~^s_1Wgj+~7OewT(Wza0@s1>je@n&5R%TS@VQzs#TX7z^mGZGF|dsMn#P`FaRI<$+i^GBFb+Dg{O`rZCE_A`EQ z8kR7NRmsbq619E!=hO+EHFGYCA7-^@==bL4uY5S8D#qyJ9Mysp+pzR6JUzMJ1QsbV zDF`s8RBT{<&a6;8$F9jy!H{*LTdO;N!HYDGgk!}AS%h{7IEEB7F_;KCw-$JEm0QRQ zO#Xi(!_0Zz;2r4Y?!1f9jTKi^aM& zuOC1C_#ZGgRBTB4sG!&^-o*aw)HIF*p$|UDAMSKG(EPx*DW>xn!w31TO$-_=8`7>; zZ1`Zq{`w)0ga?~E{{v&^Q!_5uu>aI*S(>DNY{Ah}|CtT`u{%DnKPu$JVDLji@sH%v z=&y758UJcb;^AUQ;A41@_&|Z#{0En{P{{!UN1+De1E&_qfA~{%`-D$D7Yda5K(jJ&_B*TR%WJlzNPNvmgm`>nh!Y?9Pkrw63FTi`;yZz@x_dUNT#o< z$`vY%IS(7or0}1r9P%7b}NnhYEinH1l# zDmFUb;qZ9J?l?uf<*~sEht=m)8LI`F48vm{glfcOK0lH-uHpV9zyISVg?bi& znza`yHg4dwS#tePPMYE4qJxWD7glCHK7L+h(b8t2GA{oOFwuCNrMrb1~3otorB?&DwY|6W<(dre&=A?bl9mdphkVcHclp^>yug8Wku!PULHB) zqpPM=eC!gNY(s+TBpZ2F{#WJ!VJ(glYBMF)>OAlgk!i_WFzJyqH>1KdPF0S352iRg zh}$9M=xMR{!Lo$pIUoKc9EfA?;b!aOZ&FH#y%58t;l<0`yh3^AixmZI7s|gL?x;NS z;^2GMHlYjNiZk~<^hv9}GciWDsc~}K)Mphhk56cve35@?lT*VnhtxY(d=8hsS9^Tt zvC&~VSn{FgM}fD-vY>_|<`N$n?b+-lgAcuWvCAlI;Ue`0k6qn77mjUm`h0ML!Wo&C zDrLq4WiruO^Iv~+yA!*3$DGRtJ*3$3s!lyTC}8qaVWFl3!vc=nhYtiCdQyZq8<-9V zJhpvs?xcp!oW~D17@VgBe@v`!;bLH7;9^{{L}2!b2G2Hz1*~V(SsDTw-pQD&JrGMg zFo7q7FK330gn=GQ?x2mlmN#aj+qk~a_sk%#- zF>6WFmItbPHi(^+lbhNwi}Qfx!Gt~|9!|$@w#VUAWm5mk(G-2`rw&(UwqjB%#CU;)W%%91qobV=^ZRm9!>yAM|muJs0;Tu85 zhp%OY*aVOAoY4BPfc1=Rj)Xe@iR1kGy)$iU^p>=VY%;X@P{7RX5+-H4P@^Rv!Jto^ z;lqr&l@A}E=WE_;^VRj#@r}wK0}8%qE`GRT8N=Ld^D7VV&s1*WJol5k%IBa*lVkQI zZl{F~+=ovdAdKMMa6RmwZOlunNs#tV4O`4SOsNhT%AAh(wlj8Fx z0UenSC)%3Z_;{L6#yNRDNtUpDpUHGWN#eVOq_AX#B4>prM{&PgPijG2bDJ`|3ikv> zhGUP!9-NS!r@?lxiLt`s^u$OR?zr!hm>na;RYEv)AM*5kXL>2ZV&jxD_3)w1lX_Ye zS_S0`-5Cw_QIKWh@Z5a+xKo`Z)a9=M3K zF~uxckPx54xpYE{5Qn_-oPg&S89pS1Hgd2ru2&KH)ymX3u|bCO@H_4U9!BeD7}Y#x z@NE#2oAkP$|KEzzE6(l{8ZJcNW;%4@P*c)1iyd2jAKp33Ij?1(sLj8t3no1{f8g-U zW`#2+3^BtnBZRF!a5;rf>D|>t5ahK zx0Mh>QgOo?)>RTyy5|W@-qX70DeFD$3MIyX_bkmKFA_>VsPLR)QE-)0VtOW_B+1XX zDsjC#qlt|=w>EQY+db#ydmP!gvJbM9^W2b@P?BWrF^~{s_@2gYBhVO-eaRs}mYMN$ zA9L#y1)X~WuDk^oH1u2;mo95-Rh8y;I3wB0JaGzJQ=^kRv%o612aZw?PFYkeV7Cx- zNn&Rbvc4>%Bq1cv!y@qDh=8js$I_RqNi6~fmJeDaWxALav{{(G({$eXl80M0MBDt-zuqLvqIuvnhZyif_QVQh_P*`Kd2OQC9x$%Om1zfzJ)Whj78)**@`Asj^&jsxetCYFZS=>vv%8UJNy63 z%rAD{7k@ilsFzXUNJ^g-BO}v;&^vW4eJV`{)#V(ySnqi%RL!}t<Dsv^t>3miVabUe@a!1lp}GHuxIfOGCdjJ9eQ1G7v`d!Q{wMEwxaTaz4D15N+=nSLMeZ{sbhHeZ6!*F_r*JP4VP)t@SgF~qP%YEJ zC%@qFK@K6V9bW7*8cpdFwom8~s|uVU=CslIBAcT2L7spM+y%}S@2WNwKGC#!q~@hn zp)Aqzj`h;nUCSjcuC#rKvx#A8(-!Vg`8BF+8f;Y?7cKhsyqvL}K}_6khWsg!l06B0g30x+jNOSDyZ_~OzI@B{ zeRJQRz$N`kEJ+&r4!YVN6&Gf(7~4L$C-Q35%8d_a&7W)ct)<)G2N%x);pT(4CLDYe zzpTwcjKjf0;u)J`f)it8T*p?!h6aX5LM;A@e4hoxh3~U5_}D&dkg>Eqa*0L3!SKa` z;-)u=2}=|bZWt7Dh)W+@ptQv0Rl)^rE@h{NgasR$8eLT8O_1edWon(!+~1-g&SvR! zsOiEt)>$p?#fz%+l?0hvSv9nTb|^I55#J-?cre|@jg@IZk_6K{8(js1JLzr@4Vzwb zUnqRuJ+DK@ppU(UCq?1;-Z!ESmkKtV`F)V3>qCsIl`gwrcax^+b3T<6*Fz_Ep70T? zNa9E+Y+tnCP=}a;lw^~GL1BYJyLBUrT)BWl?}Gyh%MTW41jZln*itqtEmKKH%tf@% zj#;AT!(sLmrlvN&LM@ItUz|3$7+2^RSXe~Z&oD{S>xh=T&8geVtkRk|_d#0aY@t7ji(3ZIRkYK)x09WiiKc+jiEQf6-7HoaTK0&*V z>E-)^86jaEj^`O49y!L&t@(Twvt!K%M`a7CGl3oIdk-}688@;BxGN|v>_L#D^*lWR1A|*mCZbAWO3o~N4d2yYYB3xUVK}_Q ziG7BFds9Qh1{EtWZvJEybq*cAz6t||Pi~TY$4g=q8GZ?b3pm_;sK9lqLOS3?{h{kN zawp#?S~c;?d~V^1HT7@iIC#FmK$5YlQ{v>_Bf1AU7Ta9i`<_MY^R(}K3>ulfFXB$I zJ{50~5rN2c42EbOkuZAwOFip}mU zN9-!oFn9rp?BG1Iu&-rVw_ zC55L+kVCRbn&+^BBUASwA-OMaxC2>Ii*LxbHTa1&w`okhp_9reuvbf3(dD6pL1XZQ z9r7*m3m(rEnLK%ic$Wgdf{zTFo}_ph&%r8A1qX-1>5Djg9JLRhWNv2gZ4O`Rd~nag z^(IXB3al9;T>Q8X$kYn+@UXczCAL{Q>J$k$1SzC(o>!Rrx}Zd$BYBB}5nEh$+l=iy z&T@!%s5s6rWNx$j5W+UCtH4z`p}<%}kD1}b|3CSzPkEp91cWi4^*GEh@j(-J6X(Ie zfW~>ctU~A8(!aCXEZORGV4C26hdwnPBMFAhzx%JAuV#3qA9&mL=hK9`qz|0i3KmYD z$)9-IZ&trg*FBEo#m_G)3R$rytdiU#%xv7?xo1uf<64Kl=d+lbSMjV`^dL~4qrvxg z^M&3;mcJO4Hw4*yaAs8G+tYISu!7+1g_ed|F6;TYFMknFY~a3N%%R|Qp6l@>0j69# z$;r%uix1AUG(4^(P|RR0-s0r)l5Le^Fw+OM1A9y|A1bW!(qwwd>df@!N>C?P78)UdnqCj8%dLp0=&aXT4^a@x580(jg{8Rl;Zvn}wR(wbrSO7agMG>?G&v z^{_guRTE=t%m7|i*bJDvUTv(^u`_Gbj<9#u;I@prXTLGpf9_7hhd554`VeoG{_ z<-t7#tq)V;Rw%BLo6gHPm6?;_9*5Qfmdpb7gDL`zoBrAu#Mo`y8MSB112x9B5${KSH1vq&)>{?Ex2@6zA6w6t`-d~*8*C8mI&#xr7a zmPR_7Ci09GmHrnZ`z8rB%g8tQi}93kaVE{!Q+aWZ;66o3@hs;gYk^7gD}OxLdcAMz zwFSOWsue%j?{Nn%P;Dys5n*@Hui(msoyqR!XI{FvT-J~GX=|e91+m;G;hg;Qo9|!$ z(Dfkf!zY!?E*pA}p3&LMSY>F+-m=j9l=Gg4E53Z-s+_VR^SX_)fu99OTTe5mP*+R> z-+{;jCNhQ+EY8LUCveSq!N=;-^rKRso0-FDkC6zEQ-(!@Vo&)VQ67W62Nq~I6)5o? z57r87Tp-}SS4T!f;PMjN_v}wOW&A!r;yP7ub{mIN+`}s`5*dHkh%a5BAhaUNM194c zjDnXI3$|K(coWtzMacH4qOuT}fv^Vh8kogKpQc-?=? zmMm$8`F(8%171v9S^4(^clq^A$NDZ`ODq0Ya9yrO(5HtznY}4va_$;~hYI$+mp(Xs zKd`g>kLkI(TK5yoT`HV+Sm1Vi+GR zW#c)x;>RB5Jv?__>^m;ae&M@SklfL>I2-+jmkc$_-d_^su4Zfz*A5KsRa+v}{DUR> z?e~Xs{!Wl^?d)x4;y?c2@Pmp7=Bo$P`I-3tFg6@mrpvItUo!Yz_ap`f`(}wf{G9eV z3P+R`Dm2*sJ3h33%YN$r^9P5QiSWArV^LjTa5ds(LFoSZ!tw`V&72MHo0%UK6F5i@8h-3gMUKWZ2AIE8aT2yHTZ}s99C3oW@?;}D;dhkmb~TagMU@a zD_Xo4d@vB$#=~X7!@|pAFW$_*z?jLGiLq*f4cC002VW$OkA4VMJi8`Aj``1r#1{rr z__-N&9FSl>_@Mqd+Xp)xrl+qIjQ&af^kp?Z{$b*e`N3Q}rf9RtH#14FF&{dh|GbI+ z$VRO#Dm6^qpO}Te$V)L4)bgBRy((M&#gHX2xUb>jMctgaPfm8QdA1$QX06!sl!u)y z#B29F{Iyzp}~^ zKGOBC^5cUYp3@sH3S4X2@Il+YO*x!>qM|`W?ZY>@mWw_lv-LJ9q&ab_soeYE$`W$B zC7^P`6Fn9o?Sq`WCc+GR3{(~s^sw^r6(3}Ac;3W$+$w;J)O7m6jE^h+++A3F zFkoNHdy|!x-{;C6V{#}n3Qn(bdc5rW7nzDO*)LBLp4&cBT6|vqkbdpOjIHn0|A@@0 zK0iC<`N7IV#ch){^rZzDThm=F-6tAx7!6GpDn6Y-EV|{LH~LAjH7Rdfx1i2L=y6NZWr%6pdj&@&C#1 zd-iLN+*(((nvFI3!Q1X2{?I;Ok5|<<9-NUoe(=_R=Z`tBzHl@||B&Q6>3%?QfhS8@ zJzGNo)3LqE>=Pua>;=6K-mjHy)@%Lp)PjGxUqJA**3S}lmkx7YQg04OYoD-hKC8o& zyq_0p)NYG?%((1$dZwaO^MUxbL#!jxBqw|GeCRQ@FLrRSY?3u``mmzhny;6iHG@ZZ+N76>hR1nX+@1GY zaj2&AwyhCveP9q5Icwg*h%+BKW?lkvvx5C(2fGz;4AN(e5uTtb3n?9L-lXdAcj!kJ6- zoEJKu(v@b|d|5+KX2EWrV~x)f4mTxNx3M#u?~(0#zhEY3gN_MDzm*2}ru5dLg_{dL zpW?dDv>{#6zbW|PhaR1&j}*?x9lNO2EMVB`FVOgmD~{h;d!ANB5qriKHk%ry*0qzZ znsUwjgxjB8elNmS;85Pm5cSc}@rv<awdx$%9b<5B)zImhKKqH+OA>^vgHu{t7(3miV26z@=xW<*IDMvr4AZd( z2Sv1eL~O(u19seD6LpZXVJ}|J;Gu3K!m#m9hhERo!pJA@&G?t3KfF*Rv%KRDhxZPl zmYolNXqd*Eh+Wy?DaT^;?DM@df-FVuP_shupWp7?opW}1dU&_n#uZpi zeEDy_#pA=y4qJ>_0}KNv^Te68r&VYyzdFC7C?Gz7RgdkF6~n;=LOu^2N@V_sFh2r@bd67dI--eY1mVtv?r~C z+2LAK1lN)mjS9^S!U_w1DYiU0a()u?$^@G&GbN=PFC3HdaPiP#?g+Q|_(A4)otZ>0 zW8dWm4_I6#ycOkcyc^oQ{5*5xsfsKMKDknfEps<6+#tj>WzO8Ll%F1#xPD$edT7fc z&d=);j>ud8-#Gg`Z-H9i42MbTRyHikrfQ3=+&J1TnmV-D7&CjBA3Rf!YpUQ zSC#C~ejz~epvkME8qTRpEIxb)y|g&#o?41B4;yRKmKFK|Q70NL+%%aU~jtxD6>g+9+kDV7PI3B26z!Uc&L?lFQGD~7X5%0n)w~Tx_ni~Qx zW))6QXN=sC72)xrimAni^SNi7K%aGor;QMYaD^#{0PCZIg9kdeS6XPv-ZY!hbK}sR zIoeY45+~-ll}NJc&2SLzYV=#`=IH9|c=vp8N7D4EjFXJJPicy?N3VG$BqS=(_E>R( zhu24!P|=s%M}=0Ndfu^Irg(lOOTv32*5++G9E}1CpJWwW=k8_IYU|b55@739BH&j( zSx86BGQuI6zadQPtx%a+c?9FfX@}EUn>ZRTIE%I%W}e*oE|9rv!HVQc?HZFA4N_dO zDeOGGbL|TLu6AN^HWgd!(m2_`IH0I;)kL;CYHj?Mcb+eCVpb4jU3uGU#|lZiSxewtHS?%@cv;Hw6eaNWxnwL?;CYKX(#Tr@?dt` zqNL#%t`XTP;3Q+?v}eJL`@8%WOh`}?Jy_7f%wSxlu*UX4l@@P?+VX=eLLBdfxLzF0 zatvY-;Apug%8(+sSRk(HfryB$SkGxU$ByH!7gj!e(W)>f+ix1Ho*5gb=fTv2P0p$= zJb?=Q+>9T%7I8jYpw`)(@PhNSp!0$QA=2`!n+;YnbMxGLxWaH|+i_Qa4cl0a89o}W z6OFxl=V__vI?PlwJmA<>$!DX+k~gvS+(|vfs8hNMw&$A5p z&Q9H8QlQ26V1^pY6w~)M8$wp}oGO~MG5S!(#sg>HbG2Jkd3cxzJY040%R+$_iihXK z>7gMcVo9?u!+&u)@?ChvVB`{2MykJ*P5n-3ln;y%!*uz;t@;Cc0-gr#B! zeC7Ju`22%r+lcS6;t*QTS)%G8xnfC%7-O%^2S+7~8fFgzwO`L>ZBSSDXLbG=wxIff zg%^jR$COFudycG#{rIZISLnr$8oN#Wr++Dx@mno^yubdCWnXs5_w)Tnk}TL5QZF>9 z)NNy5*3+JpdA^{sYhp>-Wr2dQ--hk&kIX*_-Ssg_H4$H(y>VglvCFEx^Is|-U*Msp zsd-j1Oy<+1y^j?1G(7T_aXCAA@VQgsHqrulCCeOoUpdZAY-mDn(@WzIagvLuD zPJI*NxC2?0lsKDSY-&;x)Z%J#;y&u|h`qhH(Rvu;P<2ySKnb zVQHxd^F!x*zbcH`4@6w;=u}v=OhF9nqwn#jyr&B2InqAwhNEMI+8wwO>XYlBk#(6 z&_Ubt2G_lhCd&hlHAyUexa47w$%!^T_RDRP*>xs$Fqd;UyK{1#E0E?WZ`v?N@aTdc zB`i*2J1*RrvuvA%ot%oA9jjJ<(?9vUCt;FF24@Yj<(^tRpU2UI+X3 z*zc@p=Ce3)r(BgZ&&rP*T(xfT6cx=g za1oft$53DqAT7hm*z=j~^D^yaa@}o$j0rDzni)ixuB#kkW0ZV)LW8;K($vdx+|8oz zC7U!vnI2s#muhPGF_ZE5A{p*Wd{zowf|8602RwzDzBV^6Ij+T{zp~BQh~x5+2hSzF z+(OGb<@j4QcJ($3^sm^kW=5U6Nb}Urbf?P;s}COdHDk@1tXVA&euV2X>Q8Q#YFf7F z@FVU8JGDexw&h+rZ5!N;bP80ExH9u3EKCED0z%Sh0%B{tFg4=Du zZr;W_4x$SZ)7WJ5J1zVs3Fz@X=yLJX;cQi5xx~CePw0Qo;psc9rs$Y)96h>(&rVIE zO+47vtZ-RJ<3_Jd?o5T>ZhlEI=jcx=J*mSV^@B@D#b*XieJFbgP6Kp@ABE`)f zCd28}7<2H^Q{GTkg%g||Z;Y}gXR@g%&QKK5`CJjq@@V6sch&PcIRgCV%R7oC)c>s# z`%>2X{mjz(|FaG>{pM-^big(|sdbj*q5lWp3yN5H%h!vfF?0U6h+7-A>1o~kFq;sr zRGFik2Rl}Lzm%F2!{aA^Tj70Ad-KBEV#_3|wAdo!k9Xa;ed3tT1c{5q)wemW+~Zrw z&guMkV#(J<`9>nE?)kkG+wfsWTE(1lD?R?#ZaV|zeC9LWHQ;gLITdj7;EV)Kw}%ZI zI2ZUHthg`EEyTg)bdQI%{>KRw!NU|4)8(5Lj^lNYm{ z(yu6ovmQ|v__oyLbF4$fzbmN>F|yLC>ea_DtXTLs;g5b*(ZsG=fs(loei*kb?c`Gw zXj;%C%e8WrsQTHALsk8YSq{|v+{Vn9|4&a>Vy?7?1jB_L^6Z7%|R5;mzLb+=sbzDt-h$ z*fwpc#2)c<#|OeyAM+aEhE>-;eAgHBDpo5yQaKULxWE)9LR z`Iba` z2XWTY!#@-pIx-}FrG`xtj*rj}{ogmWS>GJMaklJOuUyus#$OTu10c8wbuVoKsH22KiE6^bGp zF>7RcINUgG1R9I?I2ss;G8P|{5J|d}-Yg&_@VL=IPWqp~A~_*;*8W~c*7T+cFXrk> z?J;BY5Zku7p<+Rth)3;_MQ@F-&CGC8uBh|sa29KBQ)=)ps0*>ya>?2wbnhXDWploz z$&NCe7uHMi6&3iZoSz)n$j4Tq$KT?@*{Z!Xwxy+K5?5#Q5>6(?6B5fL9K_Te4|caW zM2VO89OZ6dmNX3%F?EY4$>iluS>z^n*O?tQkj6wk<3;!||kPW8g-CrW}0% zzkcSfr_!=oVk`?Ei1JH!u%t3QjELdW2r+OHX>Yu+;Mpd1ei>m_!S{Nm7Y!9X5=409 z%%u98cC+{`l#%8;dbn`K57*YlE2?HCf^%xPYq|4!8YBGlSPxqtVPbD{^mQy=VIjeO z@QN-cW0hF@;k^fDHN6mIUArtHL!Rr^(f7Fv7iX@F@ZswyZMovCuwa)Rhwg$mE$q`K zvOaW}5GT)cWB&FT7mhn=ZHTKV%-J=^qBwD<#fgL!uL^uj)OZzITojZpr?xayXq|6< zc#O@g(LQLFy3A~z#-@h?dn{O@HfkTgvOLOIW`omiJ~s8rFS@;Xt|#YLFwHxr{D`~a ziJ=|GN{_}Lo47U{6=>1&Q?IZV6TQaiDJRu+rNBq4kV8lJh=X&*fnvTsj)#H^5+~o` zUQ$12!3_BqI}aQX2=8xXny@w2M!Rw5qmUCG><8MMwBCO?z|O+-!0E^I-uV8&M~fdU zdabm6mC%#FU$WmY^Rhlx;xOTPXptt$^PX8mi$Cu!^W$Z+c&@I_eNY+q;{B>CA7=S| zlU&c)l73i8A|WVY@;!NXHjA%PmAk{L4<&~ze*G~gqW!dukJE{{ZOjHv>`lv?1gZ~4 z=-xh*-uy$nZI0#siPQO4ILbSuh4QBVdsXp|A%N-6$I6G=2c%T%7u28dV-9Hj(CSk3 zp}cjQ#v<+61@%l4Z2Oy=nEo8>U~@=RQDA1A!IH#d|MB}lCuLjLpv>*;4<-!sfxDc^?+A@;qt!;vwGN&LGyN&UH{nz>o7zfPvA63@)y?4;?P7k7BR9 zD(7fq^zLTns?Zh|TE^YzAXUC2;6h2tqJgw7;{v$B0~m7VwCM8d-7 zGXjF|g*vfYCR$%vbdI09xvk-FMcDJ^M=NfI7dq$8^qJtBBH)>kRNGb=8SeUPhN^Ck za2!v!u#J@p>${fc$AV-}uNCT&)9YJN$PzTu@f#1UOB1O-#_{a;%yVaWH_h&x!f?haja3HSz!66}&Iu zu=PD}`fHnm$E}JzH|ixF3|-}2ZGA#AJcRcC`~RlnV!Goc#;xmZ4bF81^=L2_I6S;9 za{Bd6-!_I8uI5J{<34KMG5J~Nr{9>>E|JnPE8)QB<6jIz6gd?Z%J+3|b&e5PCC}{8 z{H;E${q%xq>(7e&b%#3evV|>A>WND^s1-9y=}(C+hr=Sdi*FY{ zNHY3ht**e*|6s<$f*m$291j_oTP8UC=&@Q^aD4CL!w+gCyxBspDJPs^=5~Cb;L9d- z@PYkCA<-Is&VV0mn(~|uOW7<0Ld2&xO-QqEP~h-8bz#cw4pe7?;G>e~byyZ5Y=NQz;6H6^Bh#~QD) ze#UwBi<+GhJ_xwskv**Y<=KA#2?Jb5Jj6BTVzpNG8Dt`HPWHK-tYTR!6AIW#Ph##B7+SJ&w>y3pE~Pi)Oal9my6?KZv4Y>p@RS8 z!96^xhd#_plU1C&^K9xi#!aQH#=Vy2*j3u5G%XXI6waWoekEfW0kYPV-> zhN_5c(SI@hZeM4NRZREORd#WV+>R0)JU3=u*3TDk$OK3?xvL< z6>hx@`<7mtrK!x{yfC4_jboOt*SW1d+oIfRB#u37(096cLR-#`%^;h*i<4EYone)Y zGP`3zie_;8t?Wk!HxzH1^vAYVfz=@)_t<6UM~NSdcV`%S`v|mI=?g5I&&{Z`#C7$W zFEauImL)ctwKo?WNU#dgVP~>f5i&(OOp8q=xs9Qxbc;Q6Kzq2szk2pvXCFo>uC3Vo zC*j65o@C)uQ{+Nl7}@%?I7!K~Jg7)mKHo^PDM4e|?`3TlTMW;A5Mn6|NRw|hkWFZe zY1U17sv%k@FL#V5JlK5K0gElOCw#mARyJE);+cMKS$Ofk@+7c#J=ca)9T){EU#Tn z|4BPbgc3uj;B=nDKeV_{|66rZ&8B9}&JFVJ583|BkPl6Nv|ru6+2J35;g4zSBsf_A z1trwlIvdnzFuvS)@xec?_CI^-KX41JT2!d>R6oS(^8e+>7XIL#ANp^$d`%gTYYyk1 ziW_yzjE_Hk`ghOq98-itm^EYiku?(0bszpQABbT*{52~pc)ubet{Wg~^7Vha0a* zELkTqt#n$9$A=r1UjFLhEQto9b`6_?0%uC!sJwVYFr&##v_{k+;6e?{tnN7OF75?2 zvT=WAp9(YB-o34&M(o^2iyLX$N=yb@UarkaSZL`X!kEgkaf7rG!$F>Ik07ap5{<(Q zUo92p6v?tHHyR#(u*xFUf4@tLu`J9Ib~Ej_~&} zeXwI$CfRk}#fWji0uiyvDvr(x<>s!u7QEWKb7FL4~L*Z}55U=AEw$ z4}|r&GpQUnwCQ@2;*}RQ5{nc1S9&-kG#=O>%#%>`q*Y;^svc`Iv+Uvt9X~#}@mi}m zbjrHOO7yp1u@k>~&?Z2r*`qf@_0rM~8F^-lJ3ez421XpP_3@En=9~mkzap6#<9muyeLM@oh}?Gp=0V|7ey6e>0oy`-%XTQza(Mei{Xl9O*qV zGXwihxH9-XSfMScCVPlucf!IHM?1#$T0gD_ENqWeGb$!KRrw}JNUdlO##;cU9d7IcySYX@hPWR06y zMI5WUeEL5x#^6&^C)UTwA9RjVS)(Oi8-L$sl?BuJJ@!n8EBHD8Fv?$kIQx*J8_yLP zhGk4Ghc7c4cseZk-PFX)$GU-K-@58K@)uY+MT{6utmgZ9K=kp!8UHvLE=U}({%64< zmmqxnyih;0g|U&Jh4?b=^G$CSOnAV~(jdtomLb8w!f^hFgod8v;ZDIel}7d@9ZkwI zEPNk#eq%qT#V6|MC{yGiVYp#}d%=O$Q&Jy3uoN~PV{3TU)-gp(f??5z7rF}~Kg4|4 zz;1afL50PkuyH}*1lwPHQaqgT1y&{FUBup5KZDdYL3Y_?nW5ndwGC^n(=M@V^ zW!smR+nkgSM);&SHk%wtJ2p?TCr*%Ii&(>f2P_IPAI=ytOFr1o(~{oVoOPgwc>x#e zg2TD157OYGGqgmPk9I&@u6>P!mUp!Aob^g9%3_Op7%zsc3UpEb;kx z(_+6qHg#qJPvMK)%ppn~jt@T0I1nVqoqbrn|KJU=rn4V>xnXo%cy*a<8W#{&2uo&$smqN@L)fSLX7Pb1s$F*2fY+7T=3v)c+An< zq}cG-R-i%8<3*k`C*yfeIT;q^dlC#D?OY8D?rCSXIEXW!UCOv(s%ul9oE)Etc4lis zLVuNxk_v0b9MQEGELJiHaUW&)vGaZF+J_ub{A|uo6z1d{dmJElBS)9N&Ee2Qm)F;0 zS(={MIQ2Igi8+-#`uHK>Qr`uh%(4rn%U8Wzm}9_vC7pB{oR(@%BE%#MtO@&Y zBVdP4W<*?&cpHPGTql#CGm|JM8=F$&eU27|m?y@k8ShG&P0`>`Fi}3l!SkNCC$EYr z!fk?alYx}z5`NAGgM>XgEFUiXnIh|Jd#qS`kKoQHZif_H1imb7ET|B5JeGCVphL(t z;ew-J&;Cv^s}*tuA9k!z<~mSuN7!+LG3P6#vnD2XOg&*Gi#@zO_?V;*Z(ev{sVGy$ z1Bc6VvSeEqtSIMiO+Vx$YRAiPwdqpBh8n&lQO%3FLJD*knIHC?Yg){$@gQ-L#T9nG zc3IDG8-@8Y-G>i+d93#1z?KKGY&!DEaTx_)xq za+1tV78VO8tYKwcuwd%pM8@+rCY<~^&XLoZ7ev&Eb-ujdrM*tnCWU?16yX)R%mPRF z&+jnku-v{#O2dOGmBmTGN!eCHm-V1y0jH!qCxdHx`(+DO&&$djGtxf1QsSPdb3wP` zu;Bw4QJ3p`GCG+YRtQMW3-}??!*IaMBKwkpqKcfx3r^OXz1j@jYh+bf*aZS7eS9QP z;3vvq1&a~ z8a0lD1V!6}4jc=vGcy?QXf%n)u>BL?qu5X&zVq1Ep44<5TJ6gGW*(c1VjAwWf8 zXg`7?2FD!4YnMO z3Zm&v0=#)F3X*qZ86B4QpU9r0=+ek4aPXi>vu2V~z()s*2pti2NfE|_ZrrvaY(k7T zA1*mGvGE*Bdyj`h!Opww$3Ax!uV?5~f1F{BgC*}9f$9e1`X!82P%pJh9{bKEaKiR@%V`0 zW6Ad#X@>=Z4;0jVZ&8q1eW-zF;z3US0w?E~1yRauO5A6Jd1St~F*RMEFuBk{Lv!)j zUV}IZhOKQ6rY(HRdP;)lz@xAXS*E#P4D1ekuu^k)(D)%v;mZO8Q5K$ruE$OVFD9@) zxG}{~z}fl`2hZVq9VfV13(CZV85Rn-Fa_*<_@U#$QYC>cGP^2HA3U$f$)IbY&(e5| z*`P*?(M2J_;X_B$1h1f;!%dD(>!jEhG_9%;Xf0oMi1Uu9@)s{*7a0*Y2F>&q1>GG^ z>}*y$LM#~@TXy6&UE^kOW^H6mH*ZCPdwic6iILSSe>WJW3=(22&3@bl7gX#TSBHP$5aa_2rMvcHxZpD*l8DeMN=>X*g$9SC+GiMg4msSIsdbonagaj5 zNiT*Jp1mp#E#5OETO6|XYM376dypug%&O7Ke3FIRR-uj0C80~9hewKGVPk?Svrgf4 zgBOM@%nNoNXIK_s$oi@)JhaS7RZ@gYwS$X|*}SEpLSJSMN1G7Si!W0RWLa0v`A}k@ zV;;aR&`}`Hd|~woIoW=@&q{*f#)>OATYYj;R5%;#-1ijuF*e!0=WYo5pEgN^XYvet zbJv$$N4GD@-egkYqP1rh>w(>e&07+5t?xWYRhS#(mLa3E>Uk5#gQ<@i3T8x{cQL$S zpv1>JTU2W}>P*PagjAh8b#EgHjpqpZrNCn(zrmETj66|>4{dSD~?45 z5i8qUl$DPpnCR)X^s^`)_Fp0pBFwtSXTcslW`{LO3{ymSof5?FJn1>`gQK-7;#UA? z-a$TAM~{G+*QYSNVB0I`wBSWz^TUG0aZU`n4<@jl`OxCv^Pnxkpn4)}8_U5hf9+fx zGT-oARLIgXa`e!Z<$AD&?_llPdBV&Lq8qr=*j*enjG8XQX}6|xw52aw@F3vwc|n0G ziY!cxE0jbe_(}y5C$fG#VB1vU%-Im3%B017kIQjJe#?4S4oyDspssr+TvCT$Zf@vE zGZSh&xa^L=fg0m^Jk9J}a=k$eF%nK3&lhn$(fuSKyYDuKgK>FVL&Bk3iOya^VgYwu zOdeL~?Ebn^U=7;?$#_k%j#I(s6~BLeDHGeJ)pmK)-Ydzz^A{O%)QgICDtw6lwp#8_ z$*sl*uf)qMn^onG3VIkxbM{3yX@20`_;63lul?~c%NThSes22G73HM+X07ZVQM1&- zJMxkR=?_jQ1pU_xTq1Z-f%O23MFz_Rb_M~-`=4%jbvSV;%RZc>V##tyPQby2qmNU; zkoA3m6Vr#F4;@Y0TLdyB_lR*wH|%7&*izKwV8QzOkb>zwC+3FKH##~AG6&We+;B3y zBjCZ|$C1u_-PUQvs&y9HEedkREs2bc7oCqRC}RB0bBDtt_Q3+~IpRwcLM;>;zCCD5 zt!`>)6gSWj6Jp5VD@x~LFz%XUprm@>t~m3SMg~Ix0cI|TlanM`eZGqEwq&*(+LW~5 z>B0*uwm6Ba9Qd$6L4)-%x5v)2ElFKk3wE(FXb3)3+}rTMM1;e+<$#&Ub5@5c=61El zJ|*r8YOInE`n2SHEf%CIX54%)u}6t9SR$+?AzEK1uW-DFuGVBIFPq+ zp<@%nAE#A9r>CsGV0c`-#>@Vzf{^MAHlBlj9*b-1`6u|O@EhE4TsXn-Y{-M;g@5bM z_J_sUhyTfq>Up>F*I`Aq=^B@tKT0p`m1>&$@J|azQp6AbkkgZ!nHZ+=e*Ay>z=x^q zvk$)hvo^B+c=Up(W)Tyf5;-PT`HK(!d;eRcl{3L>)$b;QkT@GQMf(Pk#_sk5_vBlc z{vT8eeE00j%LfVk><#}#Bm^9r1b*yVwQtpt`AjnlSJ<%drXKhpf3LYVV)}fxPa8k2 z&5c{)FIZ2|{Ul;@?P3@_``u|$w!m_*-hSKKi_VZUDdW2`}>_<4`f4h zLKy8IKihTr`3E~L4K|_12Fs{bJhuCO7zJ#RV`2+PXj189IOH^;LW1KUV}x@E&kQ3W z_OOF*?&}z`H~d$1uwh}#YFsqaHsaU1_*chQ^>Y?I4N>Jjo=|P-eg1(D7c&!slhDB? z`6Ii3@Uk~@@M!1<3pGoy>B}=NesK6hYQm{QT$BDYYq5Q640hy^Vn{HU?7dIm$UFx_ zbHmApSFO4!vby`ZjP(sAmt)Qi0!}ro8`3(oSQL)17+l<`eVQR*-Xl)7st(B#7w#4z zd_-oYD63|AHj+=-Yl^Ac~1f&VyE3 zT#hUU-6uF)h`uG@XrNc2xbS^(V=J@4g^(VeCWZjUhR7F9A9h$UiYOHbi8?*p;_$&z zz?gMGN6C66&OK6GGT+-1Lc|Wlei2X5J#ZtVfhptZ>pdbO6&if}MM_N{PTW%zWO695 z6zyyjIm7X$nb)7Yr7%GJ!NUa>2N!T|h-><&rWEm@g{{?3Rp3cM!IO#a0<5{)4JRCU zeJ{ZvVhf8%v-w`f4$VM^CrM2K0hjwU6w)U&Gx>A4l(Po9-B#cF`)23Mz{kxWiWg1q zH{9d&?&#gJW7((M|H(CTB+ikY%y#g`1w~ihSf&L#!|OO71-{+hc5mXGd<9)z0lp6s z-wuCUwQ*gu(Cms$f`?gbKAaI0EzoASHRs<`qtrZyPrkf;dHcUV74>F-~vmJb3e~=^jLqY>jT&$?JyrY8R=bb9y zc{~RnC>XObTu4nguppdCfQ>W!>)OfP`OF56LPuJa9=%_c8SpS%kI7gmq&PS+c4SX(XL(;?#lp#b@Tg0}I!!h1ju4p?@db}I zRyLY9DU`CYzS^T97Nk)$QE17-gclX!3of*)d+A9x1z4!EzMEp9!93-G2m7RX+zi=G zA18CNK3c@Jm_d+>%h95NlcR_Ggu{Y6iUMMMQXg8lXFlY3TH(QTrJ#e$;9+@lhg$IY zLV@=#3NjO&G};%1*l6+BvP&p&B<$f~SP>%rqUoZD_>9B-FM2i}ocX*hapnsNjq{&^ zEG`L5d~l16Bev^mDDN@(ui?J`e*RzHvcRUq`$O{liV`LJS5vS0SCkmqR39(MQsZFl zaAm!5`Dfw=CkbJ;#0Iv+=k1@E4jCW+ryt7L``_ZGfRlWu*V~*7>lz#RgU{qwhQwR; z3r(F~>+`?2*`Y0CB`#+z)3qEw!can;`+^5^Gh@WZ03H?o{ai5>Cfdp+tq&E9g%=fEIKg}QJ$obb z3S}M#j~4EN1FQ$9FN_FbW?m8ZN!XvaS;Dx2pOe*{!&ReU>4Paf-&KU077OSXH+5(< zZQtRg7~qtUBG7z5j?=SmZouv?t{EvFg56D$jo$Y-93=J#GOQ5asZppQ%zV{>v-0PW z@As>}9%K9!fiXZ20rTwE6r*X7LCC$M(ak8F@S&yx?&; zUUpG*1y5SPYRZdWEJbq<_D$e)e$XVqGM7c^=Pl*v>n1xkKA6BHpl>q4Lx!Uv?j0wy z@k5U7izK)k8$@|46y})xNMdS;Fe*y;;ux$V-gI$8xq%*!Zx15}$GQ&zObaGYdgjWQ z(84d`TH(k#^FS95pT&bF<_kd|0vztXOmOqi)tvB%V+Ff0vl=r`MSy|?WAR=wr9h_! z+r&rB{%j3Rc3na;T$4B$HY&6$F@9`c7&Pahz@|-8OzaK!^~z-(EbbD~VsSlpgE6J6 zBEg91ivvs4^9c&!fwh#KEXY7*a(Z^gnc!t`N-gM{Tnl~d1`7-&q0Xi>1b zcaS4iVTWNt9b3XjhX-4@SuAcTF_}GR68pTa;9Je%LqGK1^BgvQ&z}++Q6urd@VJfs zgfDJP*|KX@((f*dW zfS0|oA@5#iyxgk845#++tiFE8;O*q*hnf-77^jGYaN6-t{UhNjwOU`VVTly`=l_|rpJ4FMD0Gb@UYuDCNo`E zQu*XuBD(SnGeZo!B$r0wadi%D8>>c#2M?Ru@)etod~aItj<3RUlA*vufe`IO!j&8e zyDzdHROC3rHS;913X4KWKZgRJ@+7VqQjC2iArs=b9bMSZJYOQk)o8$>UZ5}8^ss}= zne$#u;z`#B4-anR<634c(ZwL55XW|C^FqZ76RJD%1201`L55T+NP)_Bb(JV?Fo5iK(IbB5O(0C&L8`SlU9rF+IGnP&EAV^Jarv zH6b52SoroV{E^dOFEaVcK@&CADkUc0h6x;63>9MYw^<&4z|_)NZ^fl{ylq!y%Jkb;9An|_$x|CR;KBEJ`ux6J-1r=2)W^QzpvHkSidY}_pib#^Eo zReoBu^9?WKfhjBkyYC51xW0&;A%sIAB7MSx#P^=Zd7LEQv9!uLGK;qe$gMuqz&}HL zIm7!UNs9yw#H$>0&$KWE7nudb6~u5)dbEh!aYf_o8ElQ`**-|L_Z)JFvpwRdqA=;e zZB_;;$p;UZlWboZI{XQ0h^kgIVCQ6FVPC|iXrwB@q>$k0Sfj#NP#F9CM54o)DL-rk z8_%&mu*l+Qh~U()xaC+-5y0%sSRu%HA!b>C2h)cg`i>l2JRiJR+pDh}ZCB!MXLSgj z$9>>Z!tuEk2C8;bj9UU7cFakLQj!s|(P=N2DLT&jf+Hb-`>;8SfChh2;>yDeZBvqz z7z0$Dm@?Kl8D%7;K5{&_{!`(X&3W_wAE{+i;raVDOW*1E5~bf9OVk`n_?V0t)HDvy z|2v)Y=z(|QtlQW9;rUl%$J}A~{m6Qbf9xk4WZr*yafdl!f@tHXl@7|^Dx=e$U)BEf z^~#5TTFp()#S0F9)T)wXEC2hkup-s&!N0cV1NCVu6z)%IK2V>u)@kqMh7a=3T3B;s z*&F_yJ25?mN9Ft+h6Bk5|8h4Us23A(T)t*Kn|u?80lRwaJdfRhvSKmY2vn1^AD!xD~*D?Bvx3KX?|1^O{$+CGu};@F~?&vhWWhMkYkLQAr-g1J$H zkFWZmL-s|H6d$F8trBug0z3!q9%SJ|F(N&Aki{Rx~}o-sZ~Kntn;@f{RW_$AKj?#MJtlG(S$z(BtOi zYOE4sY3jOQ5y#;s_+W{Q&D;|m##$E|J~$eP>~V28Bg4b`vcXNv z%050!6;J;6({RBVbBTPd?2}Vm*p=4YNk~{5+gFwH@J7SLM-k4eLbWEZx#ao!@_C-a zP2cxE)Zo7GAWgI(@4m(N_78e21-$wk%nyIZRM?0xz4{~Csn!0xv5_@s$45Q6kdk@^ z88#95{;B`Z?vQ@)!~Rz@XYwM4M3o9ghad7k+8q8BOsp{ckUyROicy8aYPPRUriQ;% zI1|pvpDpiW|G?95!hm&pbGn6-Du0!4D5phk)Qr;$AN+IqwAKA!%Y+0zHinBo49l0l^`L@7z)8S>jhV$DQDa}d_w8FZFQhtruz&kUa^i>H)Bg2OKQ-4;3V;81Mi1q#dySZPmP)!AlJ~pL49_n)e`~ndgfGH*;cx8w_ zL|o+MY;v$DU!v@p$!xVCLBL?bhS#nuSshla;67O9lE8EDF4uz840G?vIn?kM&w21~hhqqjWHYB$gO0KM(bA)@{IzVv4;V4?ayjT2 zS2zEhA>ue;${G(gwdKb@eCMCbf8Z*^!TSxjmpAd~KP$N4$SSmh-C6O4)A#ne$19{V zUewDTfBd2K(f?(t&H3>7vk90?!fFEt->aN=kDS9i@u_1fduzrRnv_*Jq0K&4aE&B*%<83t^O zzggx8-V|mL{50{~e@ovVCF@VwZ}w^bY+%Fw{lVc6d>rv?FBCYny8pWPe(T9T-Q6VM z*m`BB|AFVyx&<~YoC$I~YnUCGo~>*+vh!+D4=k8L%|OT zg%(Bq17!^E3oCx?W9t62*!q5;^TBr& zj!X>^A32yBgdCI#IT#td4^L!dG*GvFqiJBoy@<2nq(A^$Z^MRN4k3J+>YC~?1{F=* zt#_0@vJ`j}**G#?*y!^m#z4fy`c6mXMXe?Um6it+ICfvO4AxL$dd_Ylrh2t^y7Y$I z_cC72(&lL}$dj_LVBuh#_3^CUkxQlt6Ee>?7R2okU$91u`GD00i#4|$BP>ofc;uH^85t)nW@R?-XTP41&Zyh$E+Ze5%#!tTWBS)c>aEO* zR)I4lnKc;|LOMKH*%}(`m>IT2zy5fqz=icpfnuX(+=C_->!u6=$@c|;eB6$P2cK{@ z%YENr&UoVcYMYXJ1{*#{C*}k7RVuGqwK^QxU#|8Xl<`Y|N{!2G|H(4ZO?Tb!_Pu1*WM%XL&i95;>R| zSv**T-t!;7KmTj!9>%w3K|0Uj z&3h9JgGA;`FlOyoq}h?I4IDtB|w5<1@k$+ zhA37Bi;Yc_y_E|tq-|(pa!pS;%~-)B8gK6H2W*I{G?l>NF=z zem&WfW1jeY7K7CDECM>pjV#>n1RPkK4mfaFs5EjsR%c1(D?RY9DWQV@Qz-wn<&6*Q zC$ljAj#AuUDpbRm@In553qzY1&zc&Z4-IRW8vn}3F@OBfV8eWK9ecyy5(#g%5S}G2 zO6(1P_js|bXK(oPrbe~jxA{PQw2rf>OEIPoH^;02a|*W zOJ|mw`mPWE+&CC+{`?kTmsm0NZ-w(khBaY~yS0j}jci`jvrGN(mai#Ux9vlshJ-h0 z9biLVjbb^=6@?b1r*+THx9{*_Jp52av7!8dW~kUUgS&QXb|)_QXRzRdKydSc1M7I= zT{bwcntJcu8XfkA#x)W(j1O59IFnEBU<{CAW~gt!CntW6W66S3rw?{Fb~nlVteCKX z|KD2^`=zh0o{>A>J+(eSikhw&bKy7wOAI>FUz|MW07 z2^g(sNUZ;}p>Mv6@~M9hKTLdJ6T?#(@&99F?K&0(#>8+YLB1y~3?1?Tr;=oOj`8VB z96YOZ*rAuTm1%ivVGHX6s}BC^#)g1;u1OOdCnz}NahAyB3T!BHSa6croJGZb!uA#g ziQP>CJRJ`@(iRIiTAbrlaqeR=YSg~t$owGki3rcf2?mlo9gpcUrZo9$819i_3E!(> zV8PK}5$Aucs#8<7PY;VPU{{pu?H-Rx*Q&64#XS ziWZlIkPk;RbQiO?DBnA<<6>eYyJ9{sL+)Q~mc%Ai14V|XcRC~`MGOpPD12v<;;(L0 zU_JBU0qa@5Yn&khP78YzdRq=0>}3^iZ*55Isl8ah&%dN%k;BG@@I6_K`ur+^H*}{x z2-JBI#F(6=-8bR;D?@`VKMD=jz2m;a$=q~9ZE0g;LBp;Om#=J$5#sy8#Kh53)g{Er z!Xl#cpoz7uz=(mHm9N5j!3-8o)%!M#S$7`PJIcs0|0q;oewkz>P{DuErRnp75Aydq zoqyHHF@HB`QE5{Eahd-b@d$LE?q~k>;Dda7C+nT7vNrsTKP4RXKJ8_Adn${O=D=ZRU*E)BpS7Lf!hSfejV>R}YwYUEpGG z__s!(A%*8)gNb58nT?c|&^dMo=7xk2F4g!v2eA)-ctt!GT)raIy_fsQLdkgo+H%)x zJy?$N@xNa2to{8Dy>&Z`c@C@HP-Ea`I^ZfI%X=Vz@i!M+!g0Sn6BIVY$p{NGw>N2m6+e=tBiE30u!w zFnx0P(-Xv07|}4}!w!~%jx#d?^a2VSMM_pYYPC*}4$oa8>^#d4 zGai#v;$SRgR`6gwGeK7=;9&#zluM421kIZyoBRt58moHl1TjD8eb4ja;Ou!1RwTJk zWMf`utD@xWlw~BLVJ#}yx99co2O5cOHgk0)_C{JCY6@q)`ciYj&WC4XmNq;Hu?nnU z32#$~d*1G}w*S{|O^L6e2a+2Vb%L)4DX}}WJXHJ|Hj72+p5x>u0f+BPw3ab2H7GZF zFhux2fBB`^XM%Cd0X^pVz5NYQ3al-G2QBx$H(_zC`r_2)qUR*`poOFH@q4)fLQdEDY4Cvm-%nLUTiO5Vd=uD|lb zzeHYP?}QaEpHEcz(Bf9m!Oz-!PnIj_fz!0PzjoSuyf-J)t09A(vt*BS7h^E%zoibx zof(AqY7YhpaaTF~y%FRQG)2iVBg2E~!|sb5Oj1gU94Z2Pr51^EE#l_scqk8 zOteWse6LiCipUdd3T9@yQ^;?UUJbW!kJNAU`S zMbr2aYHrW_=)&6^5%A#zr|5eY$F45{Z&-pkmdSB6M12uYQ*deZXHif~?`+L@SK*Ui z5uoz&h1wT}Y2PO_oPES$#ntzqiFJ9AV&hYd;(ifEhh)p+1}&{}9Tmz3R%{`HP8?kv zsjQ4eB0PHqB0AbHN-}bA%bw!CBif`b!Ns?bDREYj17}f_L{bo+l~aox!^8EpZJtlw zyESw$EI98X&c-%b@V$+E;D$?Umq>l>;OB3XQ`%_xn(x+(8BIzRladz6Ry1*SEw&Y~ zm&jq#WE>d{#hPC~W88e^P{l|X*Mrb$8n{F?+n{3r$jm5`{2RCEH`b!cCK~_o0+n6mS2o9V@%4;RM=mT;nN`}cxu9i zs1C`%jZNHpB*dx|_5^ZpvkABhY+w5Fh!X#f);+Cz4#*g&n%#(2l&)xDZwWE|CdAFg z$aIe7fQ(dAD$5Zkx4aulYz#JXpX9zb2`KSaB(SY+RCra`nDCH8xSW+qCTzkE-)(}7 z3)y?Q-71y|1j=n;QDqT(;yj^)J@~{y1uZVQjtm_SrMZoXi?RYw;c>!bbveJLlYM#U-c}77?}xn zG8+ZI_a9IY5Nb_*x&EJ=;r{t=6xV0+HCW1Mm0x+LlFb>&d}$)1!(vaCghh@SmI87{ zO-5~8P6?Y&_}VBk_ed^wX%OgWObX$iz_6@E?KR86AhG8>N$mbr%8H6j2PY{urZ^ms zIB-P3AxG|uj~s_X1h>qDD5(cqMI@vctq&9>zGQtU;`G5o^w5?=iG{3-ws)No7U^8X z`dpw){dyNPrL|XIeS6+uM(~UEQPZa#;pvn6 za_DWRK!sL9$x#Ot)<%Og9lunS!U$I7t^lJK-#Zx&H3fdT$-&M0NPuC5zWdUNdMBge zMR+>;7dr_su@xz76=W98WoF=>`C@^NfDhM%^u?MidS981uShsVoG%r+^r3}ocSrO@ zqZWb67)7nedlZ@$?QBwHXQ(_Z7^S0?>aC$7WBX!C!T}4Nf&dQA#tJ^}&c-wuaZbjg zeu~Bgip-&BB$bp@#F!LW4jjJ7Idy}_0f~EDY?4oO-<%L=bgAU7Qfynq@{LuIhr3bo zJU_!Cy9AbW4;dj=2PG!+(~Z5;{onsklIC#OIHyB{rK9OnhZ8%~r5!D7o(Cnk55L%W z_{E{abr(eJ5AXjQGk=BC=Z7Ds7zp?M{Its8PQbDS5{`1rGV)h5YxTb?d^)&jhw_R~ zY}*eUw`BCr$`Ofl_!?{;b$^-K?_TytT-p}jcl2;ve7=bLK@01e4^H{K3>%kdE_#3R z)QlGk+S}A-@wymoP5YI2kb`@Mk&8%cQGkS1<%1U1#P@De2e{ZAC5`V*h<0gMI8~Tw zc}jv{^`$9M(-obi*%;cmlxwfWB$O3wWj{dC?J$Ali92M1V_ z_o@fAUP^vuD|kR%A|dLl)wF5Ca$8d$1?^b8VeKaUGl5sFu9t2|OnsN?#bi4$b8fEy_XbDCmoFbFI8`5oG+_xT7LKc@ke6KYw%Vfj!R; zDA+T4ab~5@VqCSi%xlk-)DJoGt1mt*+Ql-pnVWm6c+Kwg0~-##j}vIT-u!`y)5p?|8fP!zVN1xI`1yRrl1Y6$M?}t) zFAa1QIj}ZTLWxnL?NMezw_W3LPsRmXl|-L8x-H%=YLz&BvWW3|wS0@bzqnfcwt^@o==y#J#dD%!v1#@Xi| z!t6s-#rqFjTK%QnNy6ZRCtG9`d#A%ehC0RtGO7`FZ2CgSU%5n8)Ty)xq$d9haO5xw z-C%TD@=A!&U7zL$hYtQp%`o`m&G1lxx&7z|#TKLY{KsFlcTIII^t-p^Hp|Iq8y;1M z#197V5BXp1zq-2N^q>D9xEz-|Z28E|b9v#0jWb@FDmaAc*tc39D$Obu;bCmaQf#(n z_*`u=-OlS|;}3xpABK%LPc8U(elB17iPdW#csevZN#Q9dli*YE={mkk-Xf#uC#O`q z!HHeG?oOI~OVyV=Dmw9Av`&V5iF0F^2an%_f0>IH6i9Gil3&5b^lpZmk@SJILy8v~ zZFtsB`uM>v{C{1;;Tv~2Lgdx|SD04(VR2_T#Fj6#_oI$$>w&|Dw|?*#|8D)jx=^it z{fRy7SB3Z7__IP{0E(4 zU&a4t{3<8c7-J>yK{24hgZ1F22kdM@S6LX9?y+z`Nj<^ws^Q#ie*R+;diQzm#e1(x zyWVv7XVC)l6z_yB#;hN-_aA6ebx8AW=x^P}{BMy_LyDc)<+GESe%SE{h&D4ME&7n( z>2T_54ZpVDw9XQdr}w%dj83awkl@_mDP*Lbe@aU5;XO_BT?zG}r`Au)n>W>T1*^lU z;|CcOG}xQ}FY)S}GEJqxXcyz5fDT?K0VBciE5V2N%gZ0$VWk?Ht;yz~#qjXOw1Xe` z7jk$d2)HarTrrJ@z477x=Nt|v5;niG^DGnUKeRzEv_jJV)D0dd{;5oJ_>cLp804_G z{a>XOYrWZ8ZgC{Dj$!rZ;cfh%~`jV~^h@$I*GlvXb| z;K%&z0H12J#sg!G8vfY~UK^~o)>`mCD5>ExD&RZx;lRF5h9vQpc(#MT3xjs`NQA7Z z{5o&V1N+8eCWa482P{OmF3%Da=jeX=!(d+H^V^9U^B8mtG!hcp_?a0q99b=<&S3Lp z=0Er#K~pGM^}tX2zx@X}{{=nxBmMb`c*3=2M?GT(_x}%~Yd$=XieqHpQ8O_hPJ%91hw%*QsIV%g7JU-JTt`uDKU{NTFl04$K#1tzIac5nHr;(@eexXQz~^bS|08(pC7F(ah|M9k*5L6NU)~ ztE57B*!p=GXD&#LuV7}m=qQlJJkNqjCqmc1pZPpbvpJ{Z zh0BbydXBVhK9(N$F-PP^`Ms!$wD0`~l@``4|6j9JTXN6u;|?2tABta8Y9hngUfVeH zWj+_r*XhCicJGZ^vNv#VDf#$Ze0Ii)kCS(={xB_Wma2_Ci_tHxNHNn>2Or&V^=E%5 ze5E#BYZpuW0~^+Z-OhH*f;|u3%&B1#>{wAAs>{(nng@h`6eTb_o+@|zc|7VG#rvGaTXgXAV2zJLUysBbK>iVF&O zSk>lz{1DXgpsaCfg6oSc@n)F?#~WXme}8q0`PD1qsa{(ihd0ZzADDeH#7@#ej_>m7 zy&UNWJXjYhZ_J*@=Q!c@JU)keZxe6Sys%~WUh+4p=ZA-6^Mf91{TPW1>oB(XKc%c0 z8|q~btZ^{&vu4;;^;Es`;*SjVrk;JwbJ!i{6_j{MHt$#!$B`6a^j~TXc zD<3&toHfTz^WsE{Ij5HM+4zaxD|meK-~=n@^DIsGR9XwJR6kNk;a+NWN5H2~$#TJj ziBDO2mzWedDer7gb)K`(m{ZmL=B2G%99B(A?*e>Il{oxlaS+?G;Ni+6S|3**+#%}h zUiH1@u;DHz58nq9xMM6BYg}X}$x1LroXNS_bmcsQLk*ikP^pGnL4}xn%;}_AoayOe z($(kuKIiMOo}I$&#gs3@bZE^l&g6y?{$5t6gtv19cxH$mak>!6Twv}~AhWs8##cy7 zW_h!Tdq?AhG;vPmGyS4Wn~cwI7Ys?^x#xQCBg^`|J(qfO^(V5JuV`$1us?HmJ?OOK z%3KEUX~)q8YEwCwUIxsI)Z1C*Cebjx;`@igIdawiKlJYB5l->x{E=UFBG^lx@q%_) zQHe}W0`rNV9$^O$E0>7>lbplObFh5nCQqhq0h;$Df7idB?ZOwqzWZ>UGCNyh$7-fL z7vn`ACa>cYtw{QIgHNO?E4}TYVnSWv0UKkc_`Oe^_;`-yH8}3r%^bUH(Mcq9aR#=dq)WJQmS?i!*T&sM>5pl*E5zn13J^A~WEaIyE7_nOM zG5e%`p3WqN3pb`ou94zS+TF*MwJ$VlkMiXM9|UAUOGOT9NL;XC5q!ua;VI-Y?dlUX zwhw=#e(X3fon`eW2Qw~*#8V#qKUyyAdB2clhXltD!3SPaQ#-2}C){>C=9AI?ulKER z{|ot7>|6&QelS1SaN|=mV?2}f;=^C#mqu%xy>MCUY+Iscs`Is)?r*%wj%;6R%H17z zH_hZ}Kiho3;TZ3O1pa;J`Ts9b3i#m}60h3N;ryVP`y}_jSZ8%ZrtjRvF%zm+_RAGH zEH(JT(9Y4ejKRV1@OzIrHU(QkTBhxib#FWoTak-_JxaF2{upk% z-zNOfoilKfOzw{)yMu=Xrv6B;kl(~$ek?@%p441+rkcm89L)x+ci%g3jI->1Ti!Q5 zh0^!Ox)M?f4^9zQRw$UcarJ{_mc#iAJN~l=bbc`0c7NZGwQIQJ7Wr8e=mdS=5wuLM z`pBvhtI~r@g!|{Gzu`@olfEHE$f~;0M{vzN5f+1l2Gx~p@+;VwWu16xc6k2@vHP{b zAVb27y`eG1n~nLw(FfOG9={-wwA!)ZWznMQ8ZM>(lUdCeA4t^jGych6!e7s};OLVBN58}gOl>Gy^ilTyhe>OUxN`ZL4>7ub7oWX$ z%YD{^tzUi2#SKd8xKw?hr4FyzS0!e>g#S`OR-{d8{9Nx&OcG--G14?|E+CkUdcN%;V8?w z8#1OJE*w0tFJXg}UB-g%ZPL%~Jinx?S1`lipur)xKZg76x0&7k9yBldlEi{(_pJ{n zOnZ^`tzPaEbE}->&Tq~KkN97?d!g`%?ZGS|fx=S??UuD~lBFyUweOQSsCE0pvHx|F zhVLrh*WNgOI6y7KB1yQ8Piliq)uV<3RVq@JZ4d-Y|8FYed^hKV8P|pU{=|Y;>rZdmVcM@MKmG27 zq{0;jj&gm`%s~qSHfnyXP~^8*ypG5FAKU34&6*Eg9oB?i(dSB?!OzGfVOa2sGcF`C zY86j`fM`RiP|MWR>s@yLf8Stqa`=5SM{U)~BPkr~84lR+*y^*ow`sM1O?$!j;}^fE z`hrKCG14seOrLQq*~Yy?@YD+9`JFWsb$*`Rgol#qEqb;)EH!coZvl?tbs3#@omuv2)A)-EZzk zbp1?kcW%7lkiRz6LMFqi>(ISrvJYbd7oKD8XO+-Dvhc&S82e9?-mjc*#m~sO!$5)g zK)oG5$NUHx?cIzyJS3?H45-GnHSw+4OwgAwRYWKHK;dGaP?EV1AH!c7D<)xwdTw5BnMNSTXMsP5#&N z-9orIVfwmc=9JY6BE_zX)-GNRG66Z^4>x$Py=bnYx>rM~mR)#b(}M>xrXTJ}Hg~c5 z3Rp6@I=tXhs^vK>F#m9P^#R*6@3%c?sz_xyU~B&W(empo-yb%o-%Ho#Z*kxR378 z4rdd!{MgOYkg@Wy?*rAx-+MRCzIIP)gGI`QG?DrP5j}^>wmdRn>TFB!Wo}yU`$09~ zowNIQ8FSG`>D|sUk_XLBa>&1W(x}?hQS-YwVJ>Tf`u2n)^2ZqLL_&G0zdxLN^7;8Q zT1`I=esKPw!Ll^#!11+G%m+ZrHvZml{#jtY-$v>1(Sy7ZA8LPjevJ!Se{g~{*CUJR z?g_P9%J?$UK1wL~JXvCLz-jTUbKkeMyl&CIc}7HPg7xl2+E?Sb6(U4#iFZ1`ncp>S zc_T~3(o^k6PqDwc$-HpJ1Rll(ALO6(H#RX$y}^4&aCX&#w5jobj{RD_w#Rm(^Biz*YFX`h-comV>v(L(CUE{Rg>5mrvco!-!(Wc_)Bj^9V zLA$n}%{t#-$t1(EC480MHtBh<=V&^&vaxBX{eS+3x%AI$eIFJ9J9Z(}SLZ^?rm19l z33MbWHybUk+i4M}y6Ko-)|11To4*J#+(=_yaJItsiMqU*fN-a$i^%P7YgTLQQB1y& zd#qa3O6%*9T^$czF z>9vw%(@?*i{%TdLEYBRXB@3B&mouIV>{Bb)5Mp^S#;SPE^EL-R;SVx=5?$F5(%C!~ zd@R?zcIe#_YHj0)@BfixcFwY^KXZATf_gN&;665++b^RpP(I^^y9E! z8~daM*rXFIKG#XiedYVd#5mz`uY`r6=pN2_Quo*$ty#N&Tt6(KdarKjxq?Kd2$|mZ z`@K33H|+IjmsKgqy|L5xy;II#uYkQDj9*yzzHnx&FoAFoZ!K3;vt zzUud!ABjv6s=1$9_ZY`=h%#?TlWH^(tmF4(kXZTYi;SN2!6F%5^KRZdx{c4d4g1QE z?)w-i7=37lj~O4!gAW24pi>p?!@m;g$FCRJ+~i}R%J}x;{fqPDify;V+?41$f6s6B@fN|St9IRdZ~AfC zr@4X~S?*8C`rPLuetAo} z3<7LlvEGpR`Mlfv&ZlMx_1ih?wgJ#@}lb-Le$aWSzP$d}rVt>Qq zIXnq-DnCy3lHhba!_}NH`+>!TB{Q2>oR~dZTv|P`^PS?>1-1t2Z9n)}55KUO`9dK41UO>lvTM1N{gc#tQ)l|0FO!a+YnMV7bLHOG#kIL&MDr_VGH* zWIU|s{8yD-Xm0x7YOc1clMLkAPNZ;OIKesVTk$@{jSn;r?i0>yZcOrUK6vqsT>bwK zs}JY$n)EN&H+4B%jK+&Vn@G+D5%vq`PVZ()Z`*dD!n#%ECa0#f?aP49yB3lT{%*66 z2!_hE_?RDGw`?x!gG`qF=^NkkzH45^WG*1m+-Uu2{gv1U7T+f17_Df`e<|=@>5#ds z%hEHc%bEuObFixoATWnBpeQwG>DS0oAQ!Q&Q zdIa6Dn96n7VDaJn1&_*%G)&Z!rFq~Sn`gmY<2Sg&9hYtoRD*p`XuHKiK zyDQPP_T0QhrppDly7luNh)62GyGB?-tm;YoVFfd;1}p34BeOrbwuxx*AGpu(fBN=M z8)DlM68Kq+b{)&Qu;QY{>8iW8oi;q->(Be^+;ma1>BQ0pIVBeN-)B8J%I>`AHp@|o zP)`eeVa`SdueTp&UN)>>=XNt7L3583dqdM5IVR={i3)BOjExK)AAaAc0NqxZ(7-rh zXNbjve1?PxHlLd~oQ2;1|9r4V`0TDl4|Y5_%JMtMV7a8T|J(!R9=jS{4zqDSx4j=? zD4jmP&Fu3FP=9JgdUan#3V$$zjOdU2c{MD@T6~VV*oHc5+_XF((`q2bHn)vULVe@& zH$3(Bh97<(7TjaNzNmrse`6ENXJO-Cj|&gmG!%UBtw?ODX6gT6xP5+`*9#q{96r`_ z-`E!THMc1|G(Ir9EpdXSq|ItpMGt*u33cfjo_zC%U7W{$1RtBw!Kcl`oG_>9m89)r z9s%aQ4F?Q({C7z-x7P6Hevx1O|4)yM(1!yujt~1b*GaQH_n4t>)KDe=|3LLkhl3m^ zjFcZGNz^+YH(wax*LUEL)*F6~su?WHFJBjK^0+iVv9Bs4(O~{!1ux#F_zuS-I%15{ zyNqA#lsLt;-|?`q!#nFclban>9sev~PI$p5-YWm){gUFo1BHebpgOEWBlkyg?tWeg z@fqyRUme!glxI3jDM^>Ma{`9dd0qk`E-6Ko%D@NPc;|DSrozYC0CuWPcu`u|@^ zf_Vbd=Ud5ao(Aqp7b`d1P(9WoSO5Q$li5yV>xbI{_*5m?)Fo`bFeE(Esc!DrV}9`X zeO5h1|y6R9K3>U=Pe;?E;kSPx2=s2BX-3oUFL7gD_$fK zk@Eh|;eC`2E1i7iUsL?3lkFV7uSp=Xh@KjXTO*`K_&hq)Rq{5z0TT9&kbhJ4lQrrAmn#sQ_<|H%fe%8;6_9khCpRZ*cj_jHE^AK3po zwKlodJz+B!y?f@XSgWxo!>9k}vs)&9n6!fb%k`31>wo;4&CswkaQpr2&XZIBM*jXE z@37(Hw|N06VuxPe`LJxl1|!f806FGA6H*JL7!vEhl+P4A-jHB0jW?88i-qX}|K{eW zUUgma>Wpo?U?1mJ6Mkb9ZyboIJ4kR~!;5n$- zZz0FT9MHJx<Pg$AO9be<948?CiZ=Wk;UpG`honc8-CCG&Nd++Q{|CTUf~qO zZTFewa=#cE%=5E<*#G>U#J#-4{%wB@W_W#mk$m<)Z^E2}e-{`x#9B#s8NaYd)81hA zW5?;Hdco$VG`=lUgqJ9NIKI11Ie0F=)22qNBy}_1wTG@ex05(%d;5wR=fgSdTr;d1 z9!|85k!f=1X71w4l34qVkLyoSo9%m^1@qVi_XzD+*#CTwX;Wcymt$!s>j8^6QNxZi zGQx#ROizB8Ajl$cpu>Vu+#4puD542c+;5s*bMyAe@Gbk_OP5cD3oWG z&i!?wD8b+B=7q5CWE&pAUFA*zZW*`EsXpux=HH)Ul6Qn+k!UT<6 zctfSwI2b<2Uu$M!T9EW1)uB$@A)tl9TF8ts;pl-T#sjxhnbp6$If;D!Mki-C=5=|)%i5_#_brK}&_jM7Vf1hY<9QL|zfL(q0M zM}^cli3M}7_HSyt`L1&Q@n;VcWSKS8osON~wQyUtT>8!byfL4T-~7*GcD~%;w#|9t zH~-siKI0E$kZ@i4Qt?{-!aWOrd=BDcJ^o@(_u=^b+TtzUcN-3*vAhQjGbB8mU=e!o zsQT9afJCN(|L=}xGb^Z9l{5F(CZs-iuy)^t-VcV+`HeG92v@x|F>ES*fBcU4!#TqH zgeEaJ*8H&O?^)Qt{IG+%fIwm4yMuofm>*Z@J4;W0Cvni?_5@QCW`mgz8@vu4ujMa3 zETL{zlh~uiqu@Iy_v40@eUYkN%@Jxdx3)eO@Hy7z=+4fw(0*|kpEoDd_kEl5c>;WG z4#ioru^lu#*VELVV6lWO5?!!Iy zlC%bu2Tu>y9!xNJp;x$}%7Wp zQ^Xw=(WdU0k47@j+a%QXhuPlmT-w{D&dvHU4>VtOLu!VFG3Pz|gNHsWJ}jYjyUfP! zm5iZDb+fvSVN>b$5X1Pl92PN}9}cGRDLmM9PvUldqX)-<1uu-&H?i*%2xW-SIPgJM z?fYM5>&FSXf7dU$;^DN&k;AD;LOweudQ)o(!~4DJN1i%1Jm}pKWuK?-sL-$SYEOIL zuYIN&E4OV6jWc<(O{k-NqROIj|5X;soJ{)BHSFr*HVec4NZfzb#pWue{I~tBng4@{| z{F*y%@+CZ);IqNtv*`ARJ;H1Eu}%A7k<2+m$Bp3;ze{tA!341cOC=e_d90NWS%d^5 zS)Mx{dGTR}F#no1mc}K*{mcvIe-UG_2tIJ>bAS4?bIgrZ(kwTf_|_OZXqBXjyJdvD zx5_M7+LObRyki;j3;h_grO`Zf@~nBKv-mh%JRE=U7o z@T-dJxjon;qj`cY{fG3k-g7038~xaMyj*i+0{%Nb-~V4l;YHSi4H5^YZYYhI(%9T` z$L)y25tSp)0ynZOpC?)9Vfl6;yHHF2!nT{%brSdT4@>8NG2A{MR8}A3?7PogVesJ0 z;wAr%9%f0Hcd^IuFvHXj>{AM|A8znDXI~&==;S4AqRQ~9<2!pmiD>oVzM}?J=ec#h zvuUW^&K9^K@$dd&zM0Q{yeW9wYI}GKSM{9LhjZAUODuhKFtAUA{o0EU%M3nL=>Kq% zFz>#~_%!Idfx~jf_D3Gh9ExoGF7yBYU)$Sh!CvCS&-gEDe}zOvO`YAemG3#HY9GAt zQt~GnHzXP`a8;iTTpHBJy z!0>_@SKPO@?nCaP$%%N>LQ1ohjf<7;sc-j0nipSl0_B_7EB~f_7yFE_ZTjq&jpA_#s6(_~#mIrg!-uf2M zZkaZh)pHx43d;w17nQ`@ck_7;%(lAD!+2uW8^t`y=~@jOm0U zF&qE!X()a;e!HA^L&1Uh&5c!{mPWk`pBv}qL>CLt$RA>`<5T*|Bl9qLihPNH#6gqWkI#Arw+Qu3Vp7~*m^icfvI86Uw#+{l z^4$KI9X!hLs7x>+g5kl!=EelheR~!9w5t2t41BizG2?6~G6|H>D{OQ}xJxp2dgSI2AP}I_T8JKfVQ#pZl^Zuc zop7qrY&$5!qr%LY(8TzVEl`8mwq}K^KKN!91;-E045z=^e%d#e;X%?XTZW@v)t?X4 zdKMN|ZH>EsG=7z`nV&`N`?`m<;g|An8!)j1D*P7dM&y?`5UcIKm zNa*xu^_ue2YQ(2&kq*t_kAM8xmh zKLv@GS8iH8cbHNo^x*{O;WvM?*)zO^&k6W9Kdk@u+^mVu`t{le4+AA~ggs7*u`h4n zc^;Wi#Bh`&+#~DQ!2>f6)H5EG7f&o^7GJ91_%ZUh&bM_%>lBQ5SWY-zS6uSYJZ@K1 zfUc2rqPF?P1`BZsF-Cve7asHNUKO|9d0YI-l229QQt~f1j|bN{*VV3Y>5<_+#yKao z%SwYMcl-MtldojC`t$l0jb3BA$m&hu|4_qWCTKX|3{M{Z9;<+rZcW^Gc7mDKoz?G{Tg z9r1tIBka4IwWGM1-}vm0!>YuXnQ)d3e#NZ^) z_+IXw<v(kF%Rm|19?|{{4ZDBte|e~_~HSxiAMVG#}kfR z=09<4uIN18rt&Q^Ei$5~COS)9Q2V%*qjvkDYhzSt@p>7;I9*p#{b zz_HtPQjSKqXaA5ck(f*ce5UxX>aDWeqmu$zwpYfqKgF<7jlG^g@Sj;^i0uAcrd@| zaMPDWd*+I`hBy&}LPw3zU3`oOl^GvSuz2rWBO|GQph!rLPl9C+dud|$0*fT(xd-lV zOekXLW^QBjmT3CjGEb_}gwKsn>5VMomC%*%*u-C0EKs@oBkPNdf!p)O!vd3=yIk$` z3-%uD-S#JX#`Ay$=Qxk?@m%1VZGB9a^})uT;vCC&@I2IuqUlL;BKjm37^8DM-d{atCVA^AA}ZM`pwRk zcW1#9=Xf3ke*v?%Jh|Hqj@>R}YvbcNEF{J~?ciah%s%IEEvpX)nJNz)>22P{d@R4z zSw8nij_`p8afTfiXSsCiKitoF zdI680UGvxa|A(b|CVYRv&$(Ax^h&^*pcgxmKsC;Tj0EeZbjFwU|3$ZTB#2apSnl=+ zR0y#!lWg->Ac;Ugf zXbs=$rq7)V1-58#3w`fw{IY=k2y;=v4Yl2wJ2_J&rf_{YwfKDiSE+b&=S+8{!%9(_ z57OU++_-+YLQH$1a6w6gOw0Tp$0QH+#2LHy@Enbk=-qD5<9@^9g2x}jXZN>=u+RGd z8uIc;nyi|dd|1V#$U~at>x$=~d}#fw$% zzTVou{H|9;?!nalos9|^EPwZ^aLxRF@|Bt)SLeGqJPQqyS(@_?OXvOwR*g=a^zpl| z|KV4s_c5}lyQTh-mJeKyW2 z0eX6o{0pRHg=f9cExxt(U}8`49BGzc&n7fC+Rx_Uyx~9Zl*H})h0gcBTbML88~8jn zezQ6;xYtWf^{?tnZR39pmyfuM%r*L;=XJ@bDft~w!o1o|-A%XeaUX2se8$K6y42N! zpYaeQ(pQZSHNE!;`zc z;Lu~nb@hjNHx#7QTQ8e^k9#9Sn1qj*e(o1T>4Zn>2hJS4k|bhqxLeUoLhy;hgL87l zJTad+Z44Q$e(23-)_3FM@x1?*z3~05%zoac0x?ykZJhJ>G(5eirc-O%PZ9vt6Ka+`x!G2tW4*Q zk!sWpeChrFR`{Z6+8^$-I}{!Id`4E^w|UNmp5?wmm%=|3dYllq$vS9|Bdqj6j``%x z|6yi)oTUzYtpD2%8eWj`yup1gx1i7=!RZ&DT8;IQt|N*uGE5$G3=WzcJhbeG#P|Q# zoj4^~J{;p*f1fpx>E4G6oSPkXop1`j&^&>;)2|@<9Z&7{hiim;S{*!;ckqI5dEt5f9nQJ& zesN`@$h^Ahf7rY2kETy^&jYXTJB*pCnj4e2-@9eAC8|ZpWGL5&Zd|JHD7-sa zM#8|KDZN7FL5}c&T?vmSdb2we_#8~&zsexn*mCf|&fE_MIiGV2N*E99c#-v#m0{-0 zd&~!q#7XRZ#wX4FJE_atLhgucd7IhqucF+(Z2^AG9k35(#GCB;MGrUM&is9nW`Uh7sv$giB>BI@I%cJ&c z>5)b6ehD%$I4n3WUl5;lAYa8xpCkF<2jltxH@1TsH!PZ-vR>-xOualewJ#__XywCS z`HON_1*XP`_t$wn4fJeDUv2e1;;Z=0^QWA6zMDHw=V4QPzE#IaJo)05UN#d|{*XrX z<81~3|86opUwFR8u&Ledgv7u4yBu=YZ4bYQI<6;jmLW(~ul+u6!u-GW>>@(Va}JdS z=In56L`q>o;B^b1qqc`;HrSpk+W{KbIB?+@b6D->e-i)d@5m%1GL^{Ge?M^a z?1mzhgon%9%>I2XDA=lz^u{5D<%LC(-(k^%2liGs_U_+fSe+wx{{QEByJTKoDCC~8 zJd(@c_#UHz2?NAX0)-k&FBF`3&D!Yid-bRtXk=`IzVjRnD{l4;@{tFQ-zzSN+E#F! zZG!(c%?Dou7$=AF~=X%{ddy?C;HtEC0})9Id0)NldYjiK!Lq~3R~VZd1i+s z<_CuyChz~NC%gHLV{3V1z!5n%R)fGTVLb9nKWNWPXZ)HV?0`?ZsI-li_87es3TpB9)A38p;-~EkoX%W-B+69R#Y*^T{ z8Xwpn54p58{*psN`-ep3N9uo^L=NT{tzBnh%-+yg0-8>!;Q!?Q;DCGzN1Yu1ff?Is zn3*`sLxK-EEmY(Gv?@e$by%!-V{eCttL>wgpT3Jn#lOCAxf`f;?cWWHyGPf{ls*vGkoGG2~cLL+Cg>4_yo@*r6?hief_4FOBd&K+XbT709*&g~jF+Zl#^mz|E)AQ!W1e1iPhx*v0 zAK1ib@Vyk&$8{r#Pch+9nh`ro49^*rgUXCYR_rSM zk>B*VxsB~qrgfe8#ELYQ#~&;VW9B!1cHn;1_QRsFshC|pQDx!w1Ls5vgd_BBSfqG) zRIZZ$q)dxn0)K4CTib!TNq?RTpe?d)w7;1gZQ ze&)q$v^)W$>@ByFlwrApS@_`DG9U6ccwdnnGKK6<==VyE=Q!O>;FwM%n1|k zKVM#Uk~Nv}hEbqGrNE!XjTR5w*4v^9A`Nb+ULK*q>-Lf090{xEP53g+0<GF>%QGjgrejkWvqlMmbo|6t^*{o;v4MreS+Cr6h26JIRzg!P_p`8};jPBFqqa(>kbXV6-d(g^W_WR~A~E0W*t2Q95@Isbo$gwOA) zhkGyjv48#lf1*Lb38n8`0tXv6AM6o+yEiPUEwPE^ALH>)EDjGMn4aH|xOabH|MoqG z&+fMgs5>S+yU)zIcl%qZgV8HAcpYZ5Hdt}RvkUHPb9mtQsAtU_zXza(5i`HR#QkMW zHxdq-FgITDyX_>&-1jlH{iJh*TA6aIqBVQ?9_a^J@6=lIC3##Kp2cviOFUyIdC>Ui zL-C|OwlLH8tqT7H7~k_$Z-3arxhZ`=bAB^}{N)}QgL)oucDVyqEZceVw?FK2U*7QETt5V>&X z3@&aSscl@A|nwfBha#R#zFRnhXeiZ`TuqQ&PlyfRpRL|9km3ne4LFW4w zD;GXRR|99crEJoCtJdo}Mr~D4i4$;1e7?)pZ{}L(yNw$CqRRIiR;1WE7_>Xwbb9n8 zR!Ql=Ypp*v*#|zzpKKPdex>nsb@kEpI}C$djx_KKvDo|f3vapao1r#s_0wD1%wIbm zi`-z=U+lvsBp3Qdp|Hy^AuhRThGMhO<$E9AJ~$LG{ded*4uzu!IsN42JL9hZU^*-! z!uy0hGB!8DzN&FaTYli#$LGwBS%5|=PCVRVnYca0u&Ht133V>!bH#^QIKT0K{QsYw z>Az8%+3jzQ4vrU&-LBKiZk7WrBiI>aI44EB;DTXO?fcNDT^nc5<9@VM^PE`VJF(*y zIae$XCJOf#Br=t-%jJGBjDGX?h*5-5@tmhCPp(g#!Dk|MkKIFPQ-gnj(sy3NPzAw` zgNL^BZd~n_*mAbHY0m#P17EWr6FFGlw;dKe&=`4fQgY*s1IL}x*$x`~Gk&?Cc!q`e zno!Uv#xX74ri?V$&|#O}i}&hNW5Vl%1_OQ_#2jY@Vr z&{2D>AUStmoAhbnbcG)7>ufRBzZv_iek3j~4PW(5z95)!%aIKZ2mgKlwjyHnYNm?a zj0{dfv#!X*_ZK%>RBU zXvsHCaSLbI-7<@xk!fXxfrI??)ok;AZQzmbyTUZ1H#%H%7l-T93-a9m_w(2O_Sf== zdsSh~RJ%8L`HMjRoQ2(=-#JJMl)tAy&rkpA}B;>y>$4eONm8>vIix$HNQT zxY(G_o1OX)&6BX8dea{9!yfAY?M^xym4zSnKQmv4Pvl27%Wu1L!LQonYt{2_In1aq zXtd+r^KVTA-(t~?n-5EUrxn0j=W07V4Xh?UH2foL{%b$V0+mF3bJ9 zfy=Z(aXGsXH2zn2pz_c*4zUl%IIrE8Dwg7AOFOsY;ql!<;Ngtq-2FV2+aI>wIMTac zP|@S6r1BkUmZQ=2C-2?%t9E1hysN!xM;GV)M)|g%8mk-rvCK`X*}yL$_#^kjjidlEd%d9aC}6J%)@XH~8&;yiqWeK0V=oHcNS%-Rk|j9x?W0T0lP(i1)}K@2R~&P6Fby)8z&kBLMopYEv@*28%j=M&`^41r~XR3I)d(PCwqA;O}IxH}2PyXJJj` zimxlK_?mTOKWF`QR)q+@9X0V!4O*iXe)zJ-=>NhS2}axZ@HNU79ylhxP?6v2;TF@q zDKZa^asI!p@rkG4#v_L6W(f`HuMu}74m#aV;nCxhm{7h;($V=q;R4?p8K;|(Nit5- zEI+K~JZ0>%Yt?-toYiLTd&lhHVWzSknc9UamOD&89J^i2+teUqpq^mAWq!lsH5V+> z>Q>}7udwKC%V@IW>%YtXs)7G-!u*&CQ-mY<*_E80@hy00%yaZa(^}_XlMFEq*UBT@ zEIBgn2KQNx?MUG~BYWX^(=yI~8rh78ll9~(^leO+?(=uD8Obb<-#5-|Ug3K1uux5XmCH7!$b(6n7l zy?epy8CH6ZOI~yzQICBk;QKwXafYzE#F+)^2^Q*qcsE2a_iau)c;tsnKu=6@^9r?! z)&velNA1Z@EM|=zFDeYK9qnk;wPEL)_f^0_$0SRd<-`G*oV1qarbE(h-2X2Wo$mZ# z5qxyQ;)iXV%S!jL+1>td?022y&TmEw&20W|mnm$Pc_^wO%(F=4arxex**wkCH-F?d zJZ-gM|1fz;)2fBjH7tS-9^bn#SHRUz#$k)$!3n~D*%cpH-hCfhy7Rb+mVmp=_Z=E3 zhR5%G=VhNG=Dy?NVL_#-6+0soZ%cVevbi3p*X@3san?q&S3{~rAi-9{KxV6hxOu@0 z{=V*)pPtsN+|s&Hod4Le83B6A7nshpid;xkkPvV%kq}|H7+Iltusw)b_3MRD`3ay7 ziHIEYuXv^o=9Y$({1BCk4}M+O)|<8VK#pE~k&*+Sve|T|qWed8xJ@cs^kU(KzdD?U zHYP~htv_*C$ziH0_gbBpnIik#_=Fc(IEm=rxo|>y%2`$+D=~%DcO;u92rF5A&|l;p zzejT(=YtOd;h^n0E9AKU-B%G~a|&f|Xq>V~qK4P8k%xJ&_aV`sD}s%^Imf5-HwkTM zS#2+F`{|?p;s39jW;>c5IJNhIoyuEvSq6_uj0a>_J^c9NXV8RmwXYa^^sA3DZdh@9 z3b#<6Y=p_-zH8hI&&k_Pnecq~422s97hYFOQnS7AQer_eW8YqhLV@48i;iBqSfj1O z$8Y6d5}dU7&T}I}zM|WQBh=@z^K{-gTlYnbssC~+hoJl_iQ49l+aIpouvn1dcH~X4 zxj<1zipUN#&hH-zPAEND@N@#_-I$aedZnTU*DVW^?mRfO_~(8eHGbd!KUQvkxWRwU zU3QVC-#rJ99r?xFnCvARx+hJ_(dOp2`ha8K?(*b*f4ks8+^QDK6L*Rm`@SA*V!18R z+{`em|DBSTEAs>y?&FD^Q4IwPBP`M++7#4ovok&X=#rpjz-K4fXu>xo1LV z$R9Kk-u#zmN9msWqsyL!gk?nR&~fGwj!Aj<#&?B4EBlu)ro$|p+xUI||FmXb*1!|; zCX%Nh$^KaXVVQk@HMt5>zFh*fzkgqiKI(5^*i`vF#3=dC?|ToYu_>tEv%l%|R^WN- zS;O;OSt*C-hkj%03;pcg-)azU8(H!8@ka&EMd9Cq4+nnQ-OJFmY{!FOzGXH0Z!c1` zeUQcz`*=}cxt{#X@2v)rOdo96e-=m>vo|!Hkz@XC^oyg;hew;?2ajYk6N3%=Pdm9U zrxx%o_z}R?oWd&Ia6kN?L*Zr@qxDma86TCl*9Vp)ZF+3bTfaHO;-bbpZN)_gq&=sL zGlp)xII*C>XX+WYOCc8{ohQg@x$r6I%wQ9h(~3Q+#@&;1LeepV$L3R8flLnz>!t%| z4Hnlr)|?Ys&XAbt*m0o!*ztMmxx>?m1YkRCn%PupsT=(z6RkWoOC;E&P+%x|#LPVd>mE2EGlSZ^-!lF>I>+8@h#kxt^H_y>zo_U;kg2{BkjiX&Y>k*pO z+XaSl2P{5+l$K@k*c4&N`s$;O?~)}__+QUILuCV>qz2bd4JGZ z=sBC+zYm94o;sN3e!QU&)W+sud3NKWiM$iGsDQdiw@aO+bMF}b-M_ot#8Y9f_zs^I zsfuJ)wx3ff)AkrPHEs_)6>x33T*bK`Ob;y1?Jz0`&Z%LPX|XDdTL1II=cXCDj1vRc z1MF5Q`AIM{6d1653RvR779z=9AtB(sgJr=UMgCtrl0gsB?uZ-|Vu+DY_``hV!yJM7 zk_!e?)-V@;Ow5?F!ZWyNV*)>$Y=ei44co>lt{E}nD~<*)>E5$zfdr3*4%gNPIU9c8 z;puWJN^<6&;ixRT;K7U?PFdfW=jhpqNt~QuG=<@)ml1Daq2!`tb1s@Z4v=}4BGF^G zW%iUbmIYRvN%2#(f5bAVNIz&=A#uWh)t${CVB1Y*;WCrDCp^BZMP(bNbqGD2BVzl% z$4%kkVugfTPofK^-(C29t=xATPGUyWIg&l$xrNs;u4BK93Sv(bAJ2&3t7bEZo7&rcpI=cT z`PKAAmQy5(Ocx0IZ`!)^>^ryFFWNXwWKI=7?2E4Z<=4xdaHzSDt%v{V|KE}dW|Q~%+%dKUUmnNgLuPyulk-~Q`?oiJFkfZl65MWaP#{6%WAT44u?Tj~ zznm-?H&j@H7>;o+zc1AOo@IkiqK+t=&FvXyPf1T`YqTm@dyc1Jj>UnBGfBSpnR8^F zwuvN^yUkzls3Go-LF@;aT}on-3pwlMi;q~;m`NP8pS|jm0Qd2Nh7+8h&wML&R<=2B z{$g|A@*}bneqPsGCR>oo%Kf{pM6!pUAz+${IO8YAFIGGpO70Dx7IuDEW>Uf4knu}v zR>CgfW+o2j5L>;PfC?ikkz;LFD+8( zow)FK3m&Mk$-a{leJ;m#{81e5Nx902ijZmTKjx8eOCaG;mv zrkIOqz(&#MtUk4EjmJ+OOn!afX5y#3c}k3jPv6+8prh#GsIWu9aFUmnxE$+o?Vk^0 z#Eu`m7bvS@^TDyBkMa0^k;B&y*1zp5$o_mmmQ_M)q3vP$$}^y3b3#do-J{~+b#B%z z7ExRU$*gi`Cxookiz!6t>dHyje1YMVQvub7xHm2G@>SYZ)pj;7>`<>6bF4?8%Y-FpR^k7<~f*WBsm zv_7;sK)vW(S4>xhUcPeoIH@)qZ7YgqwDoNOCNrv&cSxGP{ z%rIffk#+0&of5;7U;c1|FT>-#94R@%Qi5i$J}mQVso{MmSR`IrP`G_VYI31*hl@WPVUHNd$7OYXJU^C z@2>SWanB_TA|KC_aG1|2U$srn=0%S1ffq)c@s0@w;=5q0yVeuors9>Hbvz0s;^J*QytZc-w5uKFV|d=i6Y${}=i2$qyc=T8 zUtOtcvNS3<+)%LgVaI1q`8El)2#@>B@}L2o{h4htJPEVkelXnjzm3~K{y;=mA=}q8 ziOahhYt`pSIa+)?S9jpHZPPKa58DsdH%~6S) zY&E+_=5aO-5uVR>pcUpDqB)8ep7S;7C^53EzAe(OwY~3(Y*F6-e>N)2Y^lF$1pcn` z?X_k~MHJ002Bo;#m!GYB-h$$I#`*X4ON5B4715WsWDJwVW)VD@CA z4cyB2wA<%B+rD-0-1j+RhpuLJ<#&*Rp9AnMtzlTX1+{MT*4UZED}|9<@GdW}{PdCV9>?t0UX4 z+88z!Zcj+MRwFn2|G&;XhTrb9FGxPjA-r53)B^Z@?ZM%elLcqr8ZMVIXpoV({rl*G z?cE-Q=WcXew@E2|-NtAk?7z3~MCaDJq=)%eNm@49NW@#&M#C_kwvM_d$ItW7ePR`*ZAl`QCfnV(@Ba zSYWo`g=e=OpW=d+Gd~+MdhA_xsLx?#id$io@GGP+=5VM)+;+dX=Hnaf+cI)|MAt0XU3^$VW8PPp1s9T8x${;epWk2G@b^)Q;kzP< zL(cia?e7`S3yVeYRX^-6`}^V8=YMwc70E20^Sce3Hk{&oe0FXPPww`&?a6B8d((MD zcd_l{NL=t^t=lvs(H(Wav^5MK{7B`T?9BG)LtO7Yb&poda}f_-9yrE1{XR4Q_q~r& ztkyVuIK#Q2;BwP}toN)Bo;GbiaC~-oWn+(U?>>u&glv|_?6wp4H8&a^xO|(P$0JIy z;`+i4&gWg6Z2OMi5r5ahofV^_A@WV&dK-rbPrEYDfeEXx@|=-%O!Cl5ut=%b;Zsqo zlQ`(`J4HCJxUc8Zb*rfxd?YOjo>YFke$?-~>3goEW~J~W3+!s-n3ylB>`>_6-?jAT z2Y$9NRmTt0|DW@pY9mqp>hx6cU-lm#B)yJ6UdG9=1bHBHVl6y9W^&~QqPb%B1He}D$l<9W6`)ra44KYVcf_V>zlk{OSS zZ#i+sHf}h^C3ZL9*zG#Wd+a<_B6jsh-}59a$bI#~yT`zksYXUpwtm5*fZpD$wi_0W zEk0rjFSxhyy)-#&q5i?T<#x|m<|Pi*0ap%9`z65@Ve^F{{cn%4n3y7HJK;X9jHnMX z@1rMOILh+)ZBd@yBX@_x{LRhBcL_)wG~fLo(cI>5+d&gE&Z(Ul3D27=b}sCiESos< zZO1VYjYnz=9+j*YU9|OsiSh>}iD)T{fFnIS&&76fGAkVWTqm8fV55mwkM@ICYEKy+ z&G7O$cvP0PBi!H!%i|i>4v!zwr3@Cr5;}4}osAluADofdas9~cIXY_2Z9m(0m^78w zHC0=mCskDnZd(&PaIE<1XHtw zO6vYB`GRDY`s!=83^D>vGD1@st1>j#d`RGD3=PYK7@M!`nEz_8#u=&3)EmYdp8W1-JM!nPn*Tj^Hik!*Ety+6 z8auSO5^5L@D0VV`;NVb@vX%>7vB9hB^&TEuxfR_t`tq90?d{H+ANrWHFz~Tup66hY z;JMtOf2t+Jbs4xYmbjgNET6ScQs4G+>c6lM<6`RAC}N8e%IK)?T=y8_7I;Z zmakgdcOI5)=u+!xNm*a;_)4-uSj&%upWi=N1eZt2_VDOsq;RhNA7OWV*BsrBf@D^< z`ha8i>LliF>f^lMX5hc=kMT1;aYd2Z3n#vBOQ=2AyK8=^UiD!P;e6|yB=3v8ElXqqo~+MdmtxoRkW_YDY&gGX(Ke&&V%Tcl^v*=RDQ)fruo3aGV*}t>-*` z31<&Zo~Y9wSbe@tK$XX3e|+(3jdoUnFrB^O|I?yGv_4u)Q}xZ<-Y;EJ5v)>Kp>Xjc zgTWL5mW8i&e~9@Tzy66To6sM|11%~J!I$^TY1Y_@+)DT@;#gqA!l589@?LVW{ey3l z#I@NzC3wh-_ivNa|9W_Vxr)&hr6ZP0n6~sS^x<`Fih*3d5$E+n%=Beg3#r z^Wc&9MI6N}Yzu-5A_Df{*yT;z<@1$~4(V_Bo(B{fu!z;Wel8`%~E+ON^vu9GH^*;Slo`2e#5Laqk5= zgSQ^oU$Lf1=EE^Av%4;x!mNJH;3Vd|-t58LH!>L(S)hd`50dM_(-Tc^zH!}e%d zQG3Cr&L84?K_%I)b;25;4FhJkKPJ9z77^ind^Nt{?iq);={AOrF1Kw144>V1+W1nw zzq@^X^`tH(v)c2e%bm5i9N+Qb7?=O=1;KKM6=Y&!xXf1zP1Ov4ulMnXa~G4uCxZeJ zH^0UWv#0O8wZn>)&HZE145LOlU+aEf{prH(_EzFExDxW1oz}2fK1kr|Vfy?}iD%!3 z<;@T3Z*e5@Pcf43EVm6}Q#j-_Ir$Z1spE!aGuSv8cFwBt60#}&uG{2#A2BbC#nU$iySz{)%SUt#OM6${0on}I)3=QxS2zgZ|+@Yx!fO#+iLd< zG2M`6RybkItFWY`c76)4ee(YWb02o!PJbu0@!6qk^|zB{4suvYELfaBf5pbPe1{5d zv#)L7nb~~x|3B@7M`oH|Cm5bpR8}~`DxL6RXx@B`P0W7fHG-2QO z9e$7b_CBhf^L$I{!-6>HdrvG4S(#<^_n+73lMlP|JfVHk>lJ}q^CfH~9G2Gqz2GBX zd4Yo~@!%el75o)dR#`O?OA=rIt2J&}VSoRxEswH_ygKj3r&?91AFIBytlG|aT+zb& zq3?o|Rg>o}(PC#5t}>FBSk^Ri;RbGogL=#l>))xadU=9zr+&xr`=(P~^cY3h@h~QT zz8C5rko@t)DX!4!_8(T4!Yv-myw{@aE3{W@ZM2_u%Zc9VmyVm?aVLH_nqS2iVWe5# zceD6jLSoaxUgHv;{Jn2>Jhw1xn)~d9#6h3iDLl2$UnwjPKBKa$!jRGD=CcJK)+bJ1l539GXxG|mQj^u3#WeMx2P3yTA_7^0xN}pSh!75>qAZSqP*5AT= z;Aom(K|%5Mf80obMI-7KLYe+#tA z|0^$#OaSK&*-Kun_nCJI|Hx+f$FA&p$n}JTMdB5veL2CaIa?NP@MmK?WX7kEsLj** zl&RKPI`>EJ6e)4x4Fx)a3#wTg-8pCIu-rSlaKW9+H+XxiJcB|OsLypP(2;l)xLi4e z$C6{thf|yfN+iE@eklANdbnUqR)*ywaT^n+(*KJd_*Xm)xNz`y0&|HG=WKR{2fiO} zs5f4bDQ!w-Z8$KqCqPJ~^HCf3hPn*K2tM%xbMKfPJgT2|@GiUM7a8uhmKZ+!hyC0B zUTEjvn0a38n62l!f}Q+gM{UzpAKl76ETM5br+ZRUl}TZnL9@&*@y$!ZpM7=JmSIo5 zd}gW6&V%3@d*QpMtp*Qxv{u>tU9h6EOmpe?$aSHg14ElPt}Ol8Ke^SEsbG>S+m`SL zys!6*o)1a3pFVvOXZ(WWIu_DgsZ&2oiMo1u@;1G7FiWxGZki!2A#lY;D%9a_)z9=_KCT^7W?z6Y~ew-s|{vYOc+uyaXV|Z2{ICXlx#>?k7(k!oMeSUGx_ebA< zBL_(~hmiT{w~G$Tn*F`VV-S-3dy~z>pjpo?ax`iTo93In(BSQ^J}ja6`Cadl31^Iq z-~2D;Ik3#`(4ERnY{GW8KT0wy{-`}ykouFN_JKsq-WU{MNPo7wG;?2(JYmkKO- z!I&w-XCc{WQ@?*+X=oDTk##%@{*(W`+SoP6EP9b>(-X_{vhRxfGj_>nx6k{o=D)7 z?y&5kL)G*1M=$L^@@mStX2I#&%j86kF$q*uMr~zpSs&MQF(7T_j|UgaET1|5oHHYs zIYF!c%L4@y9?8Ff7a9bPJAXLoxyDRGiu2T-?^?EE7O&oiPvtmwn9ub}qqX4Ewh1#2 zpK?CVxclDI`{EK`o0(*^`R_gF-(yQ7`)&(8PnKJl;XJpeCQ9O4 zvyY_4v3a5!dc^m?^G57D4`H}o~e?{(%h!mDDj0a|&-@YRGw|#cSy3hSV7594LF05|OY27ay;C>lXZ=3^c*=po=Xb^B$HG4in)?kBr*!DNM3#*h1K#|wRx4P z%!f6HUOu-dkeB<;YNF!J!F5G^XMp2^(io;k|6MD;SH^{=AMD(?iDB7;8D5zWWPg7S zzgzzDQ8GiWpV2114}CT>XSqelx)$g}BwcUZFkzzNBu%N+ToV~u8Wbv3ltl9;cAiT3 z!L;YagA-hvZ+y#(IF_`}^L>xX@;kpDD<1T*@vS##J(p5>qT)qx+{3&51&IOvYxHH8Oe% zMQU4&*}45qq>|^D9T#X!;w+Y^@wk;=W4P`9M%zQ*Ex$1xu`p~Z-M;!#*TtqMeBygz z`*@qGnA_4;ev@GCC}%u0t!hO~i|xCjX6g48d(Q-@$w?W$R(w=?Xc1e&o^)|j=z<`uiw1& z)fS1KI`$nEO#Y19-oE&v>>iN8)b(M*sSoB{GZu!d`lJ*-HM9Aor%W`P{FmM$HuuW& zODqM9Kd|y2>GxXCaPs*5(1x?&AEox+&s11@<9N~>J6RruP=WM2+d1DIv8X%t?WFE` z-d#!0_vU^$##KIB`PGBH)eD(U2z~YOo~M%}vpGMw`p(g|gI<}L=XUcn9@!8+f#uAU z34a}K^JKo^(-7XAs_?EWB08bB>r7-(hb{jW0 zoN6$3*?4RJ2ZGeVnM3R zw+ni5E=w-GWcam~S+COSVdKSn(+Zs<+4#2@h;UC`)%tH=MVEny%ZixAmvkO}eEpSK z-Jox@^)(hKWG$xh4o3bM(;*w6-cZ(dWFE-P8m-d8xj!|ci zF$*sA6A99+_%8GCjqN-B)`g(49yW3N%^!AiR=3XE-lbvl-St@8Vd-kn&Lhx%v8$k+ zHOFojSJdb&w|som^wIgfYhN7N;?SEUZXP_z@Z8sTs&;GRr|>dMXuN(Fz9y2@#&FO5 z?t3D~nH%SKpACp@QPi7bSD`scxWypx!!-8pmf7EI3M9P3?Nq1#_2`ZhXg~E~$3DjS zKa9du8Io3)=hj87G0I?Sn&rr2#~~-@IETa3vmj02V1vRQZ+XVkb&mfVmp?z(xc1G;`5@4~CBg?_b{eeb#M; zv(V||tGZVkB^>e44^L`JI1$CZ^P7rN!-V|qhdZgOK2K@ z6$@r{epm5j&c}`>8J+68i^W{eZrHBx+!?+1(A#40nw(YQ+4r7j#Mwp9?dJBWSb3gD zAwV|w)ivXa+7q4UxMYNE{Ek={RcXt7^yrH)SmPwBr(^fvhB~WmQb2*8|c1KKj1)kZX*2zmC~=-nMI+ z%cH}6tYxeW_Z?}IdvIXGF)p*)3dwKx7u>0+d$8<62*XAN38n)o(g%LX|6IlMx@is< z^MeL{c7|OWD(e5#aIN^?-=MQYDlW;!>Cwkui;o_?-Y++UaYOHmCmY{4raon7N=Qfu z;C=4jak1<}M8L**Y!4#k%EUZd%RWX#tgmA3KhE8D*f6#2ut|#S9SMhX7KTl>+uudI zn!C&I+1s3J>H&%-@}m$eo*itB7w& zD(Gy&87en7Sx3EcKA+`$SVB`er?KDckKwjEM{eKy@MFiUiWsZ!e3P~^ZC~{J(tA*& z^%bbGQ9Z4OeS>_h!82CJ9^tclV+D?J-ubt1?R)k*);eZZoj+S-A7nTBcfMj1<(jwQ zm>8?#0^x>v2M_Fg%V1eh%C*DlV8zFWkLJCw43pws5NC0fyZX-WT-!&S+xMPjT`nWW zCEjq1OYHXi!1Q^q&lVqUKK!mK@zUymAMX?2vY9aY7&e@Xw%gqizQ^`yxO;xVo5+5i zR8cU9Kg!7nINZ&lLSYl3byLrAGSAWG9)^%c4 zaUBNMH!4pZ>DRokmw7Ow`f$&TQ!5_Nh+L@AoD`>J^)g_E*onf65fR&E)4tCY@SjzA zU6Ea%%h=-<2EW@^sx<>$IJ7mh+uA&bRcI@9mqmW9x=P zeYS_LWKX!}d}q;w=UmLZ)yLZ+YSUCwRCr9e7oMo_YPETJkmsf3W#@nuvcLWaAFz>P zNZOEP-+J_-=9!o4EhoF~QaAJ$;YkRsV?@JN=ggnRd?1kJxe8C$P>Xp=j* zLTb&_ZkGh<_O^umRt4V=rMDWy&ie2-=40{cdyEexI2aCJRMQF%z8fXLcxuh#z|9AJ zbpzrZ+ZM84oBsdjj2No}My!`?t_aQYLY()*>b41QJ^EJJ15{R+U53Z`&|5A%FT-IvG8O>#D z_?ejsE996Sb6>QO^@-AwDzt8zaiykW9@C1V{Ezn?T0(9l{S)N4FW;}A%73swmuZWt z_ZH=f;AFNfE&Ha+T}g0^*xWdC!7}b9_5*G5tJu%}f9I(8>r9L&!_WPH8&4>$TET1^ zz_a~8^8t+q!R!ei*?x{c)h7S3B*0E+fq@qLfd@fWtIcgLx410v`Wya! zRYv9Ao=F;O+49<4+~3A>CB>+PW_rB_D%oAt}c@SKEo7LB`SwP`K z;(BHMkn-nD6BNt0nsQua{PN&Ecg*`aTp4E@QrLfbRPg9d+`MRe&4XYq>&6cTTgo4D zvo4(8dwAiDGo~5Bc1#lHy1kH7f59NsoQI+_;BXExjq`fE^CEM{4bd-60DdJCuSnHLW!rOOo7WS zckknU3=h^knBj8s;*Qy8_vC1mJ_<3s%d*@!`OYDUXKyTCRxe#Aov=mXxkfwh7TpDp z`>StQ2j*8VI6C8D=;5;k7Z3J`@NRS45ZASyXO8$hMt`wuJ0dFD*Ce0YB{g$p^}Q$C zEYG%Sy|Yj>b(>?#b3}cK@cDUGigVf}k6UOsMI11+6z=b2deZB^C+LgAgD9R7V=m=@ z+MuS0()TX4i}Ja6SDkv2FVNMS{Die5P2_U;z9(r(VO8rb)tsO;yGrZjzkluOx!d_vg4O5}FUx{vm!0;Ho@PAbJ~*{A;Xo7brw^^WN!$={$g0E?TM0RP=l?;(vGkD5MczTX3e9TbE@k5@8QGoC7Zw472 zt_2PJv;W`cm|&whZ@uOWo;yr>9IXF;2fSbpdcn`lFvCErWnqTXp&u81A8^4a0@>4pw9{me5_-Z?So!})u z-jCY*4kd6fT;QAR*y+z|6rmETe7{0u^08h2B*UuO;?{8`Pl$Ed^qym1VTt^z@DuA4 z%cg6wsjcd6X>(a0#NOtR#VTiXtat0>=4TU3C#1ZK;P$Guc(9E9n6@1M!Oq;4R|mJ$ z@$5MLc>le&dh^Fk2D+MmO9SK?B7VmI<=vy%#4}x?{9lZH%Fc%zd*iP%KXTxUpOJi< z^Uw^7gEy=GOMUD7r`q`FS(C(6hoz#;6?+8S8)DU%xkLV6+?scG8Pg2ughK&rKi%7% zUoLU@AmG=`V#T~~*S}mfmBF*XtVNBHg;})GQ8!e)iD?7B z&;n!C11D;Dbf-GK+Z2?r%#lH2g@F63-!7|G^ag0;pYHy{w*Jq$-)~OOS;EympIK|d zj1PZy2KDF*g>u}OzaiON@{;X=qy(v^>sHPe^KbTUHxzhY5qP0cG?;PaggqSh84o&h zYaKQ{uPIBp_dWQ|2s7Z+lx{Pl3gp z$1Tk>BoD4`nmzMv&g5I3nlGCsoVXSIV3xTFkCxjpx&DISb6=*pTmCP&a`RVBhLTp9 zyv0XNF}~MM56&)8d>GMcc~0PL;)9dtLY@iFiR>(1xo)b(5rZXj%2reheCJEmXdi^Go&a^0ez5H&yByB2K)RI-|sB`K4*?mWSNVxA}Q_%kAJVXc9Qf z>B{GpjTH8pySYr)(r^F!I2X2?1(WdCQy_~F6#r;jq<_h)FltZ!KI`(H`zIh)?;J1P$B>A_~Vx+R2UgfUlCy0&&)J2LYR%`$s!*%LD8zDgmb4o(_9Z! z1hZUcK2V>;quP*Q!@^cKLzOe@n8VQnay$auEgMW27s&CnJZl#EGHbP*ZTL2$F9(_2 zr*tZ5Ok2sYV%LciA2=*_@Eh!W&m{8lf|*!Iu3Kuuk{uU{{vOz2_Eeqwe8(Xs_A3Gn zhZZiF;^?^fV1v2g^1~;);lK+I+)2xpqY?%LtS;Np~ zW5nfG4tldIdRI0GTBWfZYTtCnqEzhXp$r|7=Wco>x9j@_`hWcVZjshzzIv0enZ|mj zoEIma{YZ)_Q<9n+a!mH2(wXErPt3M)O;Tm7Ubw_6rtrqGGlzYRo=&*VrCB{o?(w68 z-G?PK=N}ijQ90p9)53EVGmlxmR_rg?QktpUQj*HL??UtjuI=+G!klHEt9r}iTzZ)> zSGaXzMW9%_g>cM=#ojV?f|idj9oKI2<9al!;^L`V?Fgn=#-mC{eAC<9D>+zlk6WIr zm}va2%1*9ejU%s**zp~SGY&S-(eg1W+GZKR!tutMf9HAORy{Ve*5^l}Ej$h!xsYO2 zT~ql=QJt}mOW?b$(-jlZF6ofcR}4#+-%(-lTKTH-VG~#NqP0op8?NZ{o-jOetB3iA z1AC3#t`>*C`~M%~N;I&D6R=z2^1J(B`@iP@u3mfNR2si7eEIaTI!4+SossdA#M zL}HF+cwWbrtUQ|+DeJ!Xtj_G-B6L8YFYN69mvi2kvP>cDgM#Ev z#hee3k1rSqu59=bz}&ZTddA*E<{R$3w7C$|<~E5h@$wEm&(y*s(;nN|whQM8Zu)t+ zOP8>?!M%3p_il3(9%?Q;ec`!HrB1<#8!OKj&uWvj zXvw*F>|V3BDZBfH?+VU72`ld`ua4lq9TQj()1AUCkh zeBdcBoU(;oPGrvuj)Pfg7aR1Q9~E6$cwpBnO*Vek7Xh;O0+=5>dC9@*v>+k0;i&2J zsR9y$9=7a^M>!YhyFK${kQ0-f$|0-o(a*#1p~7XQC-X{2v*iMF_)?<2%d$;eb7AXy zmH-zsVH+h@Hm0vRGW@2D3-(Q7%jaTZ@mE@5#P!hh9#21eqx6F9JTXPdJoi4-v$N+$ zXbBx++U>;eaA~1-Ls)I(cm5--1$C;N^`FK6UF_QUu3)|!!#@j6ww)gWA~w88QweqW z5dZxTmxUbjpFaV1tM6TYb@~r`$a)pY7*qbH0}6Z=r2?N8E!eVzA;9Q66K7*^BkK;4 zZmUOf&zl0I%VfJrk z2v}ip@?$g06d}gLiSv&bF+Gy}-mv)-Ypj1;el>%`#07G48X+M&8JyVfBrq=2<77#1 zb%=Fmb*o@vV_4oN)ZP%FdLjCHb8C);p2nONoSbqhqF3H=HlETlb75_2Hazg*I_nDy zeg0M%kvAMyBo;WvyqLvxPln@BddmS1lLUoyoVF ze~7O?%fw+K*s|l${{K&t9=I6se#rbA`oDRP+v)Sozc?1$=SVW~ykx)^`tm{6TC1hX zj2|l;yP{JYYgrWEEb?#kZCK6I?&ZPaG4;R$2S3TZ;(V^mjEx+7C45|*4|p&NYyb{_F&HTVY-k7p^^fu86Ci-gY$9hUF}iCMUCNEJ*l`Ea83==&6rNG`7G zdo`^#dEBSj4i_%IDC=^d;=w#V30dxj0QU=XU$TXmJlNB4LL=iw!Uqr0eSF&LybPBe zetfv?>h7>0Ot$!tWBR3Phl39uGFq%itLfEBZfWm4-+R65`bz(~{H#0Qv$uV>nm&W? zvD=4&69@M!+$p1B-pWvWM3|#exN@cXl-U)E<^mmadY-X4E%4M>U!b^n=ZSU!1Ewx5 z)&m_{qL&%|xiEbE?D|EN>w#ecYjcf&y{HWHD(=Qff7S*V{}WiX(<<#2PiC-`7ypYz zai{-JY*AG4T5u|qvyNGUYr_f22*t{T=w|Wh{VUA0T?|+KJsbJ`$^k_#8A+yqK*b4M zEDAp5%0?Q2p5ej$u1!e+VhcDIe(z$a&}BXQBmTpQdZv#Lr=R-&Y#xumApwJFYj&KT z6VLsh=iuWe0nR3WRs{nwu6Z&Hedl-@cZjmS>}a; zcAn>RXpsITZ^7s`L5*8nviR`KhNthU4=V68%-i5%CG~iZ_@a#ld{gYUiSEhaDEM%2 z_PrGrp$8id20JwIGCdb+;n@&T8owv$n*B?vUFTilYC3GNjXm^k0P$(i+`u#Zb0Uysc5w@OXj z!ZsiGKA1I4LZo4f_=N{e7D)tI_=Kq3!cAn$oI3zGxbb8}cnSi+aQL^1>G2IUgZ%%oU zRKK8wM@5`TfZem^PT2o2kk+3y z)mvaxem6Jryh?2=nzMPC|HD?l(7V?Xcik&r zSkAwvmha4o13CW%XQs~=ZkiDG=|Vu@vAZGjSrl3;0vLB+5R+lHzL(MS`=Y~#Ukn8y zMkTg#UmT5?3`7*QFHWduTCjkfY3}2L4-_2PgbuPCuwh|KxX<=S-dpvZEPF#!3G)G) zst>6SQYtezl%GbG)H5bF*dIudDaIJ za*{h*#%i*ynmux>b$W-N1HFSEI=nr4FUd+t{5 zJ&p<$O1z8*E{LqJ&XM60u0P+)+_p30%8LNj02xz0h9@?h2OSz8JmWaG@EBkF(U2U4 zNw#`gitD)BS=TlkZ=THL;m9g_$TL*r@g>f?ifnvs`HKzxY$VuaU&|ilXk;rm;5_S5 zgGJ!shmDVY1?C)1{4guwTUglKekJkom`erpD49c}9}sWs~lr(^$g&a&SN;x*p~ z-bh*d;Gflx+8;~RYa60=?0>R~-SyQDrGUhu4T&=H>i>87|KH$ZKTCwg{^Db~H;T+n z_dgXgDt+qhj|)pUc(_vMzUk9kz2tkD7az_jiO&3#yy(+P^#k5JbSqTUD;ya&Bp)iW zzV~4c^T)XFi`-nqPaTl(uVC$Ph-PA`h!@e~5oqi_xc@<`o|y;ewmySNJdCSa)3l2ZvXSmO7!R)e7t1a;l>p_7E4$T85(vNTF&17$Aw&8z$@PQ(0 z7~`s}06Bg}_6UcdH49qgm{@<=FMZG6@L#3Erog_TfT5rNGE3J13x)ir6&mab8`$(W z@K;DoTh*5M`43MEqehL*$EWTgVlP+e>h*1X$iwZ>dECQI_K6}p&mm1lhL?vKq?Egu z6WBK>3o!`Q%-~=wZWol$adJ2xaA4&@5sel;i>Fo=l_y+3zb|xfcyH(GSkoh}vUuj) zgsFng7kT(t94cJIS6r0V&=YiLKcLj7*yZxTOjMMs{Xo@@P~Pmomr_ZJMkyCJtXUw! z|GoLZx)RZr!v!*Dbd;DB3!@zVsPQj8b=sG;-$AE9gWHa)Sz$#0f5RaWhI745jqX;n z`}rF(%smzPrTtze-Mn@nqQ>Qz+g{xa&2P$y1`GI%bX_=lCeB%LWEW%Ciw8$)3}Bvdbni8MNhT3-!%(|R_<%k`xzm0WWjPV{`WOmPiOE9MIVj)@Hki0nTWTBY>R{^UK6L@!w<5rMq|Q7@W4EpBQqaADjz@lJt#V?*HC7gyw% zSPT+%q^3U&QFSs%aAf;oFqKJYso-XXdp}HqrW))M@1NRnK>Oc5GyccSjNOMM9Q0Pb zT&N=>N;3Y?UD}#lC z5oeR)^;X6X?jw#I3>yyI<9Mb$=YxmFqX`E%SvB+yMJRFY;&aG+$H^&|&0)?J_aTN^yy)O&wa0+#$Bm0ZD?AJj6m%5M zFnqXCxv#lHh>N*N!9J#d$@jf9k7sMik~Kws-*^-{rm!n%#Q3ncZ7$H@x;~?X+b~1# zg~5{|1tG4(igG=NjheVBVps%ZnGV0xXl~r1c~Xu;J$#8y$HqnuwsIvdLDfq z1GpF^-*Yjz^HekFtYAHKEMJIWg^bc3k%l&b>h=#(EsX-)SGImq`kRrmGTQ6lq?*LH z7Be~@{3{iDaq8}Ni4*dZICYqgdh|(|IsCWyClRH3^5dlj{nOiC2MK4$n(9w$J>a{= zS4KJB^DKW?i^JAa`xiZDQ%>YbIv`=CIPYSDl0<`ww5wf@+qswqV;%=H*7SQ?A`3pm zaWp7|aJX9^{h(#Qevrjmi2Xp@I;YaQsj(;dnh(@_fzG22+0A`GN3p+q)h^Gc^)~WX z*&BX`NH8;4?2uy7IC!9ff9*d3Kjs5p9urz4>D|6-p^?q?Y0tYOZ8E)230^RYlpP^uq>elDYKlm6Pt(wAgkU?VKKdr!L zx3~{ZUCr>*hKF5Q=_wKck$%F0p;ZL6obp%)zemEPTar*9$ zl@SK1UwInbZu!|aMyRf^Vc}D_;I-;X@PSh;4UNZ{SrqbF6m0BT+M5_A#4NJ#*8jWZ z#toLxIW;Q-SY)akcz8J+d%iSX;b-wGnp081zWs-Xc6g$Co}6*g}a6D~e@)W;hq;mA^a{J=VK3%-U~CAYK|{4kZUm=o3^<9W!y zN9hG`j=ku7!K;^R4C+6Fi zHtg5<_6RYxHGMh3-TB^kMu6eWg){VJoH+dwLU=Tom>WwH7z}4L9XD9Ox~#&!ODCK? zR3W{$WVY)SCQU;P`xyysE5zl6vKsGYK4|k=D!N4VHQ4Kl3krbi6^F5$X_i;|8L%L&#w7vX@p$J>TgH;R)6kq zstD&WVP>$a^e_|ueC>jz5Ay+sB7uVs><_arID8GW|Dz+b`_$DRJ9z)gtgE^xA@Rb# zm2IL)%|7vl)NOB9E-+}T*x@bIeQ@fX59aK*=9%g1hb`i`R;w`Ab!(3@`-ejel~qff z!nu!>++`DQ7T0DAQn`On`A+N-hU4ysZ!X?+VN3l3exX?txR*)g%1sKq;`gDRN3m$r zM;*nLzjoa))Ng70vgf~F6H9pRVdf7l+*9R>=FegO;K;pb|LP|n&PeQ0^yl9;?Uq)! zQvZjn`2UkbW1+4_Bj%Ma)l=?4=y;e zpij8ziy+Sd3l9M?CIuJq6-^hyCQR_qV3U1#kVSBZ9P__cq$fBH5o^exJM+o8$UB#_zLDPW74ml5GCi#ligXgTaga zM-Q*n`*Fze`;w1k9hX-#%UFi43bGHMy1j9#i}H`7j0w!4oQw>L;*9&22?wf3c}&pL8uUIq zv`h2*o^Q+yht>xB70mgN^07lhuC;-uq(HG*-(niKK*I;EuiOk;FIgK7EMR?jJg9jQ zx1*zj?B3Q*r@5-{M7F7mTF5Z0un=9wl@Zf>kmuBQJ}0Kl%yQqG6vUb5h<3<*jBcF3 z%PhX5C}!yc-N%{@$&CSrk-=t!HX;PRluGOv#*DM5@??u%o90+STI39B;^>j(#U~}A{5Y@pPHMPLaI8KOz!;h6UuCp z(E%5wm^F8PqAw8V~e#yoFYU?X;3tE;!*#6RvXb_dgwE*|eZGQ&^*QPueV|JFqfqe)*K zIXvX<^PhhEd@BF4TmL58>|klqYN}aVcg8nb*Qmsi>7t{7oUMemix{Jmfi#PP{vJi9 zh2gCX)q8|Eu0%ODTP$GHOUP8wTj(NMaQ29U0nay1PVrSc0vjh3#yZ}0NfnY*RAfnx zIbZN&rjNIk2wTd_ps9=pF5kN$mGGb=$ZA1f)zoIjpr(b69-#^)$C{Y0M1OB-&}4bf z+F&5_*-uvSz?IgH=}IdSq9&}!N<7)LVMaidR<%X|qa~wFh&H1(L-WA}XM8?PSbfF7 zu$8N+wej>ab;d&uf@cgOel{v_3o}$1EL_iVI3bapK{Mfn;eyBRO)N(qH3qmCBp-AT z?>eX;VJO%LzA<1ojxSKj`oy|J^1kpV>Wqh7RC=6p)Gde zw^q7jf7!XqN{xlVA!MCEXIxmk_YH=oKcR{m_Kh532W;(D>D~6WE3Q&XFg(Adg1P(u z!%w?Uu~#oYtlrEZ=ve#nf|Kn@rbLf~03MrHj_W4Oyd)s$%FnLk=#a?4BYlvA>(F{l ziF39K4j$mwKJDP3(Cqi&hqWy0!^2IA=eBn;bgd5X5^7$(LO({Jd3RG$#P=N?7q2BI zGZoE!%-F{ILXnxnQ(A$QnUyu8=^2MZbcF_!x{lxO#sL2EwGN9KS17Svh!te?Q0fig z_Xy!+7JSC$VB;cjU9yMGNFql~?LrL45`Qi0dlHNd8=ttjA9An|XZX^z&6S0#J&{3d z(Z-JsLF#=g@)*NyD_9eb%yyb^_R#?aiDQ*pb~-kQU+5KZ=a*zy@>KTM0gIj$T+8=r zX*>{FXkKt;1sn6;2M-iH-}5^x;<_*)F#Dhb_kpJmCa^VqZ%NRL_}%1?Hyv_{HOkc%$ zSd?1l@bTzZqzELOQRZUft!!LBgNsA0$dtw4`VPeo?zjhmnvDVhPrO1LW7S-|imvD$ zls=*mBA8O)q1l>v;Vfh6m4nU)e`u&PHhVjk@g1Dp%qU~*B30ZF-ksEN%Y$(@MO`KP(}srLrEMf1szxPrOi-omePpp`Qz!&t4o&A1+S6`dXX>8a%`|q;R(HeQ-ncV9EEE28ZL9 z*a|MNuKUGjCeW}XeTf#gBZtL%t^+=DJ56pyaZhh$*xtVI3+tZOEeavaw2w4IIL(pC zQDT-**`bhN!V{vB@Mh^V*DsZ3%lS z4Ei7F$#5^Qo>P5Cf??r&4uysHI23f)Y+D@#3Sypktm@)OZdEq?-pS!5^(Deor;$UP zV~+tlf5nS*R;A{ir4R0eHBMNl7|5ic#x-Y(gCpO176J9W8p#aNOBTFgzFK|nOIK*q zho>B^GII`?@kz)E`AG;jd}g?Pq^a2_u8XHR;d#@G1iqzgdldy@xEK~3YH4~^;uqp@ zX3+s2Cf^D#pPbKUd27U{{Fb=5@_|>MlX_Fe20mqhj1LDmBp*)TdhmR5>w(aFA4>V> z2r_)Fa`HHMm`TAPy+uKRvH1+cig{8TZ2lFVOximiaSG`5%ZV!On0S)aEtSPt^1%ew zjxX&30uAj|4pLl`7M^5z7|Jcc)7Y`{B7ai@N1mXgB6HC<+lPO|cDyif&<|7TjLi)( z6KH8v4Vccy-|)ZSVr{_;R%Ln!1agq0Kx}+w%g^4kN+j)UrV+ALJvHwDLJC25^_gqX&1#uH4 z?#c2vRv!vG5U?UG;hpFKX|Ek&VR~xLwoimv=Y?>ywmnujBg@fWq0PE>nV8WN0k(Xe zg9oJ9^*q8(ZU|tVd*F%b`3fgT>nY(54L5>!ggz8865%*F!-;93T!(|ffh3y**2`B! zIk??inFCo4ns^*haFKm@!=U<$Mzec|LlaA$i^Yl-w}gZnK>@!Q9-J^{XV5$^$k@uF zFw;n3!Qvk>EKbd~EFEX;_!*fvOoc={y$(8Yh*U;~C34A9Qt@-_!<9kILWVOJJ80%&N8jx?fHNtMb*%0Mf2Gknzl$r zIDMG@+a-Sz^8v?cpo=o^HFGL_5RjU_LOii+t&cDGYB>vIQeaqiYKX!`8pRGZK+2x7S zq>1d+C!$Y8Hz{yBOh^%M=(6tcd+>n8c<;jnmT_Mb7wni|p!cNdLZ*P*BY}wMg9eXw z9ug2d#c{Ms;Zk#h(sI9+3k~n*RW~X;X#1Sdlf$QJRl}~vt|qWyb3czN``(8Fa^;J- z&P}qnb;bUEuJVl(%MM+y&<-xOy2UNLM_-ODwT$0OavTwAc;0@Pw_A1TqVls6IyWqSn6RYpdGNl{HSSx(4Hb5gFwREz z>RT)sbF?^ISkG}ZwZ?I>`_FUH5D(apc|}CvxG)RHy)P3i0z}ex2sm>+37YWXN=_d~ zA9I@{2eAy1+(_PWaCZ<;ZkDf>F_bJX86E;jz6Ezf0ji(!-N>-gFFhI%DZ?Z z`wz+Jf4PwSkTZhqkH|#l#;G;Tl^3RX1V7e#-2P#KAWH*x7~|5Xr@cUH_5u?Ba5(>G zyy|+`p@KumafRdGIik%69PI?0IP1?h^EXLM%V9p<0BUbN@~p67;Z^t`AiL_{kDcx} zR;_%%|0RT%u|593)V&;KhNB4|rJ4`?ws zOki)^#b}eu`88|dg*N+dJgU0qH5DyS8l02e@btvJ@3R;-r0;EROpK5SNd5Bo&;rBE zlb04oIo}kKiC`+Y^x{Ga=YitD9Q(#2+BNY;pHn-Y&x&VxNwgK)5GgdX^tHYxqA)> zu*prB+@zpke36}9kU_*hA&iS5Lad^KHLQ>Sia?05yw4>rw;w$djpDn+4ZbyXci0M- zH+|gUBE^?bxGPLTM8f(K=L8XsC_XzWh9>E_FLO*fj(j>S{LhfB*&>bmz?SAC8r)nL zEH$kU2}(X>Ia=_eSmVIF4}J@Fu{bjErQ`_AaC2N=>0IO(aN^L3od-F@wHpnUS8Q}r zV+e>(2oZA$3}mS&VPW9rY3X0ZF!5)BlfFK4T#!pW3q$pRQ&<0Z-I=q@@qt1#!(aU= zKg^GRznJNi3I`$fA&;Y zhV(MAKR?)+Sk>C*d{&+R1#j~Khc;eEzQzSy>EuMkhWr1awCI6o~+REX9s`C zu$-TKcyr_2h9C8RuQLS*F*ru;Y@B^afnh_~Cx_}woXrz86cE57Y_>Fta%Fbut!c^>I0y@6cd#U*fPyLrBs3kPuhgG;U>H7Y!i} z4V}u5u1$*!XDK!^Cp1Lg`{I}*#E>q@)F5_`qalRz>`F($#+MSVtPi#boa<0hFkn9T zo|7R%s^@r$Llo z31qeal+Wp{WOuNWjIxroj&VNc)V$i(@*Ls>*4y(OUL_n`&y z)hD9QOCPNG$-x)rbg!4OL0G+YCBw#v9J3Cr&{@LGbI zZolPOsrhJ6+$x5Mi7f3lmJBY;`{b%5B zf%(>E{c!Kfrg zNqLtBpQ|57JFC8H&w)1*3~l@xk~3K5#kugkaQS7yo^bVe&sS02 z({UVX?reweeP48@LwZF4M;4E+)q;fQ9E+s5*&Jd-`}kEEk22_S1wUm7wb>!d^}gl3T=Kc~fpe)Ebs1h6JW570Qg;_q6YQ$u8u|EN&ytkYarAOG83!Lk1K7 zgNz3P3^s}^hPN6&7=2+9Z8lk@#isUQ%Bnw}4M!RlPP_G|&7=LnlByX?u6)?TZ~wpd zpR?l3Ka!mGEc~2Vv*lDxH%9!7k>{*C-MoIoI@Jg7W`1vy{W?LML5_z@)G4yygEy1Y z#5+e<73)r5+o05t`uWxAJ#idS6XtnqyRB_+{KL;M_q!aA%J~ZKIp%U}r1-Dw*|Y0# z;Ddjx9}@VRU#PCK5IC|mUe8RWnbVQ&0SohidM6bYg$ntfN&OohWW}rycqSRLM&dys z;|)8{_)oLjbA`X$Zu5$ry1s^Xe6iV=L9-PU+uzkXV^VQr!rY<}$8oSLz z4koA^W(?2Lg`9J0@H> zDUh-16nB%0!hzHmTbdZ6Pb92R`@V?FUFi_t9w~+r_jL&#h74ljZ9$w}CltgF2E?al zK4*5+kq~eaFj`q*%f|EVXUJ`TIrgu||1&pi{`%>#Km~{7RptZrWvZQutV`ugR(OST zU-e(lKV3`y$3A8m{e3q4OG5(#U+Zgx#1(&$c#y{b`nJIfg-(b2VJh|eWX;?^a0aD6 zThHP6$MRtJ!4)P94-)m5GaT3+DEwaVDXZ*yK9{Bg>yXxz@AG|7ZO6EB{VwUO2?Z z{Cuy&5-AIXMQo0p5}nG6q&fqc9v-ZIp~vZXMoz5y-lKN^#k_2X&UYO=Cdl-wv8SO! znK7B=c=bir13OyxC^AZDd}-{k5fO;s%YATWf#tah6(&aZNz#RloCZy99X@ix+^nxJ zJ@q{(Qnd3#$3ayC{z4Ys&X*~QOakfc&IT@0R!s(5HXQlBLUKwgOM}?l0~c7_SRXWU zaWqcgydvIjz#%F*gK_2;$A%4MOn?5fS*#IVzH)khcQ8v>Q&swz3tH98A_o%#9QBVK zy70rnZRJgFjp9r4tzRN)c#;-6JP|%v)uAk^qxhkn@vg@w$K8#Gr}i-|5LtbXt6{}^ zfsTU%6JzXu`H~R z{vOTE?qz+$*(xQAvs>fxQO!d~yc*UxGjlo|iZE~r5qS1^f!XuVZ}kF1e*X)4@Q>jK zvt#=LiS>tn6$pqhzABMp{w=^SUm4lZCUB(FY!YYkM@4tvqh4p2f2eR2d_F#Pk)jS0 zzm5EXDcYsqJstF~BrbW*_;X9OspXrvmMISmFVyqZb0%{7vY5u`v!r)&*(voL*?YY? zQ2X#h^#`pV%%f@on+z_!n=O4HiB&;@A;5|!X|?FDK*s+z-zPFCh*(H)SzkJFuyDfm z4V=tt6nF#~0}9TFFywIG<6_%WXUVl-om$1h2}Q>Gc8W$j7NosWWI7Nax=LY^iWX;+ zfD})`2F(Nim=`fb9#pVy?rFaCP>;ze$-L>qqCM~9K06$Ee<&etdlB>EXi@Z}RsaZ*Tm= zbvz`djUoR9_Q}mN(!aAgCM=#?;lw)eID^Q&&rHngJ#@OjhHjObo4^reCPBvROHcK91plZk=;P7hIm0X}#hln8 zy2Z;lAu*!yutTsz;qn#--vo;_1|e+BF)B=lcW4_feBRHJl6vvN#9R8wEQtcIK6uCn zFt@Wfe&{f*WxafG!;9~G9vHT)cUf@IL4fs$@j(G`&N&>;%=5S!;&^w>>6w$D*s-2f zL87_Y_`m@cg{Y4j+D?2GE-VvYG?fHcG8;rkxY(3(8#suwDOd=x`e$%2;&$q2oRH0& zU~_|Keky0f2_45TQtnnejMuYY$IFmhg`yz&Wg<+(E;;fTb<1@z13X zsmg}0Hk?q@E^v|yI2R@P@xZ_2W;Tbz53+bvIT=nJ>Hksxvc7rwlS#5d_Uk`Zmi*}F zwd(B( z1RQ&q1Lfpp`PoC7gXgd{=<->7X%OQSWZqy{ASc99zR2K3;|zTdHRcCRDHVV+#?~IxqVIIQz+%=KKIO`$2Q9*j19l|y-tG;|P~%## zVD}B~RE7sJGP{aORtB-2>Ck6=D8Obonc;(-JcrW(fzQvK1kZgE5aq56U|6v8_#~#5 zZwfD(E<_!2OlmMlUdhGQ;h@9A!hMnH@ro#p#~aKH3y%Bmd+;OXbo(QR2IYiRO))(4 zB>Ru{)tWCf{Jf5xHExwOYqH&k71{4+Rs7?c!ONh)!?=)#d7s@+1-1qU8}^S6c|+tI z0t_7Gr}NuYD6ZCHX#BL`Oub?ALmno^2lgk~8aZ~<#isueXMRwBh@bKA4m%d+MIOJH zWkY`z$RA-z)Q!Iqpc{Frpl+#0Px+F^Pm>qaSTO!yvd@J7?HP7L=bKpsKlRRKv$FfNl+#!1YuJ*m^D8WuHU8mp+9z~~eQMw1 zS^-X%70dYclP_X=dM&{Ljz z^OKd})k*VH=07=nNJVtgz7FlgDGLfb6ePa%N*sK^bwj98LLx-L<^y+ghabzc=!CUJ z1|bSY^Q>eT7DzGQ<6;P5I`FJx68Av~MP|VVi&z(I+j*dk<-x{xDvbs%r4JskY7~BO z643a@;dDqrAfKg~Pg_xPhd|@;f&&hXl8-n79W7kna6K}3Sg@kj;6tLJik)Qh#p4wg z0VT%lha`He#WL1Dcu{O3$SibKVnIfC`yx>e<>ns^A?yBs-!%7Vq4GUd{-=Tu_o}b6 zZ%|-#u-K*fz4MT0$QC<+sTHU83H*FG!@kMk{YCu;A~9c%T{biqdjC`X!9QJNv8h-0=2!lIB>k7$JE}!lv02Zv;eWidz(A2- zYpS!u2~gX0nt=WJiw=$q_g$Sgq2L{2JrWRSTJVJDj$DU?lERM8q#dktq?gGAaO^N- zICHYm@+B){LZE?q@g;6nfgUcObu3BCJ?14ecTHqn#&LvArb2_^rynoF=Ee)^tPk`Z z6S(w?9G++#ber1FQslV6gXy5$gg9#<*7nj39RVhSYrmd|6XKehB+|5LiIhV}icf&3 zTG0XKqsb=Cef(UjXH@Nd_<<{>pYc3ro8f|jgGNG(i%pzdc-RVj6Jl8uV%(PmD~TAW zXnmYeDS0HJiBs~x1Xdm`FV#6MBKNo$Hmyv2@Z-$k8*?%$WIHxLuc>P*eDJIPE3>NX z4W-%a2mYU_e_*!i=v^P?z{4Nn>yKYP(aOZ}@s1F~1}O$HyYR=V_rlXB^E^MjO{Q`7 z!9VK+ywCmHQU5fd_E5kyTh=wfM-?Ze@joz?kz@W{(8AC7&#Il7|6r4ZX$Xhb$^|?^ z`&R4>)G#cVCh&)mp+@okZ~3kzJO}@keD;RM9*O$@oOb)$4n9yw zWj+*G-q(D<;a{A<>8;Lr)nG#^f1{DTz$twih-qJ@}%0hmRp9e2*YQ(t3f09wE(p9X^UJjY8cjx(BAPa?5?? zXlj_`B)}#4qUC_u1pbywT#N|{6NL6O$?(_;HEA=iRJX|BXlz(HLE{LYD9dt|7lJAY zN1PaTiYSB_sEf$w=%{gU``Jhf&NCNpOZd>n>#rxzl$5wiD0!8S!-Rm{mlV{DJj9nY zv~YDj5)kDmiZBpp`0$)Xh*c)RG0#JHCvZG_z(Vxwu`99QeC%F^8ZzqDN|)d%&eOngjf?YRDvGf{P=0VYvI$knfmJ& zzp1dF$9VYD(}fKc9HI`kUIjdpJqPD z;hiVj`fuL*X$o=-^?yXBi_3&ZU1$Cw-p0&-q)}&QOhO8ez}1Gtfe7eFn!jS5nK z0}Qu1a!7bKq)BvjUp4vvXZNoH`2$Ntnz&lypXO{eIO8GYxcAvjO$#0sPKLuD>{9jy zOk28f#S|-jwY>}r>iHhX@U}h*f7R@IPrlc2>d`p;f@!KvEO|~5>@D#oZq~gv@*>Oc zuUg;R^i^R8ZxXqJu)rSiIIRj74INSK2*FF72N!e**uH3X;bBnW zROgt)-J`=8y{hwwVuYdq&z)|jD~<(OO&1nC3~KOw(X@=+LBsu)&dY@lI`g{!FPIc@ zI_Zhu!UHS5w;fo|*Yxov`-&R21@DS1Y6mUrHgLCM)M8%0gN}>WH z3~MZU7VP&IC*oQiE2^m>^v9sMW`(8Q(`Z53T_;;?|XM(ZFj(vLsroPc{ zSSfD%;D)o-oEy$z+-qli3FuK_SjXM8at6Emj(P*80~`#>Umw4Ja5lF6`2CWfmk<15 zZpg3`VR*IA?rXy_tAgoQ5By_&@F0Ol=-}RCZ7)IB@FnWY_3yLVqO+Wlp^mZj@P|Df zKMM_}Gw8@4uqmkEkUPY(Kd#l`gMiUp9SP-xJvv3v>&dwka_?^;d1EICzr9A!33)w~9!+kohtx8Qv3f zjg*X^G%~iY;&5tl2q~Npz_cLdLz;!O?YV#gF{Xf^4jrR|1$yi&qQp2_1PY2TaWW<< z@fGTc^K!H4Pfcd6!p{+q+xXyR=dk z9iQC%*v)7$|9mqkmh>Gj47OiLp7Oy!pq=@_%Mu~}O3ehz@*Ns7=Q&%I=cIUuFKu{y z%uS?%eG`L*7Q>k@8OE*?1q>IlUuxZ}@OeVRf#?$fW}gIvS>rewWF%iSJv_w0!+gh? z<>Y&T=4QtLoeBeHKaTSX6D@_6n^>9@JVcone0ko%xS`jvPx9Y}2W1h)k&?~}zc;VY zT42xEn{dL|MS;VkamI?aOI#PE8y9SEx>aLbV9(6J&$G{kr=*|Rpq|}kfqLwW6Hj^+ zPlyB;{IGB9l>eyUAm?yKafQ0j!3{G+TpE7F|84#u_~0OCXwn?^hK47e9D?z^3PeM;_Az_Ne}tBN;Gd`9TkbhN7KEb!3@OJ?N3V z|8v3#`Gc=Ow>mQ1Fxyb0$Rem9QK4**<0;hm!2Wb-f}DJj(Xp<^{a@oaYSs1k>FLi} zad+}R!5DBe;ndWFKOA=OPrjQL& zfd^9}Tjp+wNCiQ5o)hj>3Xjbrgk_zw~_B?G^>u2e0#0;_mhSj_utog`vm*59cubm zE#)oK5h56vFqw_Rj*Wv&bn@IP$Ho>17G{MGP5uK+2Y43<#C}LP{b1MfFGlPaDp;?s zY}m5pV`)Huhidlg#y@PT{}0X);65brXGf_eV}?NfpAQYHjdu@Bz9!7zV81R#h5zrT zKUe;m@i0FAV8h|1*ucZ^AnAR_lLd!=sA_~P{JO*1G*^xNgYpg=9_9xJ7PCtH*ZXSZ zgqvBUcvKH$7qu~bkiXKzFlE`PhblXR7X3T0W!LKe z3*OxL$9Z52b5g_~1#Py16n@4(HzuqMV4v=_yYYejQX$6&3Z^r73YcFwJ!^A*&zWPZ z*r+fkh12Ocn}S?xL-C;|Zl-4u>on9)75P&umpg{CVb|S1J~G$o||Y^5P#er|Rzo#~7^dvt2C=5O$XfROxv&&*nT@0i058j3q`~h;zUkzFqpC0{}BXPin{l)%Yi@sk}kYoO{ zD~2aUj``Pyga#hQefqx>6KvRjJ_;}miJx%7Xla7%e_2k)7M?j17B)8&%d|H(FgvjD zOyTJ=2oVwPnUV0Qp`yU@!7pvz0~wZ$g$sO(v>vn+*@z17eHg-~QhZNoftWTN?HzIVrP8kvMIlMqO0pwg%u{60{xW-Y~Q=G zdFb$PIK-UuDSpV*aJ*!GqxMZE7H5`}LkhMX%n9wL{5It*3o>H&FdlA<+A7Vq%%ADe zHSX0b^c>%GemUseY;Ggn@8#$}_h&;A*E^nL2W1Xc$E}QZ3EzIf*i%qp?V*N-jt4J{ zKO20AO<$Yg^I#^6U>t|SC!1y5T($>i)Uz{27%f!!VZ*|y`t^Z?YIoxU1^e)~DhvSoUF#oBe7tD$fq(4G2lwzZ|F=IR%XGy_s#z<{E^OYh z4=+qu72!~jaf(j#(fa6{ZO~!;n+gTQ>$2}=vKKXElGfU}tPKP*& z%7-l64Id8*a50>G%p2OE1DXF5-JkfSRGhw4}D_wN2Cr-(Gu}+@q50hwQ=4FVeXJujz=917Fcl2{K3j> zsGi;5e6VHXX60ySgFK&_sm~Z!DBdeQ^uY9-=+(}?JsB*=W#3xVHr?cS&vr!ny>|=O z5yy#B+(TO06yCEtFgwUU;ONR0UdkAFp`O`O@%@1_Mupdzf9N^A{N<$j!+YZ*=b%q> z0+Y8NKlrCrzLSyvQTVS6Ip*K@nOOwC&ePMgP!0O32s$n&>t)67$M@}7HgE)~I&iap z=;LSnt1*qk?Bdf31GW~?SlPgUX*^s~>l!=@4A`0(Dhm{ts~;R#uHSH+N#c*EUOKHkhwG{K1@p@p;IgZ$&^(<}IE>Xgz&?`_jz``)thqi$r4U>rxC zobJLodcP)>G&Ou_EIH8oqTvVYB<{mPY&rrBE9Xgwvc8(bbKpQx5;LD}&W4B%amHj1 zg~r2{9o((VEO8tSx~%@XoO|E1D9(LjBgjzU-jpElzDhC8BSepnVL{UqMlZ(`6R&i- zdsttbBXBf*hito0*TIGe?g|TqEv$bw#7&YEh~x9@;PRaJ!HLPpM!caZyy-*8CkH)0 zCF_f9Jcr*fY$9@w`VHT~AE zd2m6h)A>W9=tAx5TX-%QaUEs>(kUP;;+^Gqdx-sk|zOaYyebu-^L7_vuNH0i1 z+F2n%p+KLHG0|UvML}J=`Ji*3-CPz0jlB{9B7!eAX!dZ=_dk4yvoVP!j>AER^<02? zI$t=emSBXu#Yuppgmtv!(s77Hl~DS zTx{|@8z1~&c^(_d`M_wM&_5~mLsH$g|L&{4aQ~yQKaVjY>|sL>g9Gc%iHZkeEaP&f zD#$Y|a50t>V&%T$>&oo-z@AI4=9AVE3GW+kcp9%A>Cogfa7bLhm%+&JV2?z@9?30!G|M^6IQvNhc@T*}!gsNo~d^e=JplphI9$EznZH}){3Xg>JGSM5?TH)!IbnLDE# zcBHc}eztWPUtom2Y35DKg&Obgh{hk*naiRW`C_L84|nrJ=A+9+wir*EU)0?2Q0@_z z!C_A&i=+j%uV=b4&yj5S(6UkJL|1FzofO?Kr`_Z_UrY_$=`nlWjg+m4i+XxqGB!?W zXEs%s`jCV3;QE9FF_!~doFrrdoT?cdB18l}S}7`@Vi#ak5oqfAuz;P}Pf5z*LBB)v z3F}6OPS>Z!dqTc1DiaZwFnFaAB*L(s!`Zq?K+xgit3I{|a}_Qx7i3WuJh6L@`Q8Iu z-UiF}K5S5&(=93xQ{tGQVZah9UKnsxgz2Hcf-M5QoA(+xI@wI{=-7FQEwPMIg@3u$ z>>||(q7GtKQ+GbulziYtaYct#@l^?yrWL!FFrVXck~}ZPxSdOW(ktZ&ZY&KG4qt4XEvVAd z$&#ozL#K;JB21#KAa0MMA0el3X7nJ07bmxp6ct)Nm0vugDVDy_k!| z;Q+&jjI{!6EEBl}G??_XHnGl7VoNAc5D2)g!ZSfw@ZfQ#BTa{vvb%|T#0Ih+c;Liz zq`0+@Q%CWFhY6>P`yPQa!qpcO4!L$VJ(Rt&LPuAPqgDH2AWK7G*TSE+O%ECb8X6=% ziHKElfNI*tW7T)W6%NhgP>7THBp|rw@!t0dX`jUWG=zvf?i(x1~# z@Q7byqJ#a8YX_yRm&w`xctB3Ui+-c+C0I(gYfstY;`JW_|HQVD{k$0w+FY`8;gU(3KE9 zzJaNUA(N$1+E=!kS)ovs=}5>T4zaeThPV$I%+2#^q|aOu-7-BcMuqXJ3HQGvQ)AcF zd|bfE{*-_Es;mRX2U5Jby{~Eo@dP#;dAv|HXs@hFjVk*m1BF#yEKIvpPddElv6(G$ zQ%@#r?Y2KG+qm~E^y>co_wK7Zhs9U61qGb2WC)(}`0*sZB|Hx~#5im&aLTf&RXH`P z9dw*wv_k!{$`d^fhYZz9?%I}v3gQ-LH%?fPG*5+5y2*k2?knyPK}JUfK_OY#h(^AeROicRa;4D{z!U*uY) zx4I>udCv>E&yN?Yv3=h%QAUf=*v|juCBe>@94k3n_bPN5IR-T~oo7!KXMDr-yC_3m zcG)8#9W(yd;;Z!aLmvckax(I+eP4Xv-hJu!(CMGQPxG&Hy31xFaL~CZk6Gb^!KQ!n zf5l&Eo0-re&ok|z^&N>;1(ACXnrt5)V0!Dcyq!Tee2@HrE7sZPgxT^1-TC=64A_~) z`(Le}p7bH<(?Lder-B-mLmSSnJN$=X(nje%8x=;DXGa{Qcj%Wd5nW-y=p<_;!my#= zMQl^ZK^CR9#0BDY%{#mlCbcmnF=Z<@IjqSLWK8C{bf%+8?F|phBvr?f-h-0vdv%-y zBCIdEg{TG=3zWB*ysKnkaQsKOoc`i2CzBJW;-h(ii$ zol-4_{Cb=d-!DJka$w(~`Ugq8&D!_EK7aT9d+meHWq+0?^}Xlyx80i}WZZis!LOrZ z_q($%R-SiV(D&DaujYdp(}wf$U5~ zg&q8zBJO`W&ht-c(LZ4RPUsr%9H|qHre9{fuhyR$X&hRy^7x#Zq@8t_7}ms>^RK9= zHJ*Ov&x3vzr>d`+ck4gi@w_#^Zf0^MfAfQ$$7$sf1vYFu|0v0~G%sARe`Qze`j--E zd@W6DQlbRs%d|G}$n>OM@VDY;c+2GQzPrZc<>wEa+j#r~xW6AZ_O}yXFfYpF@jPDE zmh=1#_Q_iswxpRzF>cgX*5S+OaFH^};9^|I&c?h#@Aeegha!RwXNCAPTl(?M7a0BnoD1k zJSN3Ijnmiv`+esuJyyBNm!J7RxOl0UFKn69f@IcLH41DYk5i6+NLAl5!TW>5r+xg+ zs&*m#iVU8G4y?bDr5UDZ@Er4UHvGf=Kul@jqaPpm!cMjN3u#PSU$xS~_2nmhnZFkN zPyPMpz3&kpvLOtEiddHQ9~zUD{u-*^}sStND{xIZ|MArK<4HA?$~!S)Ab zOcUhv7$(%*|M$%`ch8M_CPwZi$*Kho`YejN@k>9vc2KFY<4At^!=U%adWM4++EiAt zF#a$$jAivOZdu2|-PN)_!6@n7h2_1?vQn&v7rS}C%CAjOXT?EklUHzNeEGC%wOJ!DeSCSRl;Ia6nApAc(=_CC?q|^woP;zxQNb zKjxp?8zSPridLA&b~>bOI~IJ8?Sbb10O^J!3I_xJ3AS~XiR-LgQ>%6e!f~^%H>28e=HtVjLGD9MT zkM*0d6w9%SE$X~2JB%01kYU@#)HnCij}6&=cJqY!RUah^r10f&xhN{G`cNf5OONO5 zo+-iomS29~k?dyLd}wic)7)L0&yOd?`%is&s^Y`H>LV3a2jr}{51Y58^*2VUHt8SI zQGU3iLY`&E=}s4czYiCjF?n%E(`XA%;d`yLdlpPD(pJ2<8nsYm&#uPf&A+aTybodY z(4MBvCY-S_jIDahIT=}|1553=?X-Q2`|TL!UeGc8HI?Q3AIatq#;R)?yw$ULmt6E) z^eB&W9`Cvx+57BF<=dMcScd;Ied|&ErEZ-=qGT9jm3GJ?W}$=6n^x7xH@eB4{~I$>t zAGs$?3qSmfa1_j1bTMP{!+(sMCM4#INM@El{k`*f^ACn?f&cXk!?=_S_?Jm)u^60Q zIOB}`;q5JHh78-BzB+soU~UWa_#rRGQ1mv`hvQ+h%i$lgGCC?u4T_FJ%nA%k9ZoSA z>~DRg<9A_UT(gD5m4F#W%=^{ZKZtJlz}(Wob6^U;FhhqO3*&?PY%B^5>-etnH$F<> z=Wx38`RQME*$N&uhq84a>KQNB?2u4k_PD{$#LRGDi9DN<*MR^rUwh;n19PRA2`r-Xli2*^MU&6PY)_Mc&|1at>qDyv=DIQ z5oMfM@PT`e^-RYH_NUq8m>G(hJU~~k&*EWkY(K;Q>Y0p6e}ZPS(o@cR@&_y|jCKhy ziL$r+-^bH9^?(C=+y8UCp$zU%H=L}HZ#Z)A$b0?=N(x51cwZfu_8`CczyU9NRvQWN zS6fedANcV{vVPj^u;mAi++)hOZ*6)Y-Eee# zkl_65{YAZI{g^c+2S5C=>OaV_cdEm)&Kb`iMTuztm=?Eo|9%J6hab+m2e>X2W>Me4 zU1-9xur<#qx{v43!^`U|9(+jIb;3u>E5nB8&|aIJ3vPs1J&>u%&N$Lyr@Tv-w_#oL zOqD{89o&a@MQ79sfkKu`AFMlA@mH?yUI|Z&O%{hJOX0e0E)$^>)_X-sG ztMU#OPH}3{t~emm$gpsUBg-QP3lklg4+#p7Hn_0ND0mQHIj_@8irFCPLyNYJl++Km z4?)T{MlKUvczP%BI4M_rZ?3o=n0PYgL#Fi>KM5NxSqb$Dr+k%sqgmB2KPiX2Fq|5Z za`>LjyiVr_(c!ZyRJ!dL6C0dmSRCR^eBB*39IHOx%n)YB$9vexqU3YGfP4Fjw22c0 zTHBHq*m6BKoRARvs6kpVj*DTFMH)xp)B_K@4{k8B33OesgY_lf+@BAMn9d9DJtxGq zKvpA!tKqoW7w0P?!iP^X8XgwVIXkm(qSnI&7J>mi7kUoA&}cV2cDqfkjy25k17Blf zC$F7I^yzv()6!_@p*EAGY%=?iu)Iq*lCZMob@<+h7i?LI|&AG$~# zD(`1aetCV4NYBmd%?AY@9-NV4*YqciYl*`y?l@kxy_?+In2seZ+nsE_$0u}x#8n&4 zM#+Z_j>fVQE`1HNJ}Jg=IBY#wz*BDf)NS6ENX|7{4X!pH1zYDHbZD(+5lG*=Tj(KKIDwyv!#$ThG!*s^0%c0Z%nQeyL|9~E6;&b2?-K4jjMA~=Di5x zVLqT@AfxknfwJt9XPw6mtq4#`d$>y1Blcj!fsGF*N|aR|aR~F$;W6Yq*Ua=GiLaG= z(j~FJdHIfw+U+kEKAWgEw_uB5MIdXx6q}@txTNGe&ic$Ol=FCqyh42zaJ@6<39d*{x9=o!gakb_NM~ly;l9V;%Kaz)V|H)*!=trT zn-|V*E;zRQ9#7))Ycs5ax7Cy}WgI+s!m!Q1@{9kEU&4Enr%1f06#k?1%_f_#{bDfx z-v3sQ9i&7KcBBbUbt<@g_Ta_)^VKVMNSHkCWm=Lj#hF|BjwrK&;qmqd+b8<1(OJ~q za*%6^gt&Io0SmtNV~h<&t!-^5>ntQ&53F`Pc1}f+x4HFR$rL>~Z#R`iihdH}+)Rmw zSow@{gd}FE3JEoR;cHhoa>TK*@W2i&Mu&$9US{lK2M(t){0v~e7~R}>jE(iFT?IGu zmI%L^A3O^49vEEte5lb$?dXB9Rhf_5P8|I3zG6aHfn#%#!xAqx@rQ?^p6UY)kNKRF9*!Df`5qaOiW4?0tq${K1)3K|b<2GSu*mLY zv=S8LXb5yJ*p={vr|G!mGu{ISv}cRVYTx;!k==@?Sz&EC(}BZMc6r7-F0(T;S|3zs zY&$H#ee*rrL`H)h?0XCuHpYGYlgPLrA-0^cVbU%m4o8mK_nfLvzdzFdDE}p7`G*}| z99jRk9JSvzI-HSXVlH}+_`l)5_?9htdi&=s5B*);#{Y(?iNUbIV2X{r=D`JQK@SoF ze=Yx*eupQH@gQpm!;8sF92pdwI5b@5b27-R^bN{&34I#Z5-<0sN?%@};XwX_ph|_r zMw5F^$_M7KoO$m2phwVuzA!_@2`OKXgB)V+OoE{YP87tMiZ=^3CaiogN8-v?n-3nW zOz(Lbyu=K|+CS(qJ0$Ouo2#e)gN2!eOW-_bh~%sDybl|u$mND#PB_R>v!-gj-#oqV z=l|_EP_V~_jrj+&!j=plULW7Ej0;90d=HL36fEpAm2**Ovbk~avEeg=3t=A;m=*`D z_+_Y*^Z06STpW91YU-7gPfdauI|L6LV(+Uy^x964YYrFF!;2AePuzHvIq&f;?PYpc zef;p^DLFOKSLcZ|Uoh<3G4pt1EQiyD53J7I2kki;4c65>IKh(KbWxn~KAS-dxBnV8 z-PycKmKUp=PuTqDxR-hGK&Y6REH6K2Y*V|X7iVlCj@!lSJ*Mm(zW9j46tbYF4oL5&rZ^Djo$KkinC<- zIaO^BCoQOF<5F2AbZ~+M z7DjCGJP^pg{zts+Q`oEer-4;>?V_A3cm)Tju@t=b0yez(kHm zg(1WE-~)wReGYZU2MUR7LXNE4nGZNdKh&Gve_5#cfJ2_@^uF`VwLyy;|8P77t<;bV zY>?t-WV~Ut`ozR@98Qi)v(C=v6WTMQ=LgHd@(Tywo3R`B|EinFp~|%~j-#3R$P*3a zf-`&@B2;5^Dq|E{=vYsWeXNFmXj~4%dmCXW2QUY8aIkhoNab@(EKV!&nWgo|a1Hs= z?SgK?5zk#~cBrdY{NrZp5Et6}>}64_VgUOEJ3EG_Tu17E2FLuA3u`q7ArkTLO zHDUa$3~NFz{P7BDb#D0b{LsXg4gU%XWMp6L^hw>9Iklu_?}hpIBg2&*FKU-8_~Yhb zc&xH*>UsVnUOWyzN(+T=du*euYReyE-z4ySOtS zsAJ-1{99qe{&PXg(x7>Q%?Ik`Z1floYHnvf;4o=v#3aVVKirHwa?HOjII;+R{Qky@ zaghgGe=5U-)Pz$9>`%RaH=Dho;Y^)M{x6MD{=-q zSQ|>}FW&cI0>c5N>n#r2^G(=$dsr76Ovss{QxT|9<=EVPA^iB4-}m^Lttam4<%ufj zeB_|e(I{ZYq@n#HOs8v~F$9oYHAy{+Mf zMa!{ctOvH8c)%Lq!J6H8!DaPFgOkr4A2jQ`?Nv{)RAWEL5n%hl;E12OP0dY*b>h7h zUh<3`<`Q!sYPT^|Ufj9DN%@Hd{}OhMEAmX!7y3;|yvO7GP{K-$aWMDaFBKWAMzrzSf(S5W;V#*eT+*(o`>< z)%?Oni~;)|ZTnfp=Hxb8SZs&=iW_hFIu^X&GJ{D=RqCAZ&w%v*D-VClWixi{<9({y zG4s`Pjn|xaKKux+y{l;T`G7;<0a?LWJPu)n#wQlAGF;gBT!E=kSg&FYmjojh=Qcr` zcMJ_2Ws}4MRlGh(|JYJ4>(Bm;pYh8JgGszKjE&4+*Ks#KuwTvI@b8TT^Fb&3@Qc?j za-6VXf0yt<{$lfidjF>hcZBvIStHBd&?qArVc@tZmgiuDi5&Bv4~gpc|IRbvSs@vq z5P7}*Q&T|&|EH_X+HzH24*c1}e31W(#0&FA7R7rTY9w|jXy)8+bk6_qLFPa*^UoO! z3%p`{43(uOvn5x2zs4WIZNB&M!-JML97HW79=u2sYuAY8+hNDdH}RsT#f&UrnRNwj zJPv*pH5^q=+}B^M_+cjA`efFJ7`CRsN`p8_J`vNvjca-uDp`S|C~Nw$``PSrUh+)3FLVWz)Hq98E+{NYEWFv@(j&)n&st>Nw#yt14tjDm1$)F7 z&6;U+aZu-|ojr&Gag7RVe(xex1q$4+bW@ZLjoXig;*fIi4Z`9OA&SQ#v*)O_Bg7L-Y2T>P`+me`@Gg5uMsx(~L z7B{cwZIpcUy=j5OEUt?U5(-=lQ413)naT>TPAczRUMSXj@|Xy_jTw8n#iC3f63v9Sl6PD!F`PXGn1_3C$%;-vE1Tuh+!5!^hsa^f6Lm*>f<7qn*l&sp2Xb+z#6<1e}M{+im{6K?;~^*$oEq9;3Oo6-LR9pCq!K79D+3}uZ6 z5@qY^85HVVj=1-Kd!W+edg#NCzfvlPuQwd;UUw#-R7>!gISyn zCVCs!EnR-3z^6cl|I^kwy{`J=Bfq})KW2C+?5H69Kw^ythr?Z=e^;evhJMK6wNbgy z$g(wFere}PC-x(YKD38a)kyS+6o^c#>)E%^hgEJ>!9Rn<8FI|O1Nhk(t~x(@V51sV z94@swY|S3Ums_12O#U)2ifa~_{>Ssf6rQZB^^3Pwa*AkupJip=utSlv|MbG-ttC4-I_TZ8`6 z1l@uaOc%UF)Xz^~XOL699^QID&qi!t>p}(VfH_K{4h0$N5$g)9Ss6Owm_6_D9OIMR zrdLrSCAw#VJd58Z?pzynuC{~c6xsutA{9S~nT@*TD!=@`x-mswg7rOXGv}fM zFFIZcvJ3Y#wmmtoz1%VHyNxFskC3m$haX(hjlNzDaoSQ`PE(p0mbW`iwb;Nu#pa>Y zf-hm*%m+?8Dzhl85Is;i$%*~Pg%4`lejg6R$jJpiV|_5giEFlkI7iZkP)Ds^r-q9Y zH+VJWa`!SVsI5Nkv`WDzD)IS&ho=lJ_sX#JGcJDV*I}wEA}VZCp&4J?F;RfqZSjNW zhF{W{kF8^OS?FWT*W0p+sf?SkwfTYJsq(I0&N-Qy5@syEG2CC~WVrDxZ}=x&p{2sD zc=3YeiSE{A=lUA9-0Be)m^GK%@d1yQ;>-0djRikSRWd&R=IUzfZGQN0F6V5^pmm14 z%m(+E0?rumJ#0}mDopY|X`uLNZnc=&4 zqr=L;3Zp+KF7IZY&&s?1MNbG%VfgdP<1*}wwuzDoJM5dAep+7=`g49|TldwcEoQgQ zKFM;74dN+y;3Bs1fUk^M<>Z(C^Q8~WvEgsz30VE#CT96>c1Obk`GPe0!*hdAA6!_V z*r`y(R(A4ifx#5}8NA-74_GKp@2|0&7`0Z`d;bc*Rm~rtem_2|{AcL7-~;~{18g}G z4j=pP{lx7-0v|^LXoI@SAAZizsD+NdXo7A5On;Vhgbg{3_Myu>@4_wDGLt zZ$Es1N646`MYW(#<*vTEzN}Wrf*STZ{_g)bjBUf+CrHfr!_c7Mtt@ zGBu#Uu5M<$balwxH>a+XT`kEgy&lYQ{ zxXQU*rhf1a6^Lc#Z@m`-%Bu0F*$LpIbk`!Tjy*>PyhAuqwj4DK1EI`GDZb1juCuZO-++z7ajBvEo7GaFoBOxpd`voqVo

    b1NOBFRT?QDy!i65^G^g;H@Sb4 z{`xok{-5lp71jTE_AF$a|60xYhiH?5vz&i~af1|3+!_H#mKvVbf5T!_w3ts_$y+7Y z5Mi`|JAl1Oz-Xg})W4EleFr-leuWDA`iK3S@xZ>}1Ha<~1!FcA4uRv%T_*&L1P*d? zAOH73?zs%(f&;?dQ!4k?y-2ffXH{HKw2G7YsSnSTWlwD1wIKw6$T)8BK|KNm&&;M~R$n>b|imA_JIMUaaD^=a-a?b5Tip)Zzrz&mk$~_GS zDC^71w!)MOAD#5Mv}T z;fs$b--J|0108`QjTtH&Z|A2;C<$yaloQC_7`Z{hiI~qgPPsxY*cH`zXWnISFda&LMV_0~^c)=N23lo5LZxa0Msh!v{q!i`v)J*l?xK zX8ACI^W1!aMx7k)3306rA1vKjQy#OkTnPKVBh&e?ke-o;#2#^0jV3RBeoya)nR1Lz z-WaF|v&AYcI`l>NsM8POJvR(Z421@4tO|0i zcP}59!Mve&VRuM^U8ATMcRc$#S&PfZFX-`bG5u~A`Jwrj=XkzVU2DPYgflPhx9mOK z9C3(AW7SmN69pG>-(R?J9j8m|FU zr(;Bjw)!%e5QB&xI&FU3IIyBo_@dZ+WufXL zO6;Pk`p1rk%HoCsiNb}?)SU_NKS-OymUaK;Xq9b0M? zs-`_yXjV`r88*|vyjkEzs+D%m1U(UxhR25UdLmN9#zk0?b5D#-#EwwULk*%k6&ssXB*Zu@BOkjn zb246u5@A@{e6Wy3u+^r7DT#4G=#wXpe^|E2KmWT|vhwrU%l{V6KhIpDwEy>EqmR#8 z!}^_#5B_1z*PdJZKa**WVXv&6ZMz6RyIG6Gjjtc4Wn6u}Ou+qz=2!o_3(m=!hv}K?Ec)W0y!Af+!ZtHYI#`KGw*Sa6ry1N1KbymZeUfk27O|@X-Vx+bQA)qt8s{OgJ-n=QA;bqfZnJc%HFo zvOGM|$|xw#`fvxw3hpCI6qDNys5ux4KKEyuIN|m2Bo4NN%12n*T9u}#h0o++Ftxnk zBJz&KnccnrfkzDUK0BdD8=U2txVFYUUHt6ysy|F09<_Q+lVWD!;EAzke&sl2b=M5N z%Uyphs_*r!=WnQR{dZQUYV&iBM$b25a~P%AL>UeQN(2TsO%Q0hAQAPIo2A*^U}5Wf zh4&l{7hM@HFdyM@GN@wu!M}`io~Yn`#@02>(^wL08k^i)+8GZON-dbg`A$Pcltq!H z!dk+SC6#ARMHf)_bLFI>KNyL2>Ii0Sb&<_owk*v+*}R83N9 zkDM6G=O!^J;ZT#L?^D@olvp#i7_nqYB&hPY@4T(cajvOwLqXavVfKT5JY}*XfgT~6 z6?*DwiWh{`g#_CJe8l;rS>tOrZ6GYszBn!1HTLl<`|hEAEqV+{s+%I z4lj^euy4T(7jce*+5ZaUooz+dc$ru|JRtFqjpa{{iH(I|q$V$qTLQ_d;#CtEP8@0_#T~RYgJ)y6Z7~~P$F36 z^)W$B@L;7=LP5R+b3oUOn3+b-c?PC(VJs{hOI*&|2q-KLjAJ>_!O_}3o#){{1;z;v z(j*--o;M$m6BR$OV}k~3;|v|v0~yxBhYvIKI5jCUMEK}e1h7l6w=oFyXt@ZSh+tFS z5w3Va?9T^_nGa{|le3=H-ka`sy~**pkd(}V1QDhOj+_k#Vm>c^aG0Ha7fXeNJd0xR zvD1u-b4qSWJiKx^z^{_y)+9(RNkX!;z$X zM}=P^u~}BJ;lKkfXU0Vie~KQLu(PHdIq+QIix%qxE92Ai#pW@+6_&3sU^4CMJorJ( zOT1-zFmGV{!-NE;<2=j>f=AU~G0vEw$Jm&@P^8<#c^>R)ns#x)+Jm#=^cWj-SkLlzHTLl(?BHNrk+?Fhz}UK@ zt$m&q&&n^&k^+jxtdao=+RHa(gxN9tSfG<&`|!f~?>rg1DsIlYR)V&TuPo{7CZS-rmu);t3-ou%2{k`#S?t8T zq`C3XGi^pYrU!OB1%-ZE5K?Pg#e(`Cm+c7QZYkKb@Zl7rQu{A^QptgrA!v`nknc_Rxm>qjGn;Qk< z_}c?_=-%V(=Vh_JC&xG8hxXA!34bcqh#$PMJu|@N!3IHj#@2@hVhZb;d*-w`JY!bO zK9cCgo5iWmci<`O&4>*_naj8~5fu__yAT;$;3 zXov}Z_@}@|zu;^9o)qRr{!pG9S3&rT^^ks|J-_{8xkR0}~s+FtKp5s&$=v+`q?0qQPt)=+7pClO*xKo+`!Is* zbiicWCz+x%D@vGVJE$&*Jh0=|RCZZq)m5YX)54zl}1S1YAlpdPwePoej!;jmn5&It)1i2Nk9JZUV z?7@v%mW?bSd=)kvQ=dRX6o<3pDaRIFqtqx6~dbE+J8&#)8TDoQo_t)GLe`{%9Y0blg%QY7LJx z%ZnB!#y>(l9ITHYKlmUZJ^g4Mn;GMS4+gxQcIPj>?w-NcaL9wblPPF@3ike@HO5KRBx;r+&TpfWsml)fNrAmxXmZEXAsW*PnmajXkI$UkTi;Ai__FqyI8 zO32#&d3p>Nk{+sf$xg5S|H)Up#WZdqlg5S@29siV?DaD@8Q8zDXD-$hYR%$h|BxdY z;KcUhXH51#tuO%3&b7RadbvMfl{zpoekfiG;G+6C?pQmI!rIae?qFnn-| zyGi~*@5-ZD|5pFYy}5nkt%3r^j|a{$du9LOE_lG=U}N(s!Sy+lfaM$wh7xfm&qHk? zHByY>6&nIruZYgcD|x_H<)ER^<1gm-#_(}IOPj(1b(>hlg&jWfy%iSon0CzEu=T~l zUdP1zSLu7U$dz%=Gv#rzn#94GFU%TvXgbrw6*X)U{w7fc3$`9kyxVWmA@T6Qmvp-x z2{mcCid;!HhQk?xiV>d=9cWx9t|HRTw9(NkafQXAe$sxm}bJdMbDxE?lOp=Gv~zdVyi%jfjs8 zTuu+mSzjsabbesqIM+f;xV@2w`A~pAON+seDM^{F`8=(&l!P3GTPK-$e0J)R>99}} zXqtM^;b4-of+tUZrxJ638eigh0hbM?haI?PaOX)dA6OFL^T(9+gYXPFCYFFi9XaMd zh8oNkF}xRl9h_jp!l7{L$c8on$96~Nc_~Z>A1EXXF+NbR{a~E@LHT2Zg7|9vA1}Pv zq&lY;blf;JutIrcC+K6t<{q_sXnvm}9MRWm0ehlgzc@$V1k zua)n5(;y;$@F<%+e`CwW|N8$uoH%|+#vX1s6j*<{eNV`v2Q91Sh3cRDQt{zi(NV3l zc5NB{J0uyRs~bPCG+sDww&UUFgdmFzM`kEV@bqxG^KR$c8++XFhKw!ac`2EM87dDp zDDlnb=wz8E&Sr4&!7TBvw+qTHtcm&fz{Tof>kU3TiS`30E12z%B$zA_-K3dW#S1bD5_v$fzu0t#Mn#F}$xY`VU zn5(J_cimCZd)S=V;lai-L4u`0%Wy&uYpUd)rJ@c#Uz!dqay}!>_`*o4zrmy7;?ahk z>S{t9Tlo9g9hW?IR`Zao;1*;|Ud)>CK%`M&jTwL8!4)+k=L+;X8aJF{J`icySP)>P z_@;cXA;YaiiMiT~MKAV*OYSMKcpAaXXrdwWV1vynAz#tC6)!}>k_<`&UB9q1J^0?C zVDm#qwEn=GX&bnM8{4a1aEKmH*!Z(|!J6OqK1yn}O|W=!Fv^Qh%}S0hu;He}vOYG) zf;PsZY=p;}$3Vze?Q{9ne09ZBo&DBCwEFfku+m?XgXK*3U| z{p`W_2mRJ>kw{ZvVN_5Q53o)UIq%)MdS^xi8>!$2uVR~Tyha*mwan=PPbr$;v#>o!(8gmYFH%T+P;`_?T>fZqz9WX@kc)}?tj3+;W9O$iLv$Y`s%CA&YvE= zZ;ozgS>>ekfQP-I;cP^o%KeubHtgRYzgnT-$LoDn>;Es+9`zp?){HCyj0@P9D+7LI z?Yk5^?{a^_rN%cZoPx|2VXO_S&OiR)_GLvix5$MHSDd6+6fF7;lb$c><8Uwx7c+>G zca@nT=g0lg;J45vC82x|&u%X6`||?Nu(gOVuHv`gW_4Cv&U{fqncZ;(e?f$#MupFZ zD=XA&A71F;{#f0j%q|k#FvlRdG3nD}uIlrBx)o)H3pG4tkL9s81kRJ_P5gM+B(eJ5 zkt-csO^puROdkSLB;>>zJ`_kYRygG-B{o<=}blwnv=OhYy^0QZO=8Vm$m%Qf~6xADSopSPm=fG1Ot5 zp`V$_SdsbQ(C)jJ-&r|M}y5A!z_ zUb%Ukwb?OAwDq#W33i!+U%S}3E~>nUco=+C+FfvQeo;PMiI3gZeuo zYX%Mm4Tk3o4>bf>7AmVRT+kwLWLB&QXWXS<5p$muOPE-1*bySf#1g0>!92B7>)@2; z+6cwz8?_xoIGn=wic}csf2?4s*nKbL%ByF&KR?7XEYP_1ph3V%MyR{7zxjY;6c6Kr z5Ax4C%m2&%w^DlaWFdnmhn>9hqlh21j`O4s$aZEu+UfAdhM)0Yh7J4A4?AOiR!nto z@-9DP!`vj`9AYns@@c&b_`3D{&Xr_W(+(2_IR!CjEdW?*r6ju6AjT`3Zb zg>K1>0%!a`kjkxRoy)#*ZE_d>^jo&tlsR>lV|i`^$q zVa)L3^^P?e$LAhdl1$3?&?8 z97jI-Pw6=K{Eqq@J=Vmh2O5?}Or5)>#>)Gp8e5rkn#GS04PCMME({w2dTa&6_*oj1 zyFTnPIPQ2@Lbt%8Ny}P8%J#qnzCAt1J?;rHeA=VKRUq!BFo!=e;N(FCHpTY>-7Jr7 zoH)w4Y=RV>raVfY%69b87N153p+p`ZEkUL5UYDk(t43j-y`Bjk+{Xo%i0>4a5$O;T z-C@U~DZM~1MxL3S^RNWBp~p8>7Q52(l@G+?8Rp;m-^O^Ljm^5`M-_#n=Crp56T)1ky8tUn_7n-sHM9QJY?Opq7i zW>k5&;6lQK;#O9UgHbwK3SWedFrK(zrcuIvV8&mCaLa<3Z<_u-e#xn__6tuN(>13B zFXBEw63kAR>otpOzLP_Zbq7<~!HiQv>v;AlcAjCrxG-^-9P1R}HrA&LrWlD{u(4ru z{LrS()8TupDM5oLL*`qno1>Yb#epReqKt({FE%@6o+vobVN~hbCL>j`Dp>di)18kG zK1*x}c6ng2;6hqNd9R~E3(LK(qijNghYZ|U6~6D;%BRhEjw_9WJLZEUpY;_HmH?eV zF1|VJdz54ZA}#b8A__FPU(WAxP<_R;(3xj~b4%h`QEm37|9d>-HRSI9_b}Yf|3FTG zn?Wv4;8DN)2Rj{x2Ok8argJ7-5pdbT{`2Kcg#-Mn0%hzzR?XjH`m5*h;U6D(84grf zu+>UG*umUjQd?CZ)$EYAxbcDg*)R_2<#r2799CVZ(f@b+gAU_@6|$YoA5JJRz863E zXy5Ux$r~a$nGDhoFA(E@E+EImyrGGQLySe#;UJFyyHk8)!_DG=`nTFPHutA%g>hAC zi8BdSyD)r^zthZ+z|NwO^xJXy$MF9bmEYvD8E`Rvxiu$=qa;O)!GrzX%LPshF>Ep% zC*=1&yl~*5MOuk411r-7ITPSKH?8;^Wy#-cH zuB-=I910(FI381FRGi@TnXZDWo_6i%-qwG(Z$`^VIv$9AR#Z_o?b!U6h=W4Q5er@=#t99D6Ak1g`WcTnd7S2KUf^NXdd%fHE6XB>8i9j# zT`yGH5*-?|n7eu`8no96^s)#%4A`9a9wZpetx zWqj~KaE0RX#J7=RT(0$8e8}M zTAOjfS!iagMSS4ygc-J`fl-lxzo}Q!`-uA< z`*s$A3jX&88?4?G*s#CfFJIW#@F7u0g1P%W>w^#S+kf!=xM8$Wqm0o(#=haW^AF*J z4dw@A_xd<-C`GUvrN}Y=t}i}&D4>G>?f=G^6(5h@E%+yK?7UB9!L-n!zJxG=2BZ2@ua)oTcHT1H@SfrM z{K$#`1~GL z=VXf26u+Xf#g>_^jahlG4R>RV&Toa)J~KWfgt>9HrsVT;sdFvp$+QftC5fQR&$WGqoEJSlM!JxS){y z%UF_$FJST!#)v(NJX6wMMAbf9kTCguc4i-JI7u}z4~!hi?< zEFVfF8!FDIniw3go7|kRN{i*eln*(r59a7_7zsYm_1AR#a6joV!`Bieieij^lQaItj!w2<@8ch3teaPpm->~-ZN4=7&quNF*>Q+>(2xZV~2>ip{ z;8^(j(f?IhdjnWIneT;vd1_YApuy;1;>lK7w4trS6LfOC920W@|HAo=^VSA8|6n@6 z&!!*7_$#dOQNT3SAI5C*L4R{MFZduJbAelk@k9OBaK<_I4M!MGI<_?ac&oqRgB-)h z7gMKwKeV8NgSV!}GaL6D$@? z3F9;R^w{yHMO2s;`+76%o%v<+f%t=EKcrgTu}=waWAtu5 z=)tF65fEm?dGtL?lZ^P%X;$hhdTdT{v$Je+Z$EN);sicU$09u*8PfzgA?6uMvQAuK zteKX4b1Jg51-kEWHlE@>5XmNZ;>69x>)98|=&;-}6Sk@2ReiLa=bjbolDU==TP%1Q zEQFmCUUX>K3-?8+@GzQK3wO0!Jge}LZ!$c{l2^h0eL;uQ$B&tOJ5v;OSvECfST8)? zN5k3@}CQ0)F=a*Uf#IV);hsJD@0{lOHhngE=7aV3mS64=p3m@6N1ln{qh^5d@y~9}2ONslxaBW; zP{ASPva!KI=z!5Y_J&3qZ-)0TwB>EmW3@SK8Lu-2Em{>o4FlVqo`f=KY9db;pRt0iQ ztbrPm`>Qthv+1=Ru-o$C4ub`I+@kZHPT>d6FE}8+@t}f*(oTT|DpCx70s{XpCm0Ae zbGbZNz?vb}lAx-&yvgC9n&Y{g#1gUa{Z8#H7jIq=j+66Rlpynb&cz)LBDRkXI4oFh z#ra%??+2gRhYzd{TZE3Bmu1=^$9%x!Zi82W75g4Bg=w6PecTt~lo|yU3uZd%R2Xwv z@Usi=5pnpu_rMBP4n1zhkHHPQS%Mg*=*T+7+VMAZo?}Tn*Ylt>B<+^9qvm_IkcA;u zAAUJr6kuI+?C3jTo==nKbGFS}FhiEjvB*G9pR3Kei9wZF;jjTWds}1TP2*#Z%zh2e z_lSx&3T_No6FA?$dBH)afXJ?c9~LS`==E*+u)}eq#8bh^4<09NTBopRov4kO>4Ko| zvn3MZxEe1c$TKVG9R6gugRe4Sax;_4siOxTNICm5Jq!?i%*(hXh@)Y}k%b0O9S?G2&AhP9%g2GbseAGFB{@AR}fY%aCC2 zmh>Pos;OXyxv>~P-lGls?WzCMX*=RU~l+uQpKonC?d^1 zY?W-NoPATmYBr%Jj){Hj4UJp8Ih+l3y!GUE$T2Y&@N>j2Y+&O**r4GV!kGM{j-QcL zW15`}KO<{}(+&I3AU1~&0uG(Zuh%j;*susEWPnD7O#>Te*s=e9{6m02z4?Gc7S9UL z3oR={Uo2oY`C!As_uxFLzk!v-z+)r^`VBam51x3_B$DXfP%mSfeI0@!*>XH>ZyhN!e}s2|Jr# zi2g8{nXyCW@IGdl8Yuye)&t_M2j(yzVL4?`k-|D5g3oBePOj>CA3Ry4I9U9RRMds1 zEZDI2d9w7J8I4aJV%kDN_z#3V7KrRzE52vW6qob_>m}>>83GCln7YPc# zW>H)a^B_n?cn&9f%0UlpK}HJ))qL1ZZ=5NekXrGkZF$`^RED24z3k%11D7Qf66d!d|*Fw zTFnC+_8$vb_`;jD_0>5XC)hXi2(t)YKgZOF%`_ye# zAO0FY*ZlYU9rbJ<5_s6c80UxP*zhy5WK1?-`okk|;9UbaAs_zuW<8r8hdL9-gp7K9 z_J+nBi5h|P%$x~_92BP4X; zg%%l_FH||36c#U1=XLgMG<|&VxcwuE6&e)*LfUK$o>trivyyl(P6~*#I3RM;sUcy- zjFy%{foM)9)}~7ej81VpS+?(3Tv-k(Xm|BW=(D;wd~RI8!}4xfAnSpHQ{=c0Etr1J z=<^31wnY;+?AT|Z_ko2W;|J5!28Viv2!=&Z84afKtiF7Z|CTssQh=TK|AfO|T@Nh& zs=yKl^8)061Ykxo6EPkE;f!%`-0^XeommDHNx0I{$FOg(E;F!nH{I6=!uNyA>jI8q;r?xqK z5KuarHDwMPhxwHc^$8yY?3=5fGk#F;XK!fc5nycpccVm(iETm)2p>Cl`=NsY zN{j*w8!a>qd@3aj6oqZHB%3b8wFc<-FbZ@&Y3dH*V3IXRj6UjeM)>jBgBhxg7V3Li z!dn#dIrpdtDX={BkP;EG5ocDod9G3OMebvVKb=RW80$-UB)3fv+9S@A%d%ij&w&De z9RaB&huX}fxrBtd?-U3mve=q_^oSAh5}dd}u&0?hR{TYf@GPbiVVq|Uw>o!Ta5dx9 zG&rzBBPQ>|xrPlj(QYi7Co1?9*cp15&-yl$SV|laI@~BC^PzC_lM52kOb=up6l|zr zU%bQO;}8D@NA)BayH@c@%x-4d?s#NTVRkcP3%j(U!S;^!GVX>4t5~}@71oMbXg3}V z5D~OJX{74(&_GVG{f&Q7iKp)a6L-m5c5}L+^~G<9TgS@{U!sg z_XRDiJlu?&FPeUoaB(K?sC@jRcteAbz0f{gxmxd(_zy2%9aet$hv5S|v%~3!95)<< z7Q70*!`@P?@WX($S)T2KNMp|TPf3ayioe-k9h|f;ax#7a2V}p%=t=SCrh9(^e=D+O+yBpgdKRzHOz89JSxqK3tIaL4mnW{8PgLME>nrLM4lVFqHt)lq_}L^v z9y>ZHoHygVAmi=2Ou_Aqn2nHE@i}(EgVnDUHWnx~GbSHaW7BAy>G(rbcJk7vM{jWj z->sU?mi$9}18W06dqcyWJzhViNH()De!ueIjD$xc8^?VsUK=}RcJ?C<=j9HFFg3)p zu`p_eT|e(rz+M?3cd6*P_>gHV5ukd2Dknw$ee!~MU`2z{etVdsMzp?;S z4ObXeOvrz=`*<@8Lu!KT@`HOgR1XLV9O<7Yf0T*gfEPa_M+f_KrXFMVhE^4C3w}nn z2!-Yf>Fq5I9|XD^Dijh_nGZPJ6F9QQfS>X2i64>=|1v+Q;7GZ`&GkF{44iw|DwXr$Q>~yj;BP9N#H{QAKUiB|4TI38`}8T5%-LW1u( zUWW^X2YhXWShy@T4mmJ9;JhI0SM|;nhclSLm}U9=Q7O4!7fTSH~jR;u>|{RwDuL z6MPO;vu)HAd8JI$?066IY)DdMIohn=@=VLexS%E?O4Rnj29fubJhty$QgU=Av}uTP z97~8h=oQFx=)kN86AGCQO(<~Fs|;vnSuYUWGV{@A-uawt{(=G*J3i%Ds2TfPTnhe` zdxnQ`ngp*ByA$&U3G`thH?|A7Ugg*fv8hf_TE99+6=7W|B?H`qGajx0#}km^t$K0%AUp>YrM z!KrE@%?t@_EzAo}9Y1hz#y=)Ienw8K4J`}fIUOG;+K1U0@H4XAU~fowI#9vkaQuP9 zj1+!G=8kFnjSMqv*uQHvHXHnFkl|#u7OuQNbT}EKCbN2<-S% zQz6I1@s&%CpYgAB9{&qH_J$S}X6}0+2RR5`3GiocXsJ=C$>3*XmzcmK*?hp^nJWLA z3LEzCNm0xBA80isur)qV2xa?Vv?p+D;!>fO3HFQ${EVy~4jk%@4-^8~8k*Z1TN-#6 z?piQDium!dz(&0FUbvmC4C6xqZigRJO!)X1H`uE4o;=OqpyuYgLz~fioh-NW!s;dm z(Qc-OIdg>XJvgE1py6j$n8gnz_6l*bIR@O%c9kc|!&f4@Uh0kwp+~CFO*f+uE z$x7!1J)f_LS?yAocg};^phttPpyR-LIoC-FlNu&EADeph6mM6Y1ee=o-qvLa1~NUL z&o{C2#{A-Vm@p&5(x+jbA5W`>+Qp0vAMvIHJ&CMs%t8#`lDr---S6Z8>OG)iw2QfilGOPI!3BO@}OrKy7_qd+WFz=L-# zqoE?_dZ!D83(jy$z2FqvQNUNooUudr;D$#{1rLumIWiwj3`p$eWVEp1TF=^A;bdeZ z((v(x>JEJt9t$Df6LPbsvw1KXOniRe)s)tn(o5`J3YpH2%A0n^H*8zDlKYN*Yly+@ z&J!H-UZfZ>S3P6X*y(>Fc0kR(`4h9`z2TPB4vqGYD*%%Ie)Z?$)G|^&$farlU3e_Ke{O4o- zz;%G*;enNr?QITgSk5ju@=a$#?_mZhP6r)^>Nz~}pp6S*D}GFfS)F`OwT1Il{FF0C z_1HhiGZe@%aZKO^jqS-XaTYyP4potAKHyNs>$r#A{7AwF0sV%8Dc1XzIW`GaIM^}n zW8*pgae)kX^8v?wstt(>HY^H@Kk%rqH#GjKV?4*+&~(I`{Xj#A924tAP@;eELH_9~ zHinIVSZ_8yP*i4LR2ZP%Wa57{bD`8{3pf*jO=TN(XjJ(~) z7n}!-3_`@46$8>FxGZ9VMBlSC?a*yM7~0w(C?z^ylK=HoNy`JX8@37C9)HZiZs4ZT zF=;~`@8M7BO&=}=x!VY`>^PwKL7)G4@$-gScHun=t3EllHOyFSEg>Q*-g`X6K|*da z!}BJGHYd)83!Ql^%a2ZWFYss0o|o$;-jh5}$cclIU(_qfAe_34f#KpZz;*6JL+7JE-beUQy`bVPoRU@y5b8V$HJEM;=kh1v1U5R&b{V(eRHtFKYoS;1NQn2pnIYoMf{i`p~&gHfs0K@ zw3*GJA)X#jtp-r{< zfrA_mW@%ULA#P_)Ifx^Qu z8+o$|IVLvi2OR7T|HWkGj~;sPK_GLLzI^{-g9;9fLjsdl)a1x9@qI|O|1ZkT_(0*V z9-AFMBQw{+A1urV>ifS&J^Xu6LXL^;Ljw=vTVERQ}o*fEMf4BQl)Fe9}nnPElpzHZJQzUwnt0(2El?NMW%A!B^J zHI-q5I_o<5dFwcqlshd*+?lYc>t2aTi%^M-vsardM?>b1k)w3SO9dtV^I{9!INbL5jd# zMt)8vIbpViT|yj*%Eyd1D_-9t%(Y&$B_WaRVe>(UW9n?o`&}L`D7Kl{#yXLgYtg#^ zR-wItN?+oHc^R){)EHM4Bxp$9y5=Oh%Dw+VmZQ7X^#SzL^7g4kRR8sCv`Gzj>A>+uhzrDC>9 zLK9{zf1>AUkhYTZ`#-JV)$@$_AGkAUFi%~@vY>)P;DCM8!w+dZsx`H1yPX&-She+d z4*ua<@Ik=2#ZbXp=#~jTBkPJuJd6z~Q{ zRch=j>KR;k8y_f~XHj(kt#X!1$YE_h;FzY;$?o_-;b22y>I7lt0}hwJGe4;BlfQ7G zfCav*ei+PjK&2RJZxkXW(Md=Gl;7e9udeb6x=JI-UcI84h?POW0u{~*OcCPJK9)E&LV~?ZPMFJJYm>qrmAQuwa7!MMv0N!}_Pt)~ zq60$u3KfQPEi|hSb}H~x7%)0qVV}9-K*)y)B3pzyJo4Ead=Dw7H5LT1Hm!E7=&0sw z%RF?-I9!*jBSf_6L1FM=g;m@eeDs(N;%0I5P5YB8d|-EW&*9zD6YQFIeBWW%(O=!8 zdtvWEm$c0fcJMUcymR-glV0^5wT>2rCO59{Hg7{ZSSQ(-%N{%4bojlRLX2?GizO*C zG94c?6sIUWpVnC8bi;*Dtmbf>3Z)H$s zXDUcwcGOgI6p&l6myyS@LyDJ&f5|%TCSl&))~k8k4m7?ws?V~x<&5~EOAGYMj3$0K z@sFioh6%&|6Z&#(5nLhb`C0#|Rorp7;KCwWy}>|rLxf~=lBsyb3?CjA_qGFy42$O; zHD1=7ab*9Dg6fN6z3%s(i@XZXOW39;^04q;{g0d-lHdJ084id);I6Q5*um)VK|rBX zL5!b~xw4`T)KHhH<6Q7Tz;JcLBp${?@%_yK>HH7e8U)xAJ_z`AT7TQ#lu*H868ihi z9yuoV|I>4>9GXzUp?PFN!U;JhR-q4E><$0z&-1^~VsB{nF=B6M7I|UABB5|VfS-{y zvjlYI@qT873jR;$+rMb=GqOfZ0Xe{|g(11&gMjZUS!TiJ1CCrP_Wv?rZ)g;$v9jV( z`SYUQiQyoFA~Qq$f;4_crXLPMe$5pg`WGj#b9$ZctY=vGgtdX6VTS_mnMqB>ha7AS zLJn|oOE7Q=2`v$8J?-cbrdHv>Sb4|8=_iK=vnyxNst9h$>&+ARrI=nHc-&{g;kw-E zqQTOWL zH$2{xA}r7|M~an4nCXZJ$I2#y55;_L3eP;wwLP59s`N1UV1aeRgDE+Jtbs}eGat4* zo?GE7&@kzF^Mas&xN8rB-IWzT96XcAlN`=HSy`J$mpyQyijc&`quazjcvLqDay$xR zelu~8P(zA@&>lC&WYz%oJ(^6W$yevz&_ zUtC!WE>z5sW%`&Q&bn0jVAY2yGW}H^GMbD%MHibdaw`1bVwH3)_iM^Cn|M-HY3B@H z)==Ha?t7aUBGS1m&pq(3KIgDoQGhj%eS@Oqm&Y34<>fmL$TC>5Jl|mS+pXEK=a`0o z?R&PP4h8%b7EE1|dqnyDOasCSo0yJ&>R?=8t0Kg*+5O1Uy#5ON1~rBY6&%8+o8()j zooPPc(EstvTs8KF#&_BQ@f-&qD7c^HY25pxMxOcKhkAbYhQ=xTx)~oROc%P!;9AnGZO+cU|HG8C4v{-^fs5 z!y=Gyyzzm8I~zkoLK{y_y|j!R6X%Qv6&%VBRG1Gqa#hGPacrpJ5On-te_j5LIP(EV zw$-mRF32&l2r5WE_#xobe8Az7K=&2B1UV+=zz?j=+F=jwEpQTQ(2-E!-^Z!^RQ>q9 z@O9xa9*5kx51wFfV06sB!_j28AjU|zv*X|cw+D0oN-!%b#R;lG zNe(F*S%phDI*v&!NPBdolf}G`+vj_e(iD9YN5u#g7J*d{4#~c>(k0 z{)!a88b3`Q=T4!Cdxa#tc^bAf>?uCPAZt|MW@-q6?^zd)C< zNwB^jG*oME#3RssKtti@;~yWG8s5k;v4=N5aAe|VWCk@g8`&EgSsxtaJ^Z`zhYgEh z!ovm|7J<4SdX5hi+7Cw9u?Q;s5KwAUb*NZ6tkX@fJU)@Vm0jSo#>Myitk(Ae#OF4qx-MCgugKh1QKFHs z@=-zomz-o<;)G>(+y_?hmA4cu(BkpoJUB-vmi6)^ZdWdbID5w9T@&p1E_XIfj!|G` zSZ;G7q4dB81Eb1X^*N94eacAu@Ih_Qi*sB$CVK3LSu>Uhd+>L6M2m1AJkQA%-XhF& zy(4);W4VolBgfVU9qjv^3Z@xEe4eM&%yE)Qy~$8Qyw4!Iv6IE1aQY&)#E@2x5-w&} zrXN0Enk=+=8ZN96w-IDe;^v>v)HJE-;CI)0h6xiCHI_^e^2=#tVN2Nf;2#ImulNs^ z3x3@HyUK2f>HxobP zi#J;+i2wLmQ}K_Xg1v#K`GCXmub`18ne)sC9J=CSG}s#&%@4@_I`|-gXTiY<<`2^3 zFC3`gkUj|NZtPkiVE;iEG(ak~ioHPOK7I*&j&3lc6{3Z=SKiTiCBPy3kQ#c5<>>d#Rw%4^@WME3pPIU`N^&D z?2L~Dhra4;22m?GLEA;fUKsi3XR(expQp!OjJ8x789JnRNm5`ygMazZ(c z4<0jgb$C2f&~(X7 z$B@hK!vzCjFAfq~_+BM!6I0?!~FwC)i@Q>xi@uoe~KQ0YDe7p7D>xz*7T5nH>SR6k1 zr|}Sm2`#qmcd83)Q`m*Dzw(h#1&AClx*N1B3u6Zus7li~mE(lsB%Gp%t z>gXt7*q)@U_QP5^K|zhH!A*uox#@pL$HU-*9c;>TikuEEj1gtMx8w7>ihm40Bw3mc zImo3LGQ55;M|C;-f#c1_J7ig1mbxB49%LfSGO6;oqXHjW=ZOo6tJ@SLSQ!Pxn5qv8 z2yf7DHs$2ucq7ozAY>)P)aq#Q!p%>c^(Dt)i`E@mn=+IqTFhva)y$ltqR++f;DE2k zQ%g37S?U#2*tkTv6{^oM9%hPIVIXi|PG|F>1eJ#!25S;T99AUgdUL52sq-Xo2&A!e z1c>i+^mw4qmf+jY=Hx!x+$6-5JCOC26oWeJle3H-hZc0S9z5)n%u#)$kw@kT!wh4K zEirof*35=HYTQmy+V?)m6+RT@72ji{Shpk0oQJK!kuB-MlZy?mGV6;Jk8vHixg}A# zYr;i_m4_V?S@=q9Cj78uNsLh6W6H+LU^lPO$Ai`O!33@@H9m(6aY9Wm543T!&iT+} zklhh|iqp(Vi!tTk`zo`55*dRmLH3}X&t(ib40JvTNbFH$^l&}s!F6v=fgM}_PnM<9 zcY}}Q%{Z&%!#b5&Tt2}w+E`Ua_9H;(wQ*@!}K5 zN8d$ChvOHEan=hty!d=6eNh+R|Fh!Hr+B~h*Dw&8HQ^nzaQLEyhXgc4m>pt1w6H$d z`miHZy&}V>=F39<&2EYoN@3XtO+MaMVSIM4L+K(@i4wyjr;-R(8T|)G9tJ8LxS=K~ zQy|03^4XPP%ZC+$D<8=DDltCMv!B>-A+G6xN_EF1O~w|*dzD72E^g18Bzm5=Ol-A# z(8VF4Ul`<+AjZY)Y$$Q4<=m?Zp)NV*c^=$O2}hh|E0yxOk2~{MpKzGKQRT#{n3s5v z!$_8y=|ZG(!3j>`1&6E& zbL2z86&WL8n*@uame<%@1e=)~53{o}a_}j!GBPc9l;M_qSER54@6lp<_n~8kh)B)OXA69|=JU)8;p6a^XHz*}6wv6v zef+`_QNhH^PYmLocePJZlWcfUuiSt9!I=aDi4eXY>96L@zqS0ojt@`yjrx1LOt;Cg ze>R%kYjS~w|8#rISJ|s}7qp*0i(m5O*jMYRj1L@z*gwDG-Y+dzQ~l~x+AhD_m6z07 z75=$#q#g?2r#!u1+qNU~qfQ;K3iHO8#Y=6&R%ctdsZReJyWqnFjzym~CaqfO(I1(4 z>KB`ufR?OTjR}JlSJBFeujP0goHaZiIO#s*;peSx+`{c#6@5t7nseTR(hY}C2%q3= z_c^Tcp{n#5UpJG$!F~fD855QUY1YQ`X3TMw4-Y)GDizSxaM3vMys6>Lha7F5Mw1r> z#>_oCCa~#iFonxVEU;*~P++NHA$V@Kr$lFSkM?TC2J2!52PY0k*(W;29PZ^!2@kf+ znV=zH`9wmeV&%Hi4s%Km7I-O0A701f%FFutpumACG6^DF;t^sj3ULpdEOZM>>=!(8 zC^V>g+PPUv{O>?jH~Aa1!ldmXwe=X)r~^HpK4}x4(cpOStl(#yP@_4UM`S z2QP3xO5D)mB-|t*Zrsz!@JJwuu}P}XiR;2qt=0ujGFi;`oSYaoiO7EQl4qXpI??0E z$%8*+xS0|bFvZ46+8p3xyCcrT^y=>#NtP?knmkPg8r+Rl&kZJU&OGqSm}koZUrDh& z@>dRCf3#t$hs?Ffy`4@^lXq`4&XJWXxPFiSjY6j*i$_y{;w= z!S@Thdzpl$ zUIh;ih|Sfskl=d9%5vPv!_+at=W`x&L*U`12lQJW%qWoYQBK%tB-z$b-0*lokHd$U z9a`*$9CJKmCNs}aPDyjn=x997w4kY_VU`g~)3qjv1x1Di>@H6lo`^LYERhtj@nDhd z%RS-3^o{jk>#~U{LL6t#xhuA?RUf&edTgnm%e1Fck?+)mN)aA zp31Sm93Yv*u^f-19~^o?M+Zm;LD6L%|I{Sb0U3u}M^D$?8j3vZu5kVA+vsShPSc-o}pE zR3N3ERWw8BJ?GyJhaCosRef3{LN6rwF$?uS@c+ADo@9oBj@sYp3Y7A22 z9*NeFAKyIm^BFvg=Fiw68T_98LtQh!%l@Wmy$Onar>Ar*{V4dKNy2H7)eauh$qyMl zriT2CZ{*oIA?2Oa9;uE?B6}AKuC@D6qgZ^o{#)pI2Zgd%#d~d5l}%>EFy> z<(gq!7DqOSCU4c)%r9YMCvards{;q@_^z=uoQ-Fi_(H7pZFggD>w39Hk?Lb6pEf`K z@rJWFIEZ7}a`BIvfBWlYtc-t6YuQkx#>1YV*ZO#4&y|ByUbfF>;I`&Fu)vOK1rK+? z&xI$}+-^^b4_I7$Zcl!$xbyqU4e#zXsQopNoGsnB;j9Ad%1rK~iO()B&Y4&7&vX6D zgEE>q=1!t}9&GVGs$X%0ZQ-NxE(V`-=ZzR^EiMYguq{6O<%Bt-*X4G>1*<-Ilr=j$K}MtiOl9ajcig~ zx4RA)Dz~sEO>f)k8pUV%ea8eTK2fDJTbx@iPYaOCeb7;2qsE$iY{}sdMz!3BPWhR0 z-QzsI&BNM5@H+p|WwWm^zGR5u?3ZPm^nH)7t$vJ{;*4Ks7i?aBL+QxT{N=9BXW6Cr zTAv>XGWzVK!2e%d@u%m6dtx^v7{80vP3%nwljnV*ekC>O27l}S8-^SHu(;=1?06jz zWW~+HwDW?y`b$;20{g}wt-R-@hOwLY7V6)a6!vWO>LL|cnLpnur8uk}oOV$DJGa?v zJwN-UZIM+EgR2fHhh$z#_-8e-p}=t=uX|(rJiS%#pB(z#yyoA%$L=Bri z{rD}L?)7NCa@WQ`qJQm{CMXK_w-8)?pON!F7w;*FIypT-%M}AyjMr`*)LUGx9swbid?LI`5gbjsGL$e zp5ps=a217@jgnoqwhD=|f_IhA6ZC zrw=LiwGSkCF0?srV96@*3U%2ivTdKHk4W1A&6GUm0NzX29NShMZ1-+v_^?lIVaUP& z*(QC4Y0b~-zp;C_*ay_y|Cin0{^38fM#y@_NX7~q9v0Q>S0wma6u(ZM^^2V`psAU= z){%poS%LlB|2MosW)J>luxT?~)KCntv6o*JY>`u=%3}Co5|6U@&p2VeM#c!~FIz39 zGPbT-AQ$?}Mm~kreJ^8IthkkE>&GR#fAAa8_#bqN3L|92EC>UB06CkcMA zd|KISzTn3P<~vOPm{bq^-2eA#NM*>CT9B$!UEYfxd`SE8;%MD^&gRcjbHw+}<6Y(j zO2^?9^91(TiHgQXO@5#!oz_+#ur5^T+-r?fIDMUzKofOnV(*>=;dWQPG0DId_eEo;%23?R^!e4q$W^8`(jCE1s(&T0C2lH7TTkTAIoRs-$&YFkPf$cV4a@#tYjnjIv zK31G@*C^Y_-Z>y-^*B9y9zWxa-|HAAyx_b1z961eqU?sc zyjt<`gTlG(+xDtS$=EMZN-8otaKif0^_P3M%zL6He~|5ub;DA9*SMZNdpNG7Wi?tK z+U$Jb)0L~b8P{Jqy|WQzJW<4QsKLm-Ata^VyJ7Bfxsw~tK2Hj{&n8j(@Idc@W7?r> zF0S~)Y{DGzLh{vtH>^hT-FcJbE1oe+d{w?WmHBA>JO0`K?`Iu7@G<^(^RxfoS|2<9 zk!R7r(wORSU^V;M|L^*KpJx`E(w6_@+?P2L8TJ!rM(3#Og(-ATeRuNE!?{01^zu{` z_9%k}MQW<2uRruG_rmHcyU#RS>^9uEz`p53?598fco=MI1VY72Bc|Fv&|-eZ7$CUO zd!>jC|A7TZ|I4k~>Ha9(!s9Ke>ey;z?Cg0yA@ps}sW@SD0v;UulcegBc(mQLs!6P-MwDp0Q)klSY%;qdt zQx6<{b^6w?J^roY*#2?QVdJn9y23OyLQquu zZ2rB4N^1`onX-TVvqqwZpONupg^db}9h(EALjylE;|~M2u*UYo3<#WfNnLU|ewUXNAEQ32!#J{%akf&D^0)0u$J@7ku$#Q|Eu6mypox_&~v&Z4=|7 z4T%Y+KMdHIYZpGSesmz|2akZ`J|4C#>yH@*&J727B=+Ofu#IT=a{=w8&_R_$H{YSzn#)S$t>^~kHXkl#l zvHx$U^6}}+^7f4%fAFjSxPITwl)d499IgirEHBz6S?%fk;Z>e=82j>>_60K^e)ukX*Fcm1pj@{! zn~`Zh&*6va7lbM$k}nCoDfxFy`-arV&5aVy_*AjPA5 zhIUs_eZ%$1(i*{WAA$s~yh!29bW*pGIG>@yb5E`}CnNcXmn8F#?3Rls-J(6u*=k|C+-uQ7UM6h>~%>sTKE^dnlX0K}G7;8_J z$yTWG)*5geXnn_~kaPPu!v`Cu2qX4`)8yC>HOPohF|p%goFnnX#)vsWrEdvS(Smg* z4muSRGy|0Hinl#tX3KUgw}Lk}DZG8*p4Asu^zD_nc++uK%>%x5tK-(> z-Jjkp+%B-oR(|s@zV@oM6RQtzNE5utW%d90!^Ydkk33cnYM8yGX2B!nEm6#o{m>Ul9!*ei5Ggo8MFMw#`mlapM~agHr|re=H@)` z^iW}~jh%*zN%0TK9fFLXA9?g-UN}=~#1f;b${FW!tnovMi{Cq*#uQ2ZrppUvM6XEl zOLb7_JurdGxKTm8B}Y=ANnb}J;lqU8hZHBU3o0Z8OsMH(W^-iS$zWiRlKduwfq{X6 zaoem1p51I|N{T8Uw*263e8bBrrzgRFbW8Lv5%%SA0SS?h4m`D)a3sHT!c*>7?HLkkQrdBkwM8Wp!@Wb&JHBG93h_91JWh3GlLrW^3qhh_PHS zt%i*??)#n(A{;N&>pKpeJy`fbg1=AU%(Tgu1Y%@^LRJgdFgZEq7bI{C8Mz1^xS+xO zthY_o!RBQ^i~`s31#*oA)xlyL^12x-9^B#G)TFS&iksz}O(@?nR(&xxft2Qc`^E<$ zQY~B@4vUr97%tfV@676c?0mVdk%zBehDX4q^NgZ?=*KC4Qs&gN9GK!^p}OkF*YGVf zBjUIirC)AISbK0r3NOP7(WYE6gNGMc4kR4lVsSjf>2Sta-|jiPg5T1t2*vOXS|Jth zUl?9U;A0U~n0@qLu$)~u|LT7E16#y5fF@XULGv^{Q{K00`pN5kgB3-tt#UUAOD3~S8hDlr8{H!aZbZ5Cwds9*`v zaw?g+xO(l98B=cPGatIc+tyrV(kOX>zm>D~pjLn!Uq{9?D|VM!pjys zV@qb}xN!M6^9|F7Gdwh$n;$ZsdT{o!!UOK8?~@pXs<}LQ7jzsvzm01KV;S=yPW}o< z)>T!lGXm;a6b0WTHu5N(FKXuyV|AFe`p$<*98(G(6{u+BhCG@x*|Afuj@h9{GWJiH zm7w=B84i2d>Lmy6a|GSL#i?*b;o{{l7yfAIMM!3r9(>=iEB`EK!ogXK&1SPZgl0}M zUlg>6`*4U@dy~NhXNR-r1X`FKZZWGkwb?f~FgotxPzsvrcw>Vc6Z;3=Q152j0vi^N zghLTdca_-mIFuhHs_Zc4f53TA!&{$)q1DC1B-F8G(L|OyqdA-(P!= z?c4veE3R>NFeE4nF$rya-S|MkmQ9{T_VJO0S}#)8KA4ic_r#2VQ&n=`Rr9^19wdsh zDho((e3?_=C|Tgh^jqfGVFrP$AF53PmN5am)qEUI0y@rz3~btMlvo@qIy5+172W4n z++c6MQ+zK|F=CQJv?wd{r6>IvJ4$`T7d($CiaF51r}Y_gyI5^?i|Z zlLPlb!B?yeF-v$9KFw&ibxPQ(YS^l(ZkA{;ot&EY?%U)+`a@9wRHe+SH(T`TN(u8Lp& z;L)(CzMrwZ-r$E4Gs7o&7H2+54u=m14mq1R=_v{_eq8T5L!e=S#)ojm8AlI){1PT< zpZKfBzCo6?po0IsW6Oqot*~osN&#kppEe)z+K}IWyv5;=!!#a&E7~u&CdJA}uMde8 zZFB$N!^|XL!^529v{ST2d6GA8^8trh91QoDUg3`_;b$>*itlu3)LJDW{^ys%1)r{_ zpoI4oD#|uW3{tGy7rR{G(0$3eL&Y#kVIOBh^Sp{V+DtDMXQX|Yz&q=M3-i@iyzH$T zoS7zM-{Wx5b6=t1rf`$H`d&x2ibgTBL4wSA7n>!HP3t{k9yFQed1i8`-r;0oTHd7C zn5y8Bs`20kPkLKPSWVvC1@E{|M{}&mzbjLcz)v&?XeC+os>;I2QM5vzg$L8;)Dc;1QW-s#0U!m-%4SdzJS9PsR_?x zc~8VR-s93e&%MT&^`-GdXC0;8$;E5M`s>8ec^8u9Wv{e6{vcDLpdUH;@u#n%E0r?0v(;S;f2r_i zwdADva`&VZell$NSEtw?lD1z1kAKjTkzj6Q5!mnO{xZ>Fi}V2* zUQvg$IqYM6Z{L-u_|qKfD7Ig={VJ}gL%<8X6t5;*ag zsV$MCZAXjYTu!$BB86=omb2Mh4m>&OCDJuTMMB0#(o@Xm`$VRL0cW(@+v6m6C^T+} zDpIs^46t)-*{Qfpfu4DKQiI#>eFY9373`CMMJerc7K@aHXk z4-VAuq^qpyP+huUGs~NUYY#ew+z839WUo>Zl8{*OaPkg2iGZT?)f@(Ml(K!8giBgj zeIHhc$#5oYF?f7{m$lL2LX%bybF+`3%5#pU<}i7VgB&vF`5PV1X=d;o;NXxKV)!)Q zJa}Enyzg}p{ho(^8t}=p@Yk($G8GbSNG#<@KQad!(vwY+Nd&A$j?9VAyH??4uS6W zEi)uM*cRLm%)ho+L*;_aO6!*eZ=Zi)YMjNx5#k-1TVTV&rEn<1ghjjlq5Q!PCx!*EKGLYl=+k;R-H?mnPZ z^P%!VA2JwUwd@QQKjaYD@1FfbS*T_8X35Vf&Yyl>ej~W0kwI+jgv<^q6|un!eb1=}5CAT;P{eOVQPo(1Af0X_r1YVKsuQ-;a9oc9DAAL_F>WZ&qCP-K`V&A(SEPSANy?HL|n<^>zVxOug= zF8Rb;_W6SLI{uSu=TB=@zsgp1Q=;Cm$>*Aa_yPx}Q0*{lxwv>e2LZ>e0g45ZdnY}v zxX84?^6zKum15d^MNf)V)TRAd8XdtLqJ2&#jHgaRRhlu#P;~PP#t~A>s-j1f-j_*@RpcIDB~jQSn0s2k*g_2}vJP zxz=~@Sz^rI(DX*3nbYAw6A$D5VD;xK)(9|hOj>`@VX8<&1Y4);siOaV@<*E%=rz%gZK~#nPgrkmZm;Qfo zt1K)zQCT4OSl>mI!Jvg9`i3;qOXdJo72zNi1|Q)|Hw^+<58V@W*kF6*@lgRrhJs?b z500@9C(M53$Pyvoc2A^ndANnZiN4Cf4)%b*sSQagyaK0$`8412wawzQyX`TdW$FZ1 zZAq3!?<&XI-sVLGlN=pc+_-kQIOaQ+P1_n{`mE)kN^_5`PC*V|fI5?dMMD`^(QW_z zD;H*Leb8a?b_&;}sr>5Ui#w0zi&*?v&i3RzvkLpM4ay51e3{>{Eq993gBelx_!cD! z*ydF#XlTC7ZZy!m_qjnXpJC&IHb<5#2LmJoZQt-Sz2TSA3voEdvA}fl4x?Gw^FFQ4 zuf8Or=q1c8;F$T6r<^Q*=F1d%CtN~LWw6GrRXKgSM zwSC!sis7L@|H8z`t_=r_9{gJH$GHE8VqcrwzrdwN^?vtP$!VRrbM9ylKf7fxFJ|mN==y9+%N%2QhZdfE-^0r_+j~>oguYB{ zF8O_;aq>YPG2?lHj0eJ``XBHy99&nx#v+jPpCRG**Zogz1ddGnw4n9jtqoRe{0)T# z22Sja|EGW0|D|Nfk^|ozt~d6s2)Juf&ypkUe&9fx{r$g_lRQ2!Gcq4CckE1sqro<<^?EU)@p9B%#U9WT^i@`q@;Il)9zfM>=0V>p0k7@&Dz4e`YJZ zg%(Jt2u;=M6T136?sszElm-vRm|{#av2a9|E{Gd~ytU%E!wraV4QZz#)x)ufjGi zCLy*InJ&ygtk|P9{Gi?<*{x30WhmzbJ z;l>2+Gm<;ga&oNpCRm)XdJ)9m5VdTV7>9z&!$arxD2Z5zFF3#}`(Odz<%1uEG}xus zEka^5AIvdhX>V#cDBf~(%i}}I)tBU#m>hB87U*GEFK|LaCHo$SyX;FFj|AO(!NvkX z-DTR%AKOk{3g>iw-*_t~K_se&ogwX_LcM*I`sKzS3ln76r@Z^^dacv-&wQgbyO$mi z&X^WoSb1tf6g!{XM4wk-o-bc^RWHfsK0aHAc|KQscKy-5k`EWy879{@-=A@lzd1?s zh4N}&`NxOVvkiVN$P#E=!6x3x`Y7OUfEoXh4*RKo z(|?rz*Vwz+u`k{`QGlIUn?vCS&%&sE{rgmY)U0>$uhV`d*kN>g`K+J{`)Lgc4sy*k z5{iF4rmg?q8PBp%`9Q-ejzdQiJ``}QlC56i@F9S+|Huwo{k1)NZIh)xMY}b;VO3yl zW?U#N#CmMwIr+YY=CeMe_kBEGSEItC@bLh9WB48e#*ED?9T^*<&Z0$Lx=zOT?=IKpsUiMvmbae31R zAA?*aj+-Y8ELF9bUVc&HaM)7a)-*>;#7lgpK!8%0i^POOI&LfnFC9~2Q&n?hRK9dX zL!6z{*5Qnt!Q=9I#$QlFFz!C&fCZ{emVGH(-L*b03RNU@b^D%?sHaL&gudE>d0j7bWLCX# z_+zbPE*aQyB<1tPcGd?jGaes&@$zz#tSE~ghg-`z-eYV`25zEEio!=1WUW{ju=2qK z{=!|4RklRbnAjO{GhZrRq;TM;zn2!rf(@eF9vaOj8l-v4>8lktg=_M~dam;1uRQRmdM)Fu{whXyLB~b}{kK+~)^O=WPo;&UyTUM3Z6$hl7MbOQTX@ zc#O*NhvipZcCC^8-@M#Ra`piMMwSWOcPkG+Z|vY|d>+c+5yaeU_0XY1O4z?e*=>iS z*n|@;+$?*P7+Km`9P}p?Do1cJ@H6hd^nJ-M$6E?YoD(lzWHA+J$T+Y-t}0HN!%##qMga{`E{?ZSJ1%uQJ2H0cFqC?6ER&aANIYnj^Ov?8ofG7}8PnGshzlro@n;d9 z`(RbTyr!*;i_|wn2zz8a=?PjOCFPZv5aJy0(!w|D`;G}l0-ysZ1U@unWIknP?pMs? zaGUoe;gf*m9&M)ejSj0*fBmufrN_yp_|i(4Cu#kv-F&MLw;$%Rs+(wIJ|k)Ip{o@< zh0cBRFDP@!>Ahg-tcy6b@IzXB=7j`~^=u82P0dRWPWUHa`c{6rR`9=B48K&W|GzXW zaGtN%)&BYO%}6#Q#(!b#>finN9`yL!ZthGue1BO#he8A!TW?i>lfnUZW(HB^8ySv@ z`Q9;3%*P%$FFRr3O$7%moeB1=SpLuKznhl1LJF&1Wp@2i{>vy_;QF)?blD>8`O6Jd08 zZz}AmpE^17;2%DgYMT$~G9i`W57O3!b3NFh!@uq2*96f-?c)VDN~%--&ENXzge#T@>d`I?{o<7&OY@>~V> z;|=nhp>>+88eYhC?X&&MYq^e?g=SS!Yxsv-SQu|agN!WNZ_T?Z>1nSEdKFYr_-%&k7EJmpK1bCaOj z&X~$vr8N283^&e(tM)7gb2cQ-dr)Dgr?6Cs@6d%f5k@n=4%tgL6-1i8h%hu;NpWVs za9J91QA904qTq}R`;=og8SJo#+0H9g|_dx7|o|M{9?~{O?b4z=S%BLkFXSlKJODc{w@ivmja&bx>tS$^Mi;B4h%O`|Ll<9 zi{Ux4fKN~VV+kwo)M)iRDSC1ZM$h+{Ni|+$y3`c-P3izwLK817BH}$ywus3xK5q*A$91s4B9&dV zr?HN2xl@DDhBGECJKvkI#(h}8E%C`gPWqzesSA^QG>aP-bnV(CkQ5TzC=hNZ!l(Jl z!dFpamPMAc!+zGsM;StdZkTagu_>E0BURApzyxOQLqTFYpXk2fIV702M_J^6e}N@K zkNe(JBCKyTlsLVcIhvTwHGH(>N<^8I?;SWHSuAiMglmRu@nHs|?He|#GBHK2=r1); z5fPF~JkrH)u%TcDf2-27oGt>`Pxg ztS@cp@N7<&=)SLTHeFw&7@om9S(0h%LH)DqBiwGs=Ox>3XPj)P6d#Yd~``+VmqlSjM-51A)0#7WS z?>%U+Xx=vwF&>A5{uYiLpXa;C^aw3m;wah3!OvUd)T&~$q&wo5=AFyS&srEKt2h*# z3cUAZZ{m*I_jz~3vp6zLVT){R+Q7k_($CknQzFF!e;E^b#=v z$9sZ|2R0t!;BiTC`zFBC5uwKEuwZ!%hl7^vL5|7yI>ef1a588Gw4CPk+=!89c#z=8GGY6}lS>tLCRnl`p7QOWii~C9W`^L30NrbB4-f3ol4xA+#Ud2w zP;g!3Ye2=6W=2K<@lJ~;4;}>Uz9-3)Z(*g-XUg#Gs8fSKKa0T}mgS0~jLN3(E9{t7 zahyEKqI`()3@a&3iICNV>}T zlY;MoCdLK3FE3&5&LPfiagjMTnoGiTw!hIgzD zIys#BEK2tlt}}V!+~UT4Dq!EvhZ){-&)XP+R1Y2E7OI}NFqPYzT_KwzcrkOItAq%{ z;jYe!d!I5f_p>qhgtIv7bG0}|d2wHHOpstcAj)_Fv_N=5qxfD49scgaBC9XRvmLOk znDQYZV)vzoiW3&hJTJtlA=PMbqpadmgUp;QqA&Tnrv&d^>EYEOC)pt=upsdrTNKkP zmJ6|5hZ@8LxDQNlZ80je=$a(yq9r26+BOSbe6UV{&^uS8Ju0owve~&zO>~64-U_Q8qXU*=T4>`O;)+Ng~ zUEmXHTrokVas8tIa`yT{+*i$?$QJl$XjdO>V03W((%xvm!BKol(^7!9QN8`(p?Tl? z&NDagHtgH%al*r4QSBuknH;Wsvm6hWt33rx+FSWuL?;SFyb)+^QjAnm+; zx0sc~eFlfZ-V;sFJhf9K1tR(s+E@i2&PbUMudBGtpqcl;fz;=z`k&3uEpPrYjsM`5 zI<`1fh79L@A&XztFZ8UpxxTX2k0(QlGxb&bg2jL1x%et$pJ|HK25$JL$RK0$YxjW@ zl7SWM8rlElLvJ-ZwD2?kJ26#i=5ZDUXSQn#)H}ISjqI)D&-JfA{=Z>K(2h4zjHmW7 z{#zA#KImBp$J704%u_>dENKnVm;227gMW4W%A@no3$uTcVDG-lSvNma=!a|h0p%{e zA7bjS?}+!5zgm3iar-LIvqFp#$^~^SD=Ys04?eo!eCEsdr!rqOwN2Q*%cG_^v$4TR zp;6+U;Tvww#)2j7Vu~CAx8w>~qwh^vVlqWWoPEaky~-XcymN$`j(3JH;ob8i_g*IBe-uH6YxvTGSu{p?eC|WoPv43tj!h9g^Ig@~>arxARx-j z_dD3EuJP@xHA-w&@@F0X25n_hmJxAi|K@EWF@1V-{i%a32@apymIm>B)Qg{fRiXNl zU|d1vKfMKED>Wbd3)#b`vht54XTsqPL8&<|QsSMepI;r^DYjQFgopj$j2|zu_xw|+ zZ1}S>y5?emQ-IBuwhR`{2B8NB>O5*41zR>~Fmi2YJK!R7xWJgF$01{8+A3WIkN(ByYFx;f%5POiL-9nKw`BFAZ<6(*RC9&%BI(r2CS+=({)QI1k5Wqd@ zz$tej4hQ3%j@fbnUK$_7o;bQFOc1kCl;E*xIr79YNs0TWfT4@SxeF?cRhxt@}in zrucAqB+m(AZajD_PQc6Xkbq!&kc?oXF;QNuUwmiq$A1v7OL9X+Ff5`Uh3`HyKe;DU-FBM8!S9#q118;*E>lJ2B z<_C=r%+?tgvNtq5k*J7a|LQm)H850uE-S+XJD%?LzOWkU16s@sM-MV6q*y0vZPY2T z(h^<8mVK~~?;X!U3oHJs;++C~fv@J|dc2fWe>3~cO8%{pRvmIoq0AXNUHl3OI{WpG zA3k+;d(g$sCk_GPGZ9u;gf@Y28<8GXrtK`L{1s{f=NTUfJ-gQ-*~j4!#XWB#8^?hJ z&1|_(QY?HG3QdgbRC#3V8Tt6!6yI01GDc)r9FWLpTBc+$p^T?7AS+<&k%MiF2i7I@ z2r*0%vF&Vf&=IQ?5Zf!Fd66mqfqS@;l!wrw?r_DbbI+D~cyq8g9`t;C#Gkc*Z*jpy z?UrUY=2ktK6)7LiNHEQrlVq`0JLZ8CpLLUh!Sm(=tLCI=RkeszaVjzYWa{wc+D?Iu?GwI_`mOcFU#jPMMazW!7)be z%MJDGZ0s8&q}!b%4ey1m6ZhS!Aif|;eU0U-#x=~Rl0k;jR@m{yay2ie44Mcbt3eg z4NfR{Uw2XWj+v^c_``#n;F=ykLAl}Bpb<3I4i=&4sD6Q|ey-wZEng9GpJw5$?1JykpOqWtqFi9hx4KRflztEiV3 z+GBTW#^EVtty~BDHNIJAe)y-W{9~PmF^BTSrSfOEYnDAwuf6i|kGMevhrq$^_WNuM z4-)u8*5Be;pwL{j%!=`W9FKBaf(-jrzA3ZVScE<}uo&=#a3}@HhAh(bDd5+78gOyr z+YBbB25nA{HU{?QNzoUZT3Qd!lyX*8_45)EVU_ye$RNTUBXF3r_~MC%v@Z*rlsyfi z4o+}lI=Nmk-$m3&VTz4BpTsXd3y$vI1dB_KA-XOi6O`2EvO4(iKUl`g&JZEAr9+K> zVwk5yfv+}~(BT##E=NBD#u;-2xp+mH6yJGvurlbes4uHh*kanCsOq7l(ZZ>*SoO)0 zoCUW}U(i!;Fq!zQLt*aq$;+g@Cq($nRY>6Iw$$c6{BV_Mwui=(7TFz!JVGvJa=Td! zZgcRkWh@bx-FRZt#T^?|D)c4W9xM11AJpJ_(tgk()x=jI{=Droh6smg90xqaxn&Od z2sET=H#M5KGvE8ZM5CBFbHj_K2A`D1>%oVA@Hc!^5$AWGxc;Amp^a9+8m|RQ<(L^m z<=DhezwKvu-x+i;x$^iYdFcbkIQ@Qne*2MoYO`ydd?)kqRpA;=@+%e`TUF$^!X@fq zgeYt1&uEw6S1aq+H+G(#e*m;d_rHmRx6r}%2lvBoaq-85az&OOSzi5+)3LtxwxbU7 z>Hhjx?%OWwrWF1;z_n=Jr~MzgW9)vOw_!T|VSyTVBhz#(xtvY2LYDl0+|v;GhrMZm zj6H`}lhncotep;roR%iYsPZ3T|NZW2$mDxG2Ui&UbQN-M{=shV*w^?p=(^_bLk=SB zo|jj8J{Dklz$P_)Z_ARk3mcMGY-!!IfP+bH61%~HniFcD9Xc3v<082He_WAa58o@W zB36@^r8(k@)1wuQJuA+L$#FUIN$eHl_n4T_;js9igP41>L9^{UHU=eDzLv)H;5WQY zD_OsDIMnc~?oeSm#w#JsI$1}AVTHiF4zZ>SPE6aY6w*zUMD#qSu^v+3XK7WBW>;c* z@SdeX&iIfazx2)r7aE_iiGJL&Kul=*-j}Q&U$i#bDr~ml5swjfcsf~_$(yg^Lirwn zM#niF0Xm!x8`|zUF)h3&+R4S&^z&hYSnGkk1+}b--Y*|aDF0~OugLbR@SU$l(}xEW zczdfA9x6!B@vw+6VARm4bl_>PWU;u%o50<)U8W$dS}8)W_+QfD^e=xZY8jV?*?+8` z-KKnGLW{jzjYRvuJ~q2NmIW6C7+W&e{&-knrqO)e=DK$ z#e`-fra1--E0|X%9xV*^?ny}Cz9GixVxn>>u;Z#=quY1pNdd9VJv&4>4D=ckwE4L2 zEZ=!DdX12TlOjJqo8#etxXXW!FR8#ttml-b>0ULre#%%1yMW< zO*L#v+=(2L(HB_`tPo^m>|dh0!a^dOu_576l8Ed}-6jVGqX`dLigzU6P*4(Jl0GEZ zQRV!InL+%LRzQG)OhOa0S|tm6@1qa=Q?_&V@Ayz>x%aX2C1~zwQ1etHv;=;ve$`?#3%t99iw_7>;`Fni0h7 z{`AJzf|{_h)eK7+XVgk??67MWt=+KsW0-<%=#Ce4GW->li(a$4hrBU0n`a>3J-xyA zQqfbjmIcldt1mbHkYx3#J|r;ltD@rPgAaI_=BD)i`+u~f!GtB))PYO%l7d6|8Z8+G zfeFPEn~t&N@OUhU;NAO>Lq7YWvx=aPN12oL84(j!2YtUj4#uhuoryiF?_I=Jba1y# zm^eYBQAX{%5(kH2`^I(EhhJS}F;QX7oDjCA@;!Udz0CJ44oWd~JQCt<4aM^uS@l^P z6djKSOkbdKL)7}<>MLT3+Io@!?%a&k{wwq}yI7BWZMflABJ-ev!=Tm4a9_9MStZqg zg%OF(>?ST9Ma>Ir`vZy{8|E5x2#Qsh8TuJbeJ>~G#B^Xwf(U2yi;H3@$y0X zxK&AnTic*y!U3LHU$vI;aLNcw*<;7j&$B1aYL<_!#rf6k4ZQ7>L}ymDGyh<5R@F0n z?8xG&_iOoT!NUp`DKG39esDc4n6QSaWz(mJ56`xX?2tdOgtxK%fCP`~iu2l1O+5M` zD!(3HsNoQGe4t>@_F+<-ozTyUuU_5f>ly;;8Mm1K?_2HJn)=FznW4g960e;=lVsHz zBgW=m>!U>ec!t(wiPy)-AN(-=@PXv^{hM|!5=w9XB>D66;ZN_IWrNcsLZ9Zca*57) zc;OnyL6bT=eOB>@3JMGbfBjb!yxmnXMTyZtq*>uet6znOfz^}Nj)V@uC7Ky63e1??E7!`;LzndY?N6Gzy%3C1vr%;EUrKr?f{0EIbV?k_7sb?^vmZ zIM%qZ9MtqxGGXUk^!ecfNyW92+98F76GCklMNCj_eDvYOJcAGQ%nscDcQFR+%Q1;j z5r4mnGwXJt@xecWEDALoVh0~6_;N5DvRbl^y`j8epqXrLaM5PD`Wva@GQU7DpzR9VO!Hs*Ib2tDM~gj%((O zY&(>glTI)OBt(2y@@CL=y3jIVhDAaW#}X|r=NoNjlmwQyHc336zKn03>gpw87AhKx z8#*;IGFUrUU#u1Q7$n`r$atneU(h1+l0lqhLe$bDyax`7eBTrHxIx)Y)+CErF~9nf zoXP}N&xZ}tsgDG{v^Gw8ut_0FIHBQ&oRlM1i-S*yW8yR^4lysj2Me5!oZ@bH%u=At z7&g23NMcBkMa>-h#tZ7qoML}!zp5OHESSb)tJfd4MzP>}%L2<7n@BTcnZxmoy zP{AR1{NE|b<^v9^?AY>jmLB*Zpx9}~?`%-PA^i8i8RmIBjER3(15}s~)Q9ngX8h1# ze)>N|viU&0*1F6BA#whLE6bv$6qyLQOgyn;$Bq~Enu~nHY`Zj6ShQ5UIMcnCpP#?H z`G-LRPs0Hb&>hb6KgfrOPUo-j;E}Yk@8tGwKjf>(k^H~kJ?h7)#oiH7`7^I zIPmXa-(P=EzZL~I(H)A6$95?knVzDJ3}B!WXBbB+@i zv%Z@1-X{wzc)st_W989jR4NG5+9MOBSEQn(%5Rciqem7t1}QS8eBzK7zErI!^Cb9P zMS|j?69vjn<`tv;rEQ&nT1yy$R7x0FtHP|TN;pZ{jdAgM7%lx*+zFsQ3pQ8@v`y zVA)~cW7Qd7V8i|+`DvY8^1=4Qw-_BHAMkII{;_IsZ?gy@%jGWS6OHSCZust}) zAhAc%Yt5GTPo*k$>=XYTv;26og3HGbEBI9Agb6Yxcs-cH%gQ!Spz+#Xg;N(<93(xg zuC#h6=6kLca0p}K_C6xuATBn2Lc>8zfd>(X4+-eV{5eq0qR76p>ER897G;ejP=rIXmWnLHZ5gef-j7VLcRBb3du*58|R z>U42U6aEKY3;{MQoQfze(#2>`!^)bjdR4A#kDiUlpmb& z?&E*ZpnlX6EvhdbDr!tLKFlD!=YZ5lfhOh`?7WOy zj!)gN^fbfu9cc-yzCAqbzM4rfTrEmxsy0aOkmq9IUNGspl`=7Bu6Y6n_o*_zTJpVB_2?t( z|8k~{vJD=rs_s_r3n=rQdip?4#?PtPJM9nRkOiA8^H#N)l(+ls=i+^H7O~{$bV!Y*uW0I;!ppcV@*zSy`B_2^m6P1LbLz@m? zI>XH(keZ+7=}@9DNA)e!(Z=S^Rjz&W^_ttV+tnXz>x&VduFl10;bzbknX&Vv$%X>Q z_e%~oh{||zws1@no8Nx?kVV7^zAJhWCMzQ99Ysr?Ja7E)JSEl7=EsYomHn>|1uu{n z{wK-0XnztqkCkVD+~-tmn8r}osHsE|KU#qr?igQJgPn7?0`elO*(zU+U;&j0RL15SvT zU4Lkh$0)#`-u>b8p9lZA8Q$3K>*capVHEP|eQIBH?*X9>oLEY!XXmD&&XCWi3fD(YTar*k>&#q&p(`y zWB&c0E%ArR%m-%_e=r^CHSIre#(s)OLxlm$YW)dyt9n@$*zK6(6=H9&iXq~k^FalM z10GLyK4@al;kYNlJmpKl{MS$BT$zt{1ha69AJva_Jh8dJGPFHAQ=c`Z=QQ$L6Qv1GGK#I!ixW=S|v%Qc@@`;#wn?Qh+^n^Wu7W&oa_S_H?Wz^eZ zQp}=|p(D0s1=GX>N0j=U@9`f9>-y@n_+R)}yNOM?Y$mE!0{ssxnLj%wh%D`GIwRr9 z7WyY_QEP*oiqpadh3T~p(_bBHday_G=&3VpAGi+|>~(V}G;m}yj9Yndh6ckQ?%MC{ zA6OYO*g_Z|91!7WWLhyvz2PBO)}Pp7x443^PXkyY;3IRRy-h)E;nH&4-cCst2V z;WwTEGdL2O_!~hd;IcoE66kF{;E<-$-^s{QBiVj|De>-1uf`jB3=Za3f8P^479VE+ zZO%IROAkH>sQn7M*kHrLrR3w+GDnVyb(X+?w_}YD6jJrOPCwb*?)X5#RBj%d{KF6b z+S?BW{0^S~!BL1kKI8)rTj-y&;TlUM>Ue*OP8ZiMaFVa7dRlLGz+ei`0T+e|(`0y- zGFGz)GelWUSfJqH?eUD2S>VA1-YpNfeKlr?Oz1E^w7_CH`=JL5SeNfeU=loZyGf8? z+b4m@or($i8d2MqL>&=yd~N%XX!~kw3cqfxbn6W<*--|7iXfyfX@Z z{7W$q+bhM|@j>F&=ILE-mVRvs|5zIG9ZVynm>MM%`2AK1{j>eR%A#L!vV_g-Ba4Cr zgC6&;hetXXVyf>|$RFTgSYX5cbAc3l?Y=_=i5k-XRvt@o_*19ybHN$VLAF2sC^p+j z1~^&?9GoM6fP?kH;g9-9w$wjo=1gRp9U^)CLhjnXDr7T*s=dq{0ll>dBqRK>sopo3T-O$2OQD_ zxIcU_KmJbs!Vb>H2^AcCr4N1xfI5Cn4{A7gL%nL4E^$rS+9F=ba@baYsUg;bN6nR+ z=lLSehaBPyU$QbTsb_B zV>%fN+=M3gD>6(fuM&iS9|76IDL`TSzvo>Ly2bd3?9SERg3}> zY`v}T!X%j_qF5C)MBghih<$Oq(2_ilvvF~Py8-u=9!t?QjuhWFY!ei=b2)@`JJ02C zl6#h;A)z4N84xv%Rimj*kda|=ugw%yl@N^(lUY3MGLkkeo-Y~=Dqe6gywT}#S#&a(#B9LFbMS#e_Qwkq9D+`Q4WQF( zm)+q}ZHV~S1d6{Kli&VpdLYllHlcz;$e;OuL%Vl_hJu!fz{`y+On!`t`5tl73R9o4 z&3V?%ti#iEkYkFa(yT-6iOq}H68a9NO+2ZX&&6={C3}*97%R8f#|4WQ=$%xxUmOoEWRX{V(RASxhnnQW5NQ|2{Gtd6ufr>v zJ_J0F@Ni6RJSY`YtPoS|p3pwY_T&bE3x?H=j?Cst+_@K7A3oY}a81S?AMGj?Y+@Kj~M zIyQ$Ujt>sb|n&V_`_(W^ZWtBKeR*g6ZG`1ylJQ%MQ$zpL#$v7&ivnj8_YH|D%x&zP2RXP8YEKbs zl2{xfa43zfBVhWa$(OP-nj{n^Ec>#P)zd<}qcPL5F?`VxzBJ3{F<%l378$IUt61RT z%<9o}-9>bjLh=$t?jTvA4*jJ^R5X&DpY}AwWjqX6;~XVje1@I%AqUSr#pXVTi0?}# z1^rC+bo-o-FDG9$icOuAVO%mrGPWD zL5Jx(9<~@!?mZC+EDVLQyKYVrP~iFG!ncnj!If$H9(lp`r-v+z^m|PIf0b?KO}5=J zo%O+=z3uL6g`Vmq)LXGWxYYQ56Zho@zf$!klsWkB;hgipgEizu8~f2aAOCP2o^+sL z%?|?w@dIar4>Igymf`UFQ&TS|e_%g*L!+%DC~r7!N=V{oWPG)=pN-)>vlJVL>jM$S ze--r%7UKMeq}I)3(_>@Ukj41CaVj%I1n9b6`-Xt}ApS-s3mX=;SM&H8nIyKzF)?pv ze&7(r-}v97K0<(dJ=1}tXC93UrhMQDv)f?I_Gx)%KHCPVF1yc1)=T&CTnt#Gu!C=k zln8^0ph19UJL?R+OmD{qE~h>&w%%fgC%O+68u@)bw9NbBSSxUyMWHf|!+VdDoPx=h zSxsVJoJt&X1wMBu1RQMJtN5iwNZ_l8=_$`I9o()B9tWM+{4+V6o1V7aJ5tix?Qy8_ zAZtH+U?P{fz;?mJ*^K^*O-sH{IGFIhLSfB^DUR!_BBGp*E3>I=5>k98>@97mJ%>Y0 z@{yqPr0W|eeVryCv0P?CLY2bSW(PSQLG5tkFBu0JQdwSCDNGP$5)ftE+bH0~|KMYB zf7h$||9h@=T$;=o7`J8bEvMCfs|)NWHXN%BTA;|b$mG>h)sr&}*1GJ=dLg;iL-%)9 zi{s@8QJWcZXYZylI6kePvHIv@|LYni9obAA3PKgy4K|`*P2cYgz9)b1LL3{z!yhR; zjE6#=78p!nOgJF>eno|OgN`S|f`1GJA`TXcGuaO`?5Rr z2y_u`^_HG6m75&IOud}<23`}xeOnF7C3b+XRqJ=;yzzz0ki&;yE2Y5 z1z4BxvTxvFIrTxvj$vy&PqTVIXk#6oe4V~9VW|7Q)%7XcuQeLlYkJb!1Kj2t$ReBn4H_^ z889iUIxS^&SlP@yxw3ghlY*ImkLpp`bKVji%1svbJ)%OV4?cJx`DMX@w7(3jS~7Cq zufBMhp`Vtl_ww_Df63ppx_jJTt?1(1{j%88k1mU#q_6z4pUU8_b+|bAEm|9 zbfI3m|M;WG3icM$tSd?VeOnhk`*6XTBlU{+r=`vZ?+ET&?OkEWrXR*7^p2^aZlzG8 zg~4>jsne$$@R(lpa&bDo;<1Gje~W=cf6bQ@l`pwCxEy{yzhmFP&oJYGe5dQf2?kTv zADO@54@2X}r|E}(Fket)VfEVbge_3a{?mKL>&yr0XET0K5S9<%`uX_>d(%ROJqn)d z*c%$IKXP|43hA2vdv0xf}9|j1!E$MA!&4793X+;Pa^MWtL%hQM}$oU6IKk^dX0| z>Wiie*U~0j4otCO<6X|!_is-ed$Z$1z4gTx1;p7JHoUsYadb&Tz#I-YcY`2B(VJB{ z$_(ObL#A>*Xa4cQdDjx|x+yb0^}NvYo^5ny(^=p4GZUGA$|!bvT}}U<6SQbW&oSML z9$&l{Uu8WM?E5ZL!e|?N*Xfr2^U-DeQ&rUVhc7bU`!@Pg(BZobJLLAr^US}SOT{!V>R>B6a1)35KB@%i!J8~a67+$|_<=Nx%B7sGC zF$2#NgO?8Bi`Y6kx(=LN>cz$I^o)#!Dr5A8SX+fo1t+Ex+7e%yUak#f)#}hPW@gl6 z-4tT#bW}yrP(R#7=gnCGqYX104f$BaJ~%OQ+X_78@}BphAi#EEa+4rOmGd{|6M{YA zZHXRI-uE;_?5;OA1)Pyd5aZ4@ zH-9Ym7n{%d0NsZTwNZQ4h+dvwv*B;`(MM`) z9vC*huzs-WuZs!K>Aw8=#m)*PCdPK3UQ{mcnWx9iqHQ%LC2u~zgX^M?g=_iRp7rmk z5&LH5V`6;hdPn0!8;KV;#AY0b6XI&`?&)w|Sk`nPYQA3x%lpM)a(Y6s2Uc+$wCGrV zqq4*1b&K=oHMW{7&U7g$3OFfpICoe`uyL^n<2 z68ibzh3LIs4H8+CB0^Z#=g2&mQ~P#;g%#%>4jUETmiXHXY+fv=Rt{9y``}NFMTq-{ z9cA)e#}@uEl#^?`U-jbMMtz3;66!31Kc=xCZ+;qSYkPV_`9JRnGdp=-`HO!&U$M3r zKQi~)d2#L6KNtO0JUQ0c?8wt(?Q}1h>A=4v9!`gatg<1C|IAvZ@x0!^y&>VL!h-7P zN4a{MZD#fxAO3L`<)89@TT*UYeaPdaRknIZKTKK~q>*Fr+`s*i{$sae`4;kQ_YbV7 zV?WU{@tsbC5&xk*N?|K@ysTR#!kKUPAg-ma zuivW`B2?sTQDV>EB4A@TL7xBrJmFF^mW9zy1>ej=)D^y;-Xb|QwdrX2{j!O&vgaNP z+N@^u{*uMmI-g-S>v=1!iBb2n6AtrhKV07Yc#4bK>m5syD?H>|7Ulb1X>W5l_VB^I zmlAz$i{8qf=-TIA`rsdfPU}CRDGO5{vdFP9?pCgoS}k9iHpZ)**1Gav~89%fdKiB^b zEBH_^@Oc011xwfzL*K6y{9D5#)c;gIq2IB|{(L+Z`$_Q>h(<986dBhH0=N<|5L@uT-|>+m9BobWO;q(RYrO45(yo%5?f<- zk*P8jHAZ5ym$eievFpFeIOA-DESqZB_x1zn<_qlQZp`55XLladUG0^eHy>0 zTQYX~wKWyIK3KpI*w8D^>$Ygex7)&f5@MIXeAvaC``j&`kL9=~YxgEWLD7dNx6Mc^ zeR$>X1%KAnb3*t<_jHKc=&|2;J}2D$;02Ye(uWGW&(2(&&$4jlIhF-0N+e#&Jonop z*nIR^$MNcmE(V5s`=$#BIIiw+$e7n<<+f$vUd6|fhYpx2gcN+-lPAdQ)wsSwjpazv z`LBgD?%77{JSEByec0&14vE#QGp^jyFVSnC_aR30fbBt+-G?9C*wNuGX^~?x^JIyx z#JVd?iWgW{Mt%&qa@fkpqUl7I_EG+{iCjB;b?1uOK0mgC<-KF)E)NrVzupwt<&s*b z*c_@4S{Tc7>(BDPeB44;s=Ia~U$@&j9gUa|3-XjIl-PEZuw48Yc;SSNXmf0*+j{;+ zi?Uz;kL|yF?C^`uiZ{WhSR2E5bQ_NQ&$4g&DAzPw{KfX`>F%CZx~3_;j|5I+ef%Mq z@JYSk{mRux_q1R6*l_0<$B7v}iNO ztK$t0Mfx8!Y`jI(#Gk)j)D%$9aFKl>8)w$r_dZMM8Q_ z|2L}CFfL^A%J9@@bNa2D`{{?sdG-&7n;9w;n8n3g?4AV7eegm4a0BRc9z}-wDRlxh ztJW^8_~XT4plIs;jrs8Zcc7&OWde*3><@>imQ7a-cWhm7rDjbHPl{LAiaiJZ%@J>F zK2YEPA?ZQWWfrajCUQ*7Q_DE+2eGs^9RAS4&-hQ~cYULT4f~fQ2ZL!G@<&y_GOST} zFdjdnlf*5%S#;3CObey+y6g>qpZ$1gIw>=RLD)`@?KG=RQiQz%J zOUpTV<_G^@$sfGAYMCLM!vU!^(sv#l5XfL-%X+oOAg0ECV!rdDRQ2Ppj-UF&ZNIe#j~?mUiHi%$X~8#>=!z>462) zp@S<-9{h-Z{%@JkhY9Q~2R|;jpl6re!o=QwDP6$8c=^BDhZk0UZVvonEOWB+#KE?D zZ9l`t;)4YrgG&x>D!F%4`=G-cFCK>@!fkGq~hwR7$s`DVh7*lyUSsu5#kO-V$`-JKJRS zdmmmD>ux+})+Ny))7!kD$nrdgQ^12Mr3WX?ylWwnQK)jLal6)so@hBqIi|~P?aYg9 za?%dFg|w@*zGq32_{bL_c?Ysm*o#_ZX} zjU1e@j{^9why;{AH&Ei#;?`N-pnLp-6eIHwl|K_CyhAul&+&90U*Fz*vtbiI*05J9vC})-~7P7vxr0_E51-MxXh= z`Ue*F6yXE*5BU!qxxe^Bl54GS&5s`pGeSgL`d_g29BX#CB|JCwvD?Xcc09`!pC2ho z-w-pG-FYT|-+|2vM-I*?(Us`Qux3*>s|ev|vkv5GJ*2$YxyI|}#63103BNBTujgqu z@R96PtKQOFFm7fLXa}8>s!^cnsMprqvrVbdw(duS%KCjGJO6$=c%)*9gz(RA zhMfEQ+MY3HQR#&!SFZG|WDW-tH!+sXF(!9l&q1plWFnoym zzG3E{-0xqv`y0Q_Ynd;f`=@sMDFXww*3$&&-U0hyL!^8L}bU}=K`u~doKgtfgKe}rF{OMLq+zESwO>BOC zyBdEWi7VPA(|r8>urxf|kY zH^jZlI^bW?GDW5%

    BzMd4n*SBvyS^qP_-u(aC$@|-9E{Og9eL{0be83Ivx951+ z5@t^1VYGhycK_Ok{f^)E|4o0reai*+>WrnTtcPE3++-$t?vqiV^Ai{DnJ+AEEbWQE zU1M>I|KWttvkNT0{k-?#xsK?LoU|R@3KrVGQ`-v@Jrz9+JkI|P2$#0oROaF!ifv0Ay-M6k+l1-#++s_L{3JJa^9{)Jvdu#S? z@#eSxe;q756`!AWsJrS8rmF2%`EYgP4|z7B z;M_IUuI>h27pxE5xe+i!hK+?Sa>rWzaCQrAjsp@iN+-`_X^znIn_d;i$@wiRG=w3z z+VO!x^P2B&2Ye)yjHbvjag-G^Ms8VR%f`v2{7}InROU1X_kw~-7l$*d1&OR0y3x{| z35Opza)e0onr`$s(ACHxsUgpnQT=LNUjO!=U7x2WD6cr9HO0wezRvFeEm?*P8y3DK zgZK9XpGv2#JQ*A8ZD~F8l&HvZ}dHCykM5zgtDvrLI)4+Xqa>4Rl{oU zEsYI}3`i{J3G!{37kB&hr}0 z+NbHaMfWfLe=yGW%b!DM#A>%5wP2rHQ*C>?M!Ypbsis;aT3Mo}sl7^g`>FZWTIyvP zQ{PJOGrRqBd$`&}cdpkP{BLcINN{XCaVXuQzwVaL`?|%#Mh^YT(NheB4GyTyeH>U- zJ@Jx2k@>r}#PHiv39Cz!^lt}9$4rn={WZg)b+h**=cIbaB+=SUIsJ=`f84OptbO4B z?Uib8=iK)D2`AKFxgM|k`RrNk{`ZARO=_A)V*cNYh%w~2^<+_v7oSp12dlkx`aW@n z&-bJ6u*=uPvP6jMF?^C={qeuhEFO+X4XdW~dk+%6RrCBPK2UhS|IKsd2dlzVSijZw zZu|E)QefdFp5_IQ>@s8=KW!{LcTB1F+rh*G#XmhxOnvkHk?Mj2GQD@VsXutIaG@*5 zPjTIqD$W-tsF?oRVX^T2oEU$lyqGVK?O&<5&zaL+XLkEd>}{oA8@*2JY5w2C6|3-T zmcoI+-}il)`)ezApIgW-f2`$x-PKcaSDLE#*uRnFs#~AAj%DqK<$Hup6dufebo#MD z7H@DvQJF+yoAj}(e9l*Gr{x`y@_4_pWoO8OqfcM8BsAD|3daf^+_l{LUxJc$Z&K^8 z@O$q)JeeJuZph1<&7EJly7OzRT=2PMpZcX4j(vaT$X=M*eBOagL+zj0?_YJX5stDd z`Uxd#CmmUNoVl%?>-!@9*KykC^Ox7_#HS0)agaSA_rLW(<+uCCZr4XA3OjKh<6gf$ z_{Dw4L(2qfia!6iT|XhZxm9}^NAjUBFHcX^4w|#;P5R-s#MJM{rNVd4yO(t|+KoN% z=UOhqXvNoGCK!q4Ph2SZK{-YD&zkoSo;JCE+;;cz+x?yQ%nCng=T0cwd(dz~p2$RR zZO&-Pmbw#qCqF(vHDhlQ+m9CCH)_9r+x*bXZjG0&zPsMU<)0HP_wl#lY1jVGwBYXb znOIeozTVIL{gb!L*&bYx@RZ{S*w}x5QDs7--!_Ht(r@C2q z`pSQ|T3$RVl#jf~u(O0gC${m)H@@Kaj5#-cA2`s(b1QPq%AOK)E3tzdQsR7@?f1o~ zb2(HfB$n@5kfDEgg`MYw_2EWITehw3mdFV;7qeZrKq=_uuE$viS2%foI_AD6!9e(^ zEt^zV*vF;Y=1Bx*3TMsluMd<}Qw?L^DV_cEe~96W^bLm&Z+*Gw>TRw=8+NDrzdLUH z;cHF~kG*Hz6PdrS;P&g=d(JP~#>X|&$9`YWCgn9#@6P`vsjzmPhp^cW@0%6Ad+m1yzh!6f z|L|C(jCXg|QvJD`1B7?oef7GzBkD=c?1|gwynZ7bp(n9=vyoVic#r?TpWkvzSl*US zQ_PsCmm?Dm-+j5D z{#QKi#6H&h7nd>~lymWo;{3OaPs*|}+|lK~vpZYTgNakP=EcZ3e>>aUR>Qe-S5Wan zm4=-s+G3S{8R$tpS=RD)QgeshjkO+n^d zX8QcKy!PFfG>4bWW(KM(XWjPOU+%cb^z~uo{q0;%x+gZ?^SsCO@rrg+{rx?R55=Vl zJM5nS&zZzhyYib5bEm8Cr}e&EQVjiXCvKY6l6~&+{+zJiOm$WMwep*{o)NCwD7fK( zgmB%o8!JD`JFQ>3t>gA5!Q~gu?`SYBuDn>0l>GkUUXjg?&R0q$xmiJ(&pJe6&mOms zsVZ_U3Q2cYb?xK57Nl|LR>;DYA?tQcvN_m&@PG`*O2!s}gg;w&gASxJEYs1^y||-p z*SuK~-)}v>_(JA@4deVD3Vabc5{}HCjV&TOIJ$(N!JawG`COmlL_UTEcU~R%5Fp*$=)uqVZ--Gs0ekad2R)7j%h>{WI1YYj z;QR3;^qYr>!$Ni@4yESqMgc+QcT8IxgA_Ux4sQ0cuuy&ZgT~M57(+o$pAdZF)_kZ@WGky@(4U#Ts zS)kC|@I!MCAH#tJJ&qkwJgkjvM|)PXGtIGKdfeigtg!t}3P1Co8#X2^3qHnwX@2gY zb?`y`Z1%Q>o)n%X@>Yz79!_k!Yym4I?Ae?Dui?3xaAL=%{e6sW2iCB;M3_mgtJ!h= ztwY-ykq1{Km#h+D-0C2+);(l}On?1Xu1f23i=Vt)E-v59A`mRT)PqMsto_tYk0qj6 zA|3MkbRQ_?i>!EW_3?$K@>K|S_^4<4ur9DMjdR<8Nz0VUm^)7cyU<;Y1f1yrp6 z<@kAl=oblrgAW%dvv>UmdEWTJfeJZ3rqGPW2mhbu$mubBNaxyjfxYqH^@R))_G~(C zD$QaX49nTu8f@%k`W!9@>FB5iIV8xj|GZF4pPMrL%Vx6jtzjeD3U`fu|+efDX0WaXwn`+HFL zMeqy%kFYCYTEVGs_(Cef9rmV%oFcA`iU!m8SS=G1q=UE)B)kq;5n!(MqTsb$r@|qN z30G3;ZZur`XR4Xt^rJfUrp2}T@R=Fvyo@u`U)^LrbzA#)LW`>T?~@|`zs9|N@?`E- zktb?D#i7<2K!c;{K|&M9%3u{X{wa)G-e?7J?OP#GZ?n`v$<^k4<;}}^T<5nPe{hgT z#eR|#bcJh-%#;_PixKcKPQjwj*)F-k$zAjY4OL- zlZ8=xn`o@eOOK8U^9u>CZ2I!Y+;{Iddf}tVi%0rNH*&PO6z;L<3AL!)h@0N+`fiGI zp6vZi0woe0T8EvhxEnJR_-%GbraLV=`rs@xLvne~@}rWjj;01bYV2nAm}(vBW|c6| zbYhrT+HxT6=#ozgXFeqAu`zr|JZ)}n|H!XICaj2Yqeg8qZ`|edbwBFX*ls$^yL@`} zrOVRylYL8;d{|PVcy@=jn3)|*n9|0t&oAC_beqlf|KoN$tvxy_OWw8#Bz^o~@TTtW zL5(t16cH~DZbWxHhuZEx~QeT_g_W`i*en|{&g`q@rDX(%i$$&^_CYF z_{#mt$(?ln{0lqx|4BFI*LK zApP&l+kal#*_@6!mKbH6`t_iX1oHvQ);gILU4gCo9uwL0g`PPwJ4~Cv+3{zk$! zTqMNItl5$eehNAqB7ECpq4N^AA2#BD_D)UMzOnj+l*57xHar~x5nqIo^Wrbve=u|2 zkK5-T=kA}pbN~Ly6AVg3^1t_ecKTizY+G^r_oMW?%cX1oNGrena_9BFWhObgrwgX- zpZffgL-Ah+&9sAs-_CEWST2y!C}^@>*`PN6e-(p_!@2AuD)xCn&Yz0sJocaX@yxTo z>kU_%dDQEBIx8+ee*3=hB$i&u|IP}r`4gM_fA!pS2>*U(jj)wg!8^-ucRM|Qxc}I2 zMqIw;vCZ|E%k#rutbdgv`Gwtn{_kwA9|zQHA4;2O|31FqI#;ce_V2$67uXN<^N4Z% zSpS}RN9pXC1@htluV0v65~t6`@$Z(24LjG(1w{svLlPdyaptcUVeY8AWjNhcGIhcl z&fhCeSpHwUfZe*t(Yuzt;C)t&NIB#AYdnVy?e%-({eNu|D403#=NuI`jkH$+anI}S zo0uNqZ(Cva|Ns6KbH5);c-pavF*=sP?)(4s4HmxNj_u6*zTiQ`{F+A$lW%apU)lV* z{`XCHr<|P&TQbEr z)!cV;S|)72_Dy%^t!GVPI=`>V3V)ojUc;?d)@z^C!d@#X=HU5cEqyPC1$^3(UcT$VC z?o3yF?%3YT%zohD2d%FThB>kw%AHpgKh#7XRh#}I^ltfu1_h?(0}>odyS`2^Qz-RI z(-2_S*qL8t$+d&M@dbNOrP<~+KH*(gp80C)jI#i1JPK(K%qmdw$y4 zOIy1G+L^YVKG>orwA62oq<3ZL>eSd1$0FJ7_dg5O{=A3N!lLtUKjVXhnGezN}0owx$jwW}z!wRdPxX7`wOlxd@knlsaK7c2RXGxL8+y$o@ z7aipakYmtLugW2Hy6*R`M}-S$hjRZjlXv6M|ae~!z?p4&$@C>^z8ez%Pu$n?-Bh_=&`hUV#}Gd`Uk%Z z`qM9*@vZ28?C?n6YR2`AGj#a&$!bSTLEfdrN)DYn!QzJj>ab?}u^+i?%IM zw&(Euv%baU;JXBl93MsF)tY+>!r6|zO1I85`r`51@wRhs;eniR)qs|t%I7xRIcu@< z(G0O|nqhXCQ&>~JKC_U^nd^`$v3qVoJAd!o{E(S}t_P1iGuIQia{d;hc1Nk(xW-6i!dvKXY-N#ZmwF-}gAwmlfV`oP4)o zZffoV4XcCZJoi6-yMNEY?QBym%Z@bdUy}ANPPaG@U%I}-;_==&?5q+u9sjSls-H6N zNMrmxN!D6{y^_M!G2-@aF9J`_Uh(M567l=SOLD?j1piBuSipJf$g*p!ui1I!uN>7^ zjx4=@v8Q9-t#<|QicPeC*E&hCoMry?{JzJ(9~Pfqu{MP@sMR)DJil_{^D7On9g8pT zugsHAX?Uc2k7wR5&iT zEBKTiEvujV^PiOMg`;=&<#HrwBs_k6u+mJQ)A_#36r>+eEKKPVdwgE?BKb#AEOzcZ^`2quUB{ePgwL@{Y4gEM8Jiveg6|THBA3jTJhcAh=13cm?`2l*If^~O1ow% z8b=Dfwtvsu)_2)qW~2F{=Q=Kq-+y16Wza33@aF>4hQ)8cuP*#^)4_Vt^eZVHt-OU5 z)=mBU_+I`$6eQQj^z-U3)2AC}+H>7~Zeh$WpRKH7{q4fngu?4?woPg7&CDtGH48#} z^#gf0Id+^;&1S97X_qYt`B|~U;`^0D?Xiu)3cqYQf1F4X`Fn|fa<9b2-N$Fwv;23J z3Hg^M!SwppE{1~TbIZ41N&4vg`i8}4cKf&Mf<#Qzzpxz3`G4E)8tdVQism)X(&asF zGSB5{?u}-beRAeEdqCkg;oawM=*62kezX8O!d!i7rl9EV<<5B zwb$ntJS*56Tk@+P@qN#-66^dUpmbb+QT>ajQ|IkpKiqu#u83>y z#!dyx>vMOR-pT@$~NcAza2dOwI#Zhn>W(YWBr8K^*7J4_!zO?|D7;% z!dHQ%lRgSvUh+0!_4~a|Pn({uF%qqroUr3}cXP8s=l<;n{FA1cChYxP#xf`1{KLZg z+d9H8bnX&8QE>3i+Q)zMSmvm_l~FzM>&^MU|3VuNI!m(nsHN=fdz#y(Y}{Mq6d26@ ztU-KBK|$aS=NWo-?g1jLJ~GeWN2kiDsvnqr($}F-=51TjL+eKue{_Bc{<>XEWP^Xw z`h9#Zr8l;02zj8xXs%<>=ziP2DZG*`yTvE?dqzOh?^1F8M@?)&I~DxDUEtjB>N7E= zmR;p#K_gZLN^_3u4;^r7%0*3KteRK9y!-|CSNzn`O1d}P6lE3+Rd_)RrU zSpHta_Po)(@+Avqc6+kM>{%f8?kA(hna@EPAy=-HO6duf-8rJPHeFLpSB2$&-G&q5 z^XpoIkMO_pWW4&xfXC7JeNYQai3eX(*OmzrF3kPbbd2fylUsZ$EXRyYc6i)ByXc{L zg#R_+{o4#5td~jJ*E9d^EOB0$)dvo=wlnOyR6O?)lm7nI?|R$5N_wRE9A-FiV{yj4 zDObEN|7GcJ`u+C%>d-}om3HiJ8hCqrnfw2VT)o&*v!7GP%~&L{BT>=#;ev9f@>4sq z^wi#dklF6)bK|Utlg|&+nnm;XW#+BD5T7`~V#&9dxXNah|247~3Kz!3+|)QAKI@3W z!wKu9U2>*z+1=4}F|_-UlM*2G`AkeekN@qAtP5gHIegt+Gj=RkqW<8u)%$G$#&5W8 z957@#e%Rr0-(m@-`YS&IB)^{5*}3%^=dLGxzmFZfApAo|te9PdbA!eI)BR@L`%^y@ z|J)e1l;NSd86VHdxJI{GJZpJcT#=G@oA*(3Ar$bWa07yfPT+e{sg#A|EBi1#m$%DlHi{H4O`HvhkI zU9zm-Z!eq9qcMN~x{mjpmb@F}3U^;PRI^c2EPtB)>?gU~Z~tMrt`KZHr{Tfkl`W0- z(hl_xl9nZC$puKQdbI6ul*r-ir)_saB)3`2-R!zvL&WlaRab<^p7ptc#~lwEY>{JP zH&iH5=@;EF)!6s7XW6uydL148)6bXf*dsiP>)m&z{cVznF_fIEHP+RunY39Twd^!2t;0~Yy=>9wDz)V)JRef1T z)nPWeizanzJ`Z|!qxa{Z7e@kHINaM$GKT0ZoBV9ix{n#}CQM!YpHJ=GErkNTrNxD_Qbt!8!0E?=c$iO#33Z7#a|d$;}jbTC?RQS%MeJ?7KIyF0)C+;!JYU!1Ez zufpE^|N1Aj?;Q`iNiz3azNy{*@%f&&>v}$`zUN)1S7x%`iu?E#28;i>v*WjxBu-e) zRWUoDVDa0J2{9jM%x&KF-sSpgDXwT0o+fiI{@RbFqMHj7&T-CHSo=ZtipPn%k4gq> zn@@x z+;lj~DE&wy(9=5pbb^Jrbjw7c;}UzWGgchqXiU)jonFo<=y0T&;kiM~-_2{81PiWy zS-{S9!-{j?O-Eys4OX3Z9W9!dL^nK|6xV9p@ma&n>ECiURrPy3U4i>2EsD|jC4Iwl zujCp@p~?4dZr!y(eQR5-i{zYyhwiFT^M5D(@Z!E^#I7f@A@+pDtYWJiBUOcj2kScX zc?I(K@h!?>Zai*~CLwKB+2-_UqWf*0_+zRnZ{oZP7jf0S5zmS9aJXjXC7AcU;bF(} zw>{Pu3dLS7oZxksp^)4BVEk=oYgH5HmFj{$=M83mYi5mimssS=xqRV_g%|k67fBV} zUDEMD&m!b^m6zXd-zy%?g6_8^55(U%lW|>KQPe2NarVFa`IWM}I;PJxJ=9d@;dD%c zS;>CyEn(yJTLl)E@&`<)-8cD3O83`f z_lrL-46c3@bZJ?tFzbG}yO)OVw;w$+Jr@=>JTwk6-mCQDf`g1;?H5Hkc4g~dIlsku ztTg9-DCfM@Q0}qeU|#2cH@Bnq^(}jzDkObsh&54Fv|e$6B|ax%gYSg}?*%6mma@Kc z=w%XI^6D$sVTPH%z8ShXRz?KfTyRuEC+6Sw0~I01)=Xb9z2@yK4dJ@QlDjW9=*?8n z%QsiMDsiH77Q29bQ*J@woxDkQyRDNR?`(31-X(H1E3O#rVzkP_hC3jTX|9}k(pMAho`)T}D zlHG#mHJ8sYm@vbRqptCcgsUA_w@_pA#^mJ-)+{PH`H!!zF-z@~kv!_AT{dMildc zGaLux-ygfxYkX)~&9);oF`opN3TUhU|IpEUKJxrRb#wcjRf!wEa0LW$JUGL5;QSVm z+Y29U71^+0`mfIO{{k)zh!f#MM;}W*UGJ0(?3c0WV?Rc^EjJ3+DBUa+%A;`4_%rKX9sC+ z+VzXil*!bCr}NeZ&pjaqT-h!1>$6<#joBUTHz_!XB>#S0-(vI6{+5A-R>qG&#=`Gz z+Rc5n{0$H77$2pd|8q4_OH0(0C3;Cq!;F793yh`q@k;2)-+quLYJ5h1^Z##>lmF!B zetU5u>$<}ZtBGHyD`iUy|IJ+|y06uL!Q4*;GMsmk`a2Hod#~oq#b`O{oZli&`=|U1 zO$GJ@UY@&$`7CpXE$4q{gXJYgEdRG(I3c{jB0>0bqCLB`^|yls*PYMJO*c3t)GECF zK+(ZYYxdwbmmbVIP@q@0?N~_)_i}g?w1oUPD9Nt<=Heo=*0Y>T`)ePZ`XIB@ zdco8CKk|A6nX*~lZ@&`0<$~Lt>rRf%EP)Jaez}X$TW!OEK`V>|8|npQ&GFn3rt5|O9&X%@7tvz z!{#E9l69}SbCZa&V%Uq>Z)ZREbUf0uZs)a4uRCul_*!<|UP7A$;or&|sV`Ll-9{;!PtW%c}$1JIg&k{Tro63*fzV9sF z^zmY$b;_LQY~Io$e>Y7%CDse}6k=4dsXN$|c`#$E4Itan5?a>BKemJO96L zuA41f_eFSrcr)|*DRy%ot1!o1R}rn{U%k+Ud-{ch#hVl6em2}2 zZBXCUHmT|Hi)Ry%>-jOS|C!&O zw5~kKOnckD*EiPQ5~&e?-I60*etdR4|HcCS=pVQ9a?cp(u`OQkcio|Mp2_}`|5a*! z^q-d<-WILFm37&y>7qi?yFbi-vTq1+AChupj5Xn0*~}Svf&V|-jSKrXe004xQOEA> z`-obO&l^6?IG8wR;?s@7ch5iSj(&d9aP6^QCA#0{h1&mmz0KO@_S#+hcU~%X$a^-| zV`WTqMaqFcTQjzr{D`RB*;?MR#L;lsG|d*>Mfc-!oZRJN5BVg?DoYtfubP#(R_7$k zu`?I`eO&&@^seaM`zPw<>pmH5ouB{Y+GNYX$_zwrKcl2hY|%J~zS-}qS1yl;50w&@UeN0dN`l)(}4 z_?jDMg$}DHP2G8M$wFb%i9CL_8w&Ic^k!Hj_#G%n@&EXL{)KZJmKPMg$W-wEcAy~O z7{f+R$*n8qH!raGe$R|gAt}coO2Du+QtS8^DZHq92t>)iY@oq8&4cO z_qRu|bKmx^gq_ki&InijpZl*XE@p}N{G6n`E~7gOc4u%_RCf3Fcv$9W6sV+~ZEl)A zC0B6n?~?pW0rQ1l-1e03H;6Nny)1ORbYaQ z=I?ANCs9i-&iRZ-w%ne@a3=WMkDXhm*<9c`cqGE0Vcz*~YHz}0w)HIQIXT06(X@^v z&Nniqzf9dslBONJ;#*x4k@h^`W5S7lK^xTSX0x2%$76Ds#pzQ{i;UB$K-pgwYwz6> z-R5jzexUH(hm(@$7nfunJ<_oMP0XIhKZ6;MU6{O&&&lb5#q*=J4-1xk-0wf}+5J=J z_a3YW{@13Rtk;q|Z;!NOh-35_;eWgn_fKK&riSxVlB9Wdxm73G?0+GF}`W6n2?2@?;U6)%k29v~=p zYu|>57oUGWvUmT#z5My=hgH|V`gWXn9bSCdSmsviYKBM3JllFp6oY!VEj;x;Yog_; zuT_seL}q0fxzAhW;(hoolaPf@oXw@%9;K_EU%$0r%3G~pbJQGm8idX|=iGGk(#Jx> zHJ6v(_#W1GVZoHY{Kp=pUo?Bya`1{wz4@Bl?YHC^tv`f)di1WVQh0C1nf80ym0jx6 zx%bv+RcI!>>soHg@c4~Z`uwBQZg_s#cF@c}Zr+W^Da;MU%Y!+k1NbBa?UXfG{;z%9 z^Z1cnNUd8>n)cfbG8_0sUiG#3u{lWdJ) zpZI8U!qe8^nV))Oe!A)`>W#njonym+Z0q#-yv_alY;T6WI_Q3z@xi=9bvc1uj>rFf ze3P+=Re#P3#&b0ywY#3Ra-8VC(RWX8!_^PVnhpxgfAM75p%~{GuHPpFHUD8hzV-SZ zw@oL+xeU~5&fKspY7FO5ujsAty}xf+<%ToA&HTUpHGRJQcO+< zE`Qjg@auQezn*LHi+XQyuJy9oq5k)sqUr;+PxC%+kx{E%((y~s?n_d~4U5pP`}kb= z6l+bBOf;^E8qTn8+P{Z+$A+NuA5O34x{+pV`|Y~OzxC%L4=k4A;r!0`_lbVO!^NsE z^;vy{>uxHn*YVK&%g#C1WJ^q1{rff-ADImnb7#l&^LXy#ofRYNlzwwzgT?=&XCL3! zf4OP0!{fI-j5Ys$@YhLRNtkn?bEm@mS1Gz*3kr7LOmb~zVH7`h|GqQNjvZ&3r?BSp zJXrj=`u`rcPx=CSZx2nFRVcmh-_;8fKg4Xi*!{!%l1*cVXwA<_7b~tlcKRTr`TGyM ze8T>;YwTPav5ckP57Y~?MqDyovGc~<181J!W@q^Px1c~R!+3qt{Ot$M{AWGCsIHNp zp}_asub}SbR-(IFemkCXY_)kLP}1hIOO=*XiTC z>&z`NnjC9qWL$i*IY3~^0`bjx+izbe6ycK#a1af!U=nLO)y%qfL&8S0NhQx3MCMg| z*vE9@miU4$lPjMWMHa~!Oz(G8-SlyXh5FoB>DoVGx9bnTiIbG8`}pqu#r_R))ej1G zw4K;(Wv}bMSVaByTPMyNe_!WhoZrNG?Y^6%HOssDC+RPK*Q*5|=$tmCHTvGo3@fI; z)7lo;o>{))*o^0Ar!=?ndfB-!#+iv)>VDCvb>p5M$n)T0m+sz6x>*mSO?FsK-Z)8v zyMOT)V_~~VJ0CeV%sVM@PKovKtK;+EZdhMpEV}vq!kPE?EbF?t^x#pwEz10 zoJsj+*x~Yfg|nginO}x3F2DF*8JfRHcbfj~XwH=DjD}xR_!1u9k4|Q+lz+LgAw?}k zo>e#5?c(Hwx*H7l@4FwJW_i+rdG1m(S6g=8x*t2fvCnJZJ-^~;4trDmeF>)WM?x-& zv*$CdJ$kn1VCkoats3r{8{LvsG8FXUZ;Na=BOW0m{6UV7>)*Bmh0@CwE+_~;X8ND) zSgphRU8lPrF%24WLZJ8q05AF%&Ih0NO>;Jg0N4(YYPrfH(>2>wr4<7f(^k_a7DhuRt zJoh`}#|{fI{RxGhZ%k^<84C33;<&f{lAQCu=AzeArM($J2ai<9?9l&rBf-D%C`-(e zBuUPj3uL(W@4q-bpE2oMUXVlKxwf7|bFX$f9(2EFvT@bM1rfXk7Fh>M#T7VK7%TpM zVR_2^LXUz)&?zg4g66LRs~=bH@89bctN(v_dUYOWW_Gk*Cy`EB!E-2bj=zn%Y-f5GE3{g3|(=kX~QFFz+$;Ja6beNM{l`E%YjPf%3L$vi3H z`f?r1>~CiGeyE)Q}`vzGe<3Cj~l!FycoPEcl+0Zg&QZFW$%P4Y*D6{Zn$vR8 zRq@B|yzh_fbUL&TeKa=nFcjJ8=C+2bS~~ySU5VEGg%k8{ZaATmzxRv6gV^MZiOd~0 zte9K=biYcNb>kSr<2P{u+?@x*cv^Y1{^$G-l4R~PC$vU&YO&K0WU1{UX1gVlfl6YghbaJgD|&;f(9= z8~&B3rF8`?Vh>JQ?s%HzUCaII#?E`p2ao7n=VUbO?o|GFQ{#YIT34dDwA?`!zjrWuq)Tgg9 z-^Vg<@kKuq!$tLro1S)UH?L^X`dz%*DYSQyVuB@?;$o?S^KA$3*56*N*Yux9z-dzX z#aSv$kJlt0Y_Rx#-z;x|gAwEVzwFL$lge@{S|xUTzxqmAP(+DS+9}B4+EdP*6>%H? z?Xv3R_njhK6xzF{x1#f1?{wFDUyLlj9rLihQ9P-~RYumLvibb~e`>$4EfSZqx_{8} z;w00?B*%|+XKrr)%QJliTV66lp(lUB26ow>J1jmssb}+Ksi<#1^Mm{OAv0rkf&bei z9M<+mF80<55H{?(vtYK>ZPjH*&c16?oVZ~2w-=5Ldk=9>znbur`quf61^UEC_-elur&ZhPI&0z#+1Ns2d~_?&Xg_QvS!*50o9)~cBUxKSU*cbDZ=MK ziDHr0ozL@cODbDj_$bf%s7-?D>AHqENvl$Wx(vo>O_vPuH!`oUeQjH1$HNrX$YJsO z#p#WVn*8}KJ!#(zc^FNbJ9HK{y}j4{(|2BOva3zU3VyZUi4)fMOgzGFsP*7^QS+zU zFBizEy`EL))GDC9q2S1U&wbxBc07KO!g=TO1dY893Z>bVd0J)St4t62yzezQ#dS-d z(Ac5=eapHwr3VwcY9*Rm4WC?u6~;`FImxg#S7~Nvo1JPzF_!e`uo|Tvixr51z|5NCH71` zqw#xH!vfg@ojupx+_y2e`pEF23;PM(d@*6RtbW-_|1|(elRVk#Nc%8P2r~djD?l+Z^LKx5;DU zrr?wu_NMaNW?K|9essu4aNRiK_eO%PMCI501rPk6ik9x!J!6mf{v4Uk!bawWQU{LY_jzIn|O;qqg@>zx@7 zeGGo}XD++#r=TGIwHy6n`I*Z2l;`Asuexn_wv9#R)}hK{Z+8pknyt*du;6ppIw#A; zcXuvH{}!?3pI+4)`|S>$n-)nex)A&0nV3)LgyvOWKdCTn`N(}b@N?b!`^)XSFF6*t zyDu)R<&6(HIBOI8+xW(rZ(sH;d=t&-HsMorvY+cqDXZHe4+@3t&Y%1F@`1(gR|?Zv z_ij%Jyl#47;g_KEpQhcKuy+2B+xgFu!;F+mg8rG^{(Y>m>?~8gNo(CYNz47)4u$cx zM;u7=@4uI0(6o(D>Z9G9-0xriF#q7}UommETZ8J8W`^Q_H@PL(U$i#8w?OHLy|KuH zBBt_76DRonbK{HUSRD}a_uIjegU2P(FNyI*7>LxqW2;eNxqkX+m&=XoOxui|On=T~ zc4!DcEZqNojYpHc^zyr!5fe0??3Gk<;GTI~yw`&7g~jjq6&K@r4)u6iGzeSQO_CP3 z=eeMJs(uplG|>+}zaM=l+!+1d@hT6yl431ur=rG5=AWDD;#kh*$haLmJ=yf!xoNi! zJt$}SVaR&@%E2q_%8C{2+$Von^hMp)l*(Jz_-^59#g?#G=C&DE%yKz3mM@gh6Hbsl z(Dm&N&jew^P8E(BmW30adpfi5{XQP=tnKoyr(%ENrntQeodYf`e|sdBE8dIQe2d04 zwfB4XHGlp8@0WgD!-LLsd?N3feiauNXq;fpk&TVdS-#jp?X=K(LFT5NOU4SN9A*550!CWzt<`u^M7@LQE|#@p-W;09XtBBDE%&((9G~9Kka0d zTDG2n>Pz!`jCVyg1$%JvcEzwON65IHUG$t;VDbA|rtuRFZm^j0jeULtPuR%-*-JZ8?ShwS7F_D(DY5bS4NV^zG$}`*{cs0&yHbd?sN_Ha;Vh2 z?&QBcLr0)Xio=NAuJOR00}s|e%WkciV(23Ju){*-f6jk5Lx}=*1%(6i4j!2Qz40jf zP7jNVTb#BT@c8mdSS+5fu+aViSMOM(pxA z^2h&wulSw+vcBmMbMO4@<_Sy({H?#pa?Y?2(@T%k*rEPwhb{mAC;H9PRF^a@d%xDBe}diR1>rroc8eD;0+zMs$nA{dkXrj>Qdw zKl~=PY|k%0pZT8az17FMoSX87+h$5fR=DTo@4R_#qH*GpLs7!jFSxyyR4hJIyFY3w z!C^T0| zc(>TL@#^nyef;yo*mosg%P)GvP_B+Ryn6h5Al<4Y3yrRx|I? zZ@+)^{JZ9cg2iv!OkzZK^f6CpI{GH-NKAz52TSjLuOHrPzEJ<~S;qo{hkqB|mEgW6 zY5Sr1b$)|I&=2MX7FQqLQFzMq$zlFG$15_m7YbcXjH+21&M2*BQ#P{izMWwEKOQs` z-Q8ryf15$tiQkz)V)pyyj>rW?dQ8bGl1#rvM4ApP=zcKUsk-I<{^B=zj4XD_>{8PF8BY3x?T<$&f`|E33&+q$p!=lqny^i}0zc+*QCfD09 zS5$A9P?i?~8HM@2&*t{GZ3b*!%G(55)Iv8L&ic2wve(thtlDmYLNotC2LbDcx61UI zrQSuE80tMUToo;#+AwL2@BS_uOV-Va7fJ+JCOFEz_#5qe?$x|kGYh$d6gDv)Sj^)1 zj;T|-vcA{r`n&Zf&*-e~{iQ9=@!*5}ffiQj2Ym8*+d6%}JUBh8#LD!8m1^T1!P}p6 z*f*!2Iy;|dqt>FgCt^$OuS|WVFvV}{st=-@OchEJH}bR_9%x}~DCfRhZT=wLU|q>X zi3QQK3Um|Ww2!K>+rRz#_>$xc*+uL^w%T&{X1Z_5-*zW=`$xI-J&$wu_wISlZ~Wz7 zxx%~VR)5(aKF{+X=k7aq^Y8h4eS9oun6GKFzP`)Ox!hcG0cV6og7(7+>aTCx9Xw)U zXlBgryhi5z`d<3VZCs=n__g0jOgD7<$*n~PBg{!$YjiI zcu=@?$1^?&hR=6bHn*|xHh*f_WQ(P;e;6v?ui`mOV}VTH^o3= z88fSW)z$k4PcIbt>wGcZxnl2wz}pEA8@In(%&zF5nLVj|_2k4R_P;)X{3|pr&i}cC z@5Sjx{}`F)&g^#4OXhO?I5L5K|Aqd^e;;<dB4o7ErB3)V zcl_JF;-t8f+6K!r&oAG8VR@HJKu)k$_fb&ro&N`4Gamnan8l-usqXp?y`O)6E8pLF zeBXcj?B-6Uutx&^dnM-17P0g25UI)Ed*b%{_iY(RZZGQLp7+0Z+n;@<{cK+XPVD$y z`A_)wqh~MtKW^6trOa*rwDb4hw&ODT^xs5*zwLi?y`zRvLxsVMT05?dD)sa8UmUod zELUdnfW807wA*XME8X?kZ7g(i1ol{e%$T&^KJdoU6!&B7ABul%nk^{S+at27L!y7K ziQCm`C7rppHBaMQiBD+^+lSX{#Q5rDOds956ll}< z@PVA%Q9Hc}5=+DptD;~Y8~EsP-|&9|)O zOm4c|$m%}f%5b1#7T=o#NvqY9c#I~n^KGb@^@M5v3*~td@@m&+FHu$f?-Q~2Ocm?h z{zSd@bs}~)x98M8uehE6IDdct^M87|3zb0w!nwPT&)Iq5FjtS-oo=rCEbrTA9Ppj{ z_LIQ7q$BSp32r@@EMWial%jeSpK{H?PU{#MFRjZnKQXuFPe||(-DvkqyTP(x>7`DK zj({6Sd_S9~*hHv+y7skeKTiC{*Dd_SKzQGi1dU`B8;he)+Haf@uG@C@O0Ahjvf^UN zlD4vQpOdXMzcKf1Z9KpCSC96k&Kv6+9{4?xX6Z~OuwvQIa)-w)sf~}TJS**}ZL3f4w_}Rh>;b+>+b>M|-gwxP@pMc7iZ1`(o*vJw zUn@5}arQebCGz({;X9MsSc&j1@wY7R_j-jdoG^QTkIb?8&g@(}muMICZgNi8^+Wx< zk>i9DD))2lb4a}iWca+s*h#yDU0Lzx2CMmx<+>s)wC`8M9&Oc0V4ic9HNWXY>|Y)k z|AwODx7h{$Zfs|LtT6MDO)L-NgU4@T_E$42I!{@r(|05w>HV%Byw;$|$#uqDa z@QvmR)-P#}-(FZu$UZERG>=b`#Yd+8*&X(hn0K6i3>G|bwBA#@{p02QiQDcUzxTP{ ze4lzv>mT!m0*l_C$DjUhzxn33@V?r6Zk%Uk@9(_L!*A#Ja`pN7<(l`rKdq^&X3kKn zm(Kl@yZz&~`-f|H=0$SE{La#5KCsaH+q31zW;rNmP7~SJc%Z1E?A8=#@10*NZd<3S zJezyyu%=Fot8opIHZrSz5%wm~uK;n;|trZ8R z#I9Ws{Kg`8LdqfcgAI!oB(`u`El4@MG+NK#%5#P#oHD$s%~{u*-K9mh9=&qWI_d9= z_QlU4zE0n;ee;xnm|c-CY8EZL>{yiEmAOD9{fn;p9dD)&0YART^Z&1JDFpetxZmcV zT23?Qw3_?X_0pApa=(AHP5@1q+bieWcl}FvWOsZvNRj#NAGh;g*T~IcFbr2r*vMsf z!>aQOyU_fkZG2mn^gr73!`A%&qy3W_kFw;*?BO!s8zIIR|Hnd?{oa4++&^n2EDS}r@!9<2UBkz7zP#};!?cfk z?z{!f&>xtvk5a`wkCNTSnH~xy=j(3!6LkX}@hszsLUW|G#Dx zRfhc;jfa_R43vJ|W9N!eoRQ@8qeDzNzO|Q!@vxTLzu(DB!AWh*NBJ8bH77i_VPDAl z{x-WZ4`ao_yDBe|HXh@9VDXs8*&wba|M|z~-$8?N>`V`Lzwh1lul<0Wp@X1}^p9l$ zWfLkt+-D1rasU30^WSLc4E&pzD_!9qrUWpMq)8FRv_5TDnJ3R{RtKCp48Nz-;&7efGr`1QM zL;SuuYs1Q>198F+iVWj_XS80DvN?Hk;WFEA$5IwN{YUll!`}qE=2d@J7%8u`__^)w%=9>fcZu6yc|J0j* z+y~l)FQ0qQt#*F?B;z-~>)C#leiQm*e}4Oi+xGjfoZrKzc;voT^Z9Rbj?*jMqPo1z;Xa$bVB@0PT9XeC5K@J)FMU><#~HB$o+xytK+F ze%GqJ%Rc?@YxCUIw{sUwJIuQJ-(Bw|`C31X> zMc<^CEx)5*us}fa$Hf0evA>@^ou>TIk->>gj#>MItWU(*M`26eNsDlH9FkCK?^*jf z<+1AHQ!DGsecWfvoOU*M`n_#mLs!q7GB@sv=K8+2n{WQvfEv(`Y<{%JIvW0|eg5(9 z{ex-DZEIvY)N6bH{p5X6`0Sq>AM5Ex<-6@S|NUe?zwO|Wvg5OhcQ$=EC2ZIH_5Xi| zhn?2;pl0{Idg=VXx(^EUcHTbrt=^r-x96G$=M9U+3*{0X@ppXYlt2Etp7%j7sHtxD z`N#dd@@BayJ*_cftR^?EHn&DMY}8PGDx`$n01-p?1SbCV|2?d^{66 zX9}~29z6GR#z6*)RF4SD#QKDlZR+L+H^^5px9$8;=wNwYy7EuH{l{(JkKM0#}Sa|jOQ!75JU!4U-Li*c`*`=gP4<>jCn>HIY z_-4F%cI1DK>?Nl_mxixL&fGX!l08fGL*4uT|N8hOxMo;%Zion)UQ<{6yGDcM8o&4d zpZEAg5*sxvG=KeO7u-vchzWV+&^`DZ@Dt90MTwjyM$J%{^Pke$w3A_Abg~Ff5 zKmYg65zkTmp}*48!|#y($L;se{^HZ%*kNI$kns8b|J~or?>))={$<}`)`ey)|9iKA z23PN!nP#^siaj`@_T%a0HzoI<unOg7n%~MP-#ahUCsH!*WVL#XG-DHo4g335Egd&LDCU{X zt=ZpN`6^uS`NdNY{@8M89nbkYt^V8p-B;~zmsWYXNU#Vve_A20c5l1eFBz7k=7rp4 z$8H|@$fBMj$f z)t5}3+`@Z&R;8(r(&GskyY2~2l;aG$!Ne7E)#!en&M*i=5W3v+dm_mx%H$e_d;#cpZxZAH3G) zBE6{lw%z&7?-%vYX8u7-`M-b9PwCum z=JS56{lh2Ta-X~5^KVd#lJ|=Y_rDufOh zy;&QsGqnj*7}?qvlp`SFzGZh zqy!(F?q5)FLU>;;>%mTQcHSa|Gbt^B|EB%r*rCJ5V%+=ZUmTx8j*PJNZKVgc5|(F@ zG9EJ?`WS!gc72YFYyX2H5k`G>;hNm<7PrrxxS#)M+YJkGdC~m`uLa0x{oM7?m@^`Y zFZTCCyRP_p>D+T_IluSRn}dd^ZiAXOalh@~awT8W`}xaijq`_=>zB9Rw#kyu-mIP} zbn@z)OU-r{Y}nsFWPaOcerC&l>pv$Mn`W^s_#nT(g;8PmO8c&>Z}@HJcb9Q2>*!fz z@vG`jF`tIkq;HN#t!`f6XVsX%!L>EwYy7N9W!}YGCi$JJk#IO9VZ;9R@doR)eJ$Bb z55MdEn0CAS=$ngM)z~D=5AIWLnzH|G|JC=_`BTfLrRkqk_c-@+(QPpmmJc@+n_4IR z+p_AumdjSYQ?5$N2f5F9+)mAHX60=wFgka8Yi<>fxROPvVZn;7l#V{W>Qiz0b(Nd4 zCMijYgs3VpvIOx9>WFf?J2LNy2-2ERo5}d5!8?WhK%qY$r;~uj6pgKi3NJYI7MC8` zd!|{rvC8oQmt?9%)QqJ|dQIm%=gYb#f67&S(ItzDYnNp`g|>3WChuidN)u4cwVEh= zL3?XLyjT1WAzS5+?{@#p?tywW=lAz+|Hr%YP5tA1`=;Et=bt1h+k+}%>D)hlH>^Zj z@+W+@y?^4aBdlUflSfIx;HYCt@g(3f(C_RCiCJ8Z3;qT${(Vqzpu4%F z;4I6cPilNG(nP$C*_nz#L(mguHcxDxFacB#>7VU6=}<6#^PcMGHM!frHx%p%Ic(b0 z1{y2ckRVbk-SkQQ&^+Bslh5<`vU$(_eTSXrT140rj`;~^g=g%@{Px4=NlY5&+7w$= z$;FcLi5-@S%g;6@1n||dzir@mnE5AnJ2(@b{K)*VLb4#nNTjCT{M$8l+eKUzR?Pj@ zCzz)_uy}v_l|kWgwjWXl3b`Lx2&)VJl(@%b7jWoUngSk7mLv zK8u3~c071+zL}}McMoXf_y2Fu_!+-1gS;TuU3Q*{CF&(&icJr#*+oRS>R!!acXBl5 zX%?8QD9&@p|3bNd@LwO90JRFkmX0=!qds!&|35peZ@u^XXM}}#zOo4)h!NB{W}E3qJt_d|l63X@n&kizmf zvDA(W^85}9+2k5OIHo`1Hq#OmP35=Hkl{#V4d$&~ANlR9g5(@AJz4YLx^oT`emnd@ zUf^$Jo|-hf!Xv@1ZSN*s^f>)HU@^n#`S%)FRxa66$C& zvEb8Xr^Kp-SJmPTyROTv4bZ+Tg z@AcZYGr!+Xco4Je%^QAO21)a)KlpeqbZuvU-N3g+hI2mKFMTfagopM=^9>?)m2Q*J zGgd6oOn5hoJ^Y?9JJVy!-w6*6XeYd2KC#0hiMcgb;K={`>^xqATr(^ZFIuarzOYPQ zo09PKkpIf&F7efRIdeCZE;-khEKnj^le_)16(7sH`h(?`PQKp`)p!{dv-2!aE0E(; zp1a|IjB}Uo=Z1X;9y$2`W&B_u{P$n;#RF_w4<6rN{>l9DiKL6Z(#>0l*cg35}A7J}; z?0-FI(5~pAF+0moM(te(p8wrY5OApX!uj=I&fjJ)NaMbL;9$XQO`bVd+88!ke*0y} zbIPMY?SuDS9yXW%`3omlb)Sf@@Zw{A{=!21NB{dT36dMXzF7n8vz?iFU?TUX=FTG3~TkgNO_kD%4LAmFC zg%mzcJM-R|dx5HM4p&-2Ru)vw`7Y>wj z`ZD)#C}&fge4CwzlbNZ08(*#;u8w~XEQBThEs6XP_8d+;ujTgJsY`>`URq&P zki#Z;@PU1QXSaKk&{xqL#;u{A66I{n4-T?M{M%+Hv{u0S(2`QgMGR*m*3Me~ciFF= zX;ZkI9h%t7nl=V0JYULTA>7&DvO;!S&js~uGMD==Pv5-i=H0u0gIeNx-s^1l3~ZjR zsNZ^ga%bbQ^KGhAA1#=0%g$rzlSv$RA03$Gv!kLj`O(G)JsyGrD{6ga+}eD$+x?Ki ziU>P_-lL5t__*8~nO9je9(uTvO{g-6iIL@y(S9j%Z6Q5H=k~a z(p5QmT=w$!^6+x|@YjNSjLrVmvhMntoUf+Bkbd>^tLIYghpK0m{@r-y#B{!yvMEls|BvD9^Zx${J}K{bVCFT6#q4Z+=O6#v-@ENS>j#T|=6Rr=Yxr$;`AxFse?MNn z|2#+bqIIJF`HkQ1-|+eW{&D60-hKa;2k^M^GoN>0<7<~lljwS`=fvmo{@`l`=HlN8 z8zh*%HZOGHjIdZDEMduIRC%9g8jnI?L%qhr=CzvT4I5S2?Y@EL!_tnaG|V(^oX+NW zLdVaJ<@4s_0-oL0m^Vz|3d+O6a8$>X-DZBBpeB)zn_muhP`M@IR2e-fx zasRU3gUci0j6};X7FaYtG$>Ly;eT&#KEs1EMw~O!TBTn2nJ`;>IvRc4cK__b7YfX3 zwd_1hJ^aD{f6P7U_9B7L?pKT7549R;38n+${RIWHH~eN__Ww`N{p0uQWpnr0@B97W zmHO%C3C*o>4G$tFY$(+52Mq#zyRXL1<5B6TXnemyhP%g*@t_#HhU!{VOjN@C$#Flr|AEDA*}6>)SC7h4qsr3GuMn7F5~) zKa|#3SYR>x?P3$-h8-pB<&6^-wzN%maQr?^lI!k@F1A?pl9UeF1MwfKG8m55 zESd+J+o+KVz7SV4XKr(2!Tsa+%E5hxUo*e^AAipKq43#1`}t4Q9B#kaBV)kvS(4@d z|AQgtPHB79`2f6P_H@7Y2mIxJVbbYniVV_9I zYALse{j2vY``40LQNogO@}}Hf z!38soOJ8hRxt@7qQ&R0Cg$SmsUzWe&keUBVFbeM8Pwy3Jq?%}`v|2Mk`tBvqX@q6q%ovb>t zZj9D1ES9u0H}!YiW|yyzPI$q`IrASMmt7j)1R1Sb)`pc|WV|%Wr#3g5ZYa>P@Ob{= zxApwn;%tiAj1T={68M_kg#P$_ur*;w+HO&FROH_ci=_#(7nuke6zDjqWu#teQK~z7 z_woPe!_04FdP`D7_>`Z@H}y!c%l*+byQC0owz=OFDVz+1r1Qh^?Zv%Gx#G+dgf|p=KHn3(VEuweGJF!ke}wbi*9*R3{$&c9 zvg(!Qn$7;Pf&X=ljF+fE-TwbK68PeT>|f`Knr)HVaP*EWTSnhspD8ki9J3efz94%= zmhlK^Iy!d}^F%hKZF~@((A4wxe>K0xMuK#T4tMFvMQqB!oxkst4Gab%Nl@acnTt4^U&P|02UKFv{ag}9V zub!YL;$^|)(dJ@vkwxNtQb*;cH7!c71szr#Fii3fh+y%`Dw_QN|9Y-fO^G)zm0W6K zpOCzA)2C$Xc+E*h@tchWCj8yfWwvj7$>*a!+jc3$cV{Rh`RFcu>l9=XcF6h0qX`$b z?pS(CV9J!v)2p(I7pDG`Z)4alF#n15d{>XJ#%KK_?wXs0sW3C9vGR609K5jcMCV=Q zUhp~ipL|bw&G>(`_vKovRm^wZmCSe??s9hLC*gX~YU}=O@1@WF$$f57`|*8E<@S$z zx2L4feD=?+`s4dQx!+HG1}zmmKD+4f8}Z6NXJj1;<~H|jQFxSo;@bj@e{tZM-7h}IL!DO+^D(bjxNnw<#4HiR>3-mq2)7?? z|GdxU^X~(XW(mFFdyvg|S9C*!Yn#oICGRz=xe}cWmcRXzzi>tH!NUS^_U%=C#*K#+ z-ETK+`dPuzuiBZ;p0Sw z6JZZ@nCv9DANcR%y|KxlK*!a8bF#wn*ExplT)z}69cEsLXzs7+kueheIK$)a#BF!B zKFgWJrZE3dng7Rs_my)&9bcQ@zoKh7XP)o)T>qn9?p~qs^ZQ4B&j(G6g#B)K6zG2J zc2RKj{BLW1Z`;vlfAEoS-h~T6QtVsyFuOl|HSs`{8H;I^%JjzdQSw?5rk4bh5+6L= zud``7@A6%1H-vbZDh6oVUQRSlEKua%7+BuQrG1aNDa2|qmrUaBTTcE=hvlNa{%ien zs{59Q=$>Mett_$=rm-d|DwIBYrqXd?PluwK%<_g6{Fz?t;)-ShGtMgHvF{6-xs$VP z_sxp`KbGsPh&_F3_Rhe$4Q5-ME8nj2;1j;i#xQSwvw*LuM)URW8Q1-0X9bHW9k0?6 zXJ+?d+Hv?)!)Atcjm~$I!G1Tp{jFs_*PqC3yhcjVPTJewwJo#DzGruPj@u2LnD?UF z4qlPb_;LR{Xoj}zpUv+%R>%KkD%+jku2cQo;&$GLoFysDN2QDEdoN$^H+$2&?P+tu zoZD`aLSMx9_HW;(_O_tV9;ExX<@FmD;yGf>ZgrqF5XW!+``7N~@WuZB?&dB=!+p(- z#xK%uetUG_aZ1h1FAJrZ%=qjZuS{Z@y>b8jWB2}a-9GR_?Tzpqo`Xpu4~mqNwtqWs zd`7PN|1Y%+$Ah{XjVJfNZQc5#801Ajziae>8VP!Tg8M4-_tRu9wdJ_QQI`u7IB259|ls*n{F)`WILx z6fxhIuKiPQe(Rsj`OW{el|aj;YWlzZ(>@QH^f~|d{r=|H+y{^NKG^h8I*XaHb9v?Q z+yA9=Z;F09Xn*t8BCj1Y&HouS8|kG8)J0kNcD(!g?(FmVJZdwGJ-%@63tWECM^iwG zYsYWv-``iSDqRv2eRTc%Wo5S?xgM-OKZ)U?)apO!53h*Ni|LBLRX8Pv@$dtaSy8gv z!cwP}`?Sy7yKt|8)q#gvQy8n&*e|iaT-#ijns4=T%GdS%m5%=wFiTYy6h7l-=qvx! z+%fa_;YnhDPtKlTd!TUcg~BJFt^YiV z8`W7njF))-)q7=CWOv+m_0A0if#-K^e0KlX{d(!jb7r@He6D|d-yXbo?40!ReNS?q z-?*I@@%!9|@9eVwALs5ocCTJK_fOb;c9Ev^la0R>m>)cd=$!rIU;X3U-N*O+mwx*v z-@M{>Ug;h_O}iffd<(7Fc~01w-QQ#b+VjFL!Umb{-^rd?*p$m`xiX^BO|&+*?;o z+Nsy7d*GeO?zexee`J-nnaCJ$et%H?%d5VbWq+7Ljr=MGvqnz&>o+Vu^DrLRpKwtB z__untgXO!~Lk}KwKYqL3on4QQ<^9!DVeC9^?)zN&+ZvDjukJW(&^wF$?f<_GAC@*f zf3VN)JZSpE?)IMi?;qvU8hy>|bwx0E# zzxF;~&jUEewC5|uOr1MZK<;H5Y~2z9 z|8UmB@FPxz70yYutu`?c1_ryk*H_JA zEn^itq|;^tnz_Cu;umGHbb7x;%oUSA3e(x8lN2WHv$`+$~psjVP!mfl@P7nECq;(jI#F=mYaXbIXiNhMA28HbRIh$85G|qpT@E~U2_b&!@ z_y2#eHUIza3f}{Z@8`ZL9|%9N-cR|!b*A~VYpfSrcyMl!Xzs91uH|(!|7P>~=`X%z zos7249rxva{9oDJ#b~-AqU46fXLg4JN%fDEM?RWY3?*FmR_42iUa=%yHzgPI|`{~9jDctuC9?`$C_P5vEMNi{X zcWrb2{oSlYWbsWC)`*|0rbfM(*wwamuF&PbTMyseqcYb*$K#0aJAt_u&mX$&yBjd)Wn*jXjHU{mz`&AK2BhDB!nnRY8vn;~^8hle?L3akp^# z9BSI-mYw_MNv7Gw#ku>tZvWnVGgsl;CHYSq?yzo6eb;$b)jRSP59__agIV3t9BU1a zu0EU+p4C;JeDTitL)(qc9z4E>ovCQMh*0;13A-gLK1k$T$aw4IU{Kod+@52XyEJH( z$cInN*V=W34zHC=vrWAB)4#R%9oO3*_y0ex+^uBZcwk4pI=hI|L}zwE^BkSpzaQgj z#O?hmRGvSVuKe@1xsB!g{9l_6{q*$T(-Cw`qs@$Ee~$d@|JQg-6CT7Gb{Q0kgG#j8 zduG2uT`TE?$G0E9-+lNT^Q8l9qP8lzdvE;Ce_Xlq`0e}Bx%bR||G0hsakc%zFESZR z5(=9RzMubdL+WX_L~WMm7b4gk=KZ^G!Ka+?PK4?A{KEnV{vZ2Y+&w?hUEzkk3B%eA z1&g=r`^CrdM}k$}Op{$;L&2V#n%nD|8x8N>I`Acc@lu*GyHxQDi)Abk|IZxCGiDEA zxg(=q&vx*x+S$&3%ea~5F{K}P6xgv6vet|51XAL8BDGANS5blrVet z?-W1YKfz3C{Jsp5#vLCfe0`sB-(!gp%m2moZM#ISJ07{y`~BbZ4Ki8G^Vc&bXeYdD zIxr!$_e=2S(k@L69l^`%7c*A6h=O(v)t|k8{`>yD6*(6j)T{U!o^L33)#W(JWc)v` zc}3D2J_!*i(G5kWC*ArREK+(hzZN!l-eq6%{~v4JuEIa}kN+;;)+=F|xSCz?L7_N1 z5AVV7)d2Uy}ysSO5q;qTc@f?+-Rv#a*HDnk(cMN?cr~Jc1@?iJD z?pN!B&aZ0{>Qa&LO5F5^C9L}XI?ly!I!&#Un3)Rm`P+Fp)S|Tn*pE*1RakaYf%{vZ zO=a!7|C36z^+cV|x!u|nyQkxx8ViGk#l&cXwJatb+M)~z?8RNTTlvIN`ZSH1G^gio z;p^$nS>C(tpLXr-qxawb-K6*VWbn1OPotDL{g&#ly|i?bf_li`s^hAw=AWr+{(6Az zzvHnkzROzkPct5zFn8q?->Un}0>v*RbeI3`_P_n0f9AJ1fyRa{nmn=}dU#k{`wwY) zJU$C49)D(VyjA)mJj>@11y?ghW-~JH+S_T#T`*H3+w}16+jEB;=x!i6fF<%fa`*G%i z=PnWBgeQsSsx0?cHn%y-9e7yp%%snF+-}ei;zS0EpH;yM9cRn-@X6h!7H_7 zk%av>Wb{=Peim3Pka>Ra;Oy%H3;cgpQKA&Hp6p`ng!Obs#zyzZRDJ47tng+Qko0@vtHMopKj_XE;G!@JsoET zYQ>zqeDvqB64PoA&rG+KW@X`Si;Zq7*S_z!`)79hNxiL(+s)(O4!Q9N6@S`b!QS${ z`FDd~&4MQ-3l{$P z4H`lB|72(T@$FyfDRIVbUOoq}P1?P&OTvS1O8eux|F`kIG-v0P@NGO&Gqt(PRk!(@ z1KWFTPI=bmI~$+RKX=3C`~OF6*V)-Z3|{{;-~8iq{*w&GBQ>q>XUiR*`Txte^PB$% zvkPvk{UVc-B2+7pcp-Kl^ZEb(Is$&!+W&uYzkaR+bDu#GL+sN-d3+BYmOrk27tJn^ zP@uO%hw-oW9)=rQ*|bWYj9e7#_*b-%xNu#_@yI1V6Lid-At`d>;M&d&8s5 z)7SoNlGvsCi_Z=;IQMU9oyxkOalQX|r2fb({rlqngY|zUX5JUwc5Hg{fd?^v4pjbM zyN~(j|NjS1H+Rf@-*rFX%l-e8&-L}l2<>B)7h<0K{eqAX)5jjigL3RlhisdhjqJBc zwEW4u?%;QzV2{f0ggHMr&jkJAfBFCa(X*fb^lyJJUUvRZ{oYT8VO;h$HxV^hSNn`*^mu#UOu0@Y9f+5$bIY0Ua-oZ?T&;ZPSKK4)?CB)9!ig zGVpb&Q00qWb7L2yL(1G}&3wHzJ{s5eFiZP*a0ssHb&kF3oXfJYYT@-+4xCSc0EHmjD0rtDetp-z${RbNZmc@ZfRp-$SeR zSX$KoH+aqACD1;hV)ng9&lhZ0Hu!jLe(&~u+Ijo#d@Gx?+cf|A^3rr!efewG4!qE` zi<=&~aN`oD(#)@YD-+|=Z~j&+|MSo6{!`nN;_7oN?KtO5k$LlPd%l^XI-BE`K#zk} zX`0g_D~k@SoU^{ebCq3~!Y{p@T&{b-t85o?kDWGXZp{@LCBaj)(~?*^IYA9tPKR8{By>PgRU`~4~DH~+j>vpc`nsu(n4y8VJ2 zsAu*+m_2yy{Pg#6$>s@L=l}Ru{p6{_gP4Q@ed)Qi&AZB(`#)@d+mt8K`Q7nI%>V0O zRoHnW?2j%1E@J~JqgtGh_KMk ze?0wu>Vtpr|Mv)4f|inMvfDF%uK)G_(3jrrANSlpd`7tLN6hcvkJsEkcDr6S?WcE+ zO2UKnk8^ilZ9K~GeE)^|`2RQmH$SkE;od&`xAfaTzkgUauHmZL!urAV!17nO%zyf| z#{RL+;XKJ|E4iR}dER0P<;Y}5Wu8oHo{Li)O*f5*cDvAZ@L`L4A6=IxW`cm4a9f1%v5>imYf z6Abqc=ls8~&3NG9`h*$(wEu#3pibS{&3VJ3Z&&$-r70?3_aC2KFSxDtoKNli_ZR2K zp5L(i`QtQ)AK&;V<^S5-&3&<}-T7Mi@BM!TWuzc=)xx?DmB|ye$#k#%8i?{Ec`2D_m&hPZ!erG)_5^CrF zn0>%v$?vyY6gG0jvNM&}-{Q0XYN8muRXyRqwAISF$<>U9gLurP+pjSuvo!xY{-EHS z-PVhT#Y{79gIe0#BHVq;lMQ7epX-JGDp)%4(f%dhpS~$sSNzdh(wy7u;eu(ej^sAC z`QPcc-)F!3$L)O3*v04Crnejiv{S4f{;7Q5^*doh>Eqg+$7k2;v5U!h_g*%lKj%ck$W2;B)b}_?-W|sP^LjnP1O{_s9f0nx32U@%x1n|Bv4;a-Ur< zU3pudwNdp&(zAnCrY}_go!z};fz6WHOb292o6^~zHHdxOu2;D2?&GsNkNvJ^ongsv zKsZ9r{`hRrssY^%z6lSPpE>w*0c(P7Lg&Q)Z8vn}?jQg5KX}3Gixn3)oE5P6$8&+< zLF^y#1CMXWa4-M3eg5qSZnyY8n9k*zVbNE#u9KfF?NI#w5Bdup>&SF`{~?|u`k$-9 zqW_WE`JJF8OA2}44<5;p2?%&2aY4r9m&BSKd`ds=ff~^p{dIdRTIM%5^{M zv^Vi!{fv1fLWcz+%Kz0_vh@9xw{zoOSah9uHFd!w z_4EH0v)-Ku+K^Y<`|Zu#FUpL||5{fkibiEkVkxU{Zkw||zIsXRE2H0A!|bFv`oErd z+56GzNAHa*8(vOi4U?YS@A2cOuFp+Hj@>73<%)H#Ubf5Ta?!Ed^>V&jmuyfxr+y*P z=w;&{W@FzcJoo1tO4ou`_unf9-2`a|YDGM*-QV`{`@i(72TyoNs2fDE`aiy3ee8B| z@AG}q&u{;n`K?~Ao?HI!pK9}u)(IP{_vG7utg8{;XLoy!@VV*Mx7j&wSah%BKE}Df zM(Mz#<{$r6Rqan&SPJM%SoqvOKD+2p!iMVnNBcj%JU+Xg?fka$HFgKf{$Duw@&R)( zyWIJPM-DzeW^X?K`273jcC}w*nD2i()+5F!{p#QhkMn%6$<@u|8r{6CueymmurHM>aX z4=c`%3!DF${RXWC{&qk4{_bSZF;qW6Yh1T~{67D1&i8ux%0FuU`s-$9PdKq_Rhhbv zM223)v6M?{x_M5G3%1`hJj&8GO?Q#z$r*`TKc3EwGQ0h4d+xt#z5Tb3%gRpg%j%JK ztk7TmxWoO@>Q(=&%a2IcRXL$+@{uF^Zt_AiMss@)b^;~ zop`_GET{I=i- zhd-W6vw6CglI3nZti_eX-M@C;E!9u2G{$um{^9z=u35}3_^f$9 z(|)Ger~b+Q5&b3d?}qpf?Jt^lR(@VM%b?I>?WRV1uH|lw2j;)9@Bjbz3p;a1wdk|+ zf7Tdt-M0HFfA)_w*xb;*(yrd`IeUzARr?>GCWotyOK6ZT+FTUS@D1CcP%lWc@(#JQyvG30}Dc^ebl9{pEjZQAb3M-av;xB}=mpk1|D*0pf zj@elDNJiKTo{zu&exBCq+x)Zs|Js)Gc5kv@b^1HYVKfBLAKIeni%ls4PD!VUTUz7X&L zd0z4Rq5qMez42FN*h^$M`@dv1-Ml=XJ0d!FD~r!(?#llizh5l;rd`>xpZ7txeeb^C zqI*s;-ckGU{oTjtAODYUu4g;=+Wx=jw_n@>-4C}3mwz@W&@(zPvn^5k*X<1MAEpP+ z9CqS&{{KU*tYNpqQ9GWyU+tTfe`vo5zJGAyHm<*1k+#ng9{4@@eEhPM+|J)*eCAtu$M@eE0e@0A|S>Jy!m!66pzY`E>tnjafvKmEAVadFDd1p=Q}u2j7HP4HN; z`N#L5_4mEo_f5O`hEMs&@A}8N`&$kx#FX!|x&5QMW#>KVncqKr*yq3f<9ov*PB`;OwH&B7zwd|U#eypS|K}45u0Jw&2Q4OMxuN&L z-h^TO%lkY|Y0QoGk8^h`g9^v@pu*AK(!gTD&0~DZ=Wg82fBf^M^4r}>du~|t6~21+ z(Kz90W8HJP`nVewON#>I86O6l7(DR1#uF&$w|xfRAD-ZbgZ}Jt(;D_S#y9#t&27(Z z+Skmg`^Wl+q5r|AxfZwIeez;#uxS6HwfxhDrJr}5l6U;IfI0m(&%r}8kK6^VCS-4( z#x?gs;WIu7C8;XT{jz5NKyx#{AHD{qbkKO~$7lDCe+E^G^0)ugKCj4~mp^&ig4ffQ zyX{rgvr3+^WWMS|H@S=RrE`BqhiV&N2(P~?wCB;b*Y)c+UXr}}VxE6_N%x!d2ob=km@65?g(R&Nut#x5_5YvXKrK{1`_ z>rP$XGWpRo>9&vWUA_rdfWZ+ia2+X+Xlctk!F%r@ice{fWP75~Hk|C4j~x#Z3( zb3OZ@?ghhhInY$vhuOdH_U`+qUh#R8&F?w2+beH_a%#}6hoO&icV50{bG{~bd&TYd zFA_GCNqkKx6)|^Kp3k`-)L6@%@3Y(Lukm`ll}p*|M0UQnykEDqJ|OwDnY~|>oIv!o zD+hg7>bu|MZvXi0?!zpNwR0|`v3yujDGxuJ*lD_EKS9z7fS+_cBjqfg>E#J)X;P4*3Z@*1=wuMgK z^MudI;fNLU%fnwAMb`Cx7Ma-2WqTo)BO%xRv}k#+f4k5(3qMu<$y#@QE%{tOE#^o@ zCu{Q8xaGNiydA8`f?-96*DREfP~<;-wQr5Lom{O;@V%QS(-yhxI5kK3gwfK}SI?sp z3TM99^XBc#RgQ!CpU1qra=NkYE!(=1OZQJn&-fW~ zu50!7WB0PBD2MlZ>hX#GJ+s64!|ey2pLU7von4yz-oAI+zjF6~mX(Izmi|0vc6(3d zc8mY{Pmcfm_Fnq;xw#uoG)}IGs_bbz|0D9e_2HU~FB6~LKaxA|^6G`v@6-30&wf(< zy+ZBS8uiQlX5i9D2t@t3od?>VcpKE$E? z+kbq1|KPrf>HU9gH@{!-_&;}0ydEW9G&0760Eq&fR_V z?Pt&);M(mc>_pPe|B3x=|8d*@X;18$@{8xP^9Fjp+skwKuCdIX=hC^qv&FX`?$T6_ zDPQ>V)eC*iA5W&;{8rCh0wsS$9lBK)eB18)U){}r{x8{fe)G?N(=Bwr{`ar>ZU1(w z5f?9$+=YL$R_~g5FYznGtDXBFE-AVA+}lrUMd`+lKCV!Q0Lv+0YMRr(j;u5Hk z|KKuPsBweK{KsB11bs_>PFb)dgiC12k9%8k#l2V#8t^k8aO7h={91D6*X?^=7`Pan za(P*)P|9)gSg2ORf$cfk%npecG(=Y&OK3U2_Bq4-y>=~J8g}9>4T&EntaQ8dG$M=7 z_TtO~J7(0ZRNs{1(&8$-tVS=yCi^DW=0%O$F2B2E)w=KdtS;Nh3M)5%sm=1v(M`Yc z$1`_+`sc4^we!<&{`oiQw%wsS|L)tZcscRZ8goA5=PXGd535d_Dmn4f;fafmu1_hO zF?nu+cINV-krJvuqQ2O}2`rd8-%x8lJIkw$-oWJ|nz3gMR z>*ddHmp^~b9NZnvx9_j}SN2Ethv*NHeHX+tME`NsrQHz!k-c#Cjevi$e@rhdzh`!T zBmei$zr4Yg)m%8>_sdWz{V&V;f1f|9ZmXZa{0k`l?HAPie)F$R<=gqqKmV%N)tB_m zzg){BbI^GH*PnlveyeTW`RB8D&42FV51+krbYFQC|9tizG{&`k+G0&x|L3zGX4{>P zeVupy`Rv5JL%UVf7yJ{RC?u+s9=QKh-R0it9tYDG+V7S%|17@RLv-%$FH1iBAQs# zeqSwjTGx%}D4uidN}s1XPClTdl@Qu`L&?nN_HIV|X}i8i+9~O>TfHy}xObuOw#$ZH zOsgMk$?woh;!)ql6X)%Cq};LnmlvP%fC3Yh z7JbbeN@t{-uHC3hZro!gy3%p-QnUY#Gxb+w>``5C@W&=*4Ws+4(H^c_c&{~2kFeqY z@%VE|+7b!X2M>b!ONAZ_OlxM`;mg>qX#;N(<8NkyB3y1tLPOtw@W6g_)EK1^Qgl_;aeb(eZ|p~`Q6rIKgw z-Sh6&Hf1XX7EzszM;u=K)?;|6%wA>h|9*M?t!?HPeubni?O4mYZ`!3h?AE@D$+rbr z^ef|aq#YYA^IJsD>O^xc;5Y8sFvX$qQf^?!?hsKAFCU3$Rt01G+`YXu`I%8uOcpdm zZT@p6@X_VxKJ&M1Tk+63&GA56jLg9v&Ik(u@8&rYE!77OA4vPQ{)F*@gGv%S0*ri% z{f@BLe~>p~n9hItU~~J5hYAL|(FqS6^_UEj1V0pLxF0z7LGXds3>zMvMG{^18G`@# zXEWF|A2@I=uBDps;0pr}153GPMus(0IT;(X?gj)*FR^Zx;f$~l$z+~k*r>PQz#_jL zHsXI3XV~R1{E=g0oAibG!WjvbEB%fi6S(*2v8m@bANb#8$Ct1}LN(!o{o^HOe2SqP z5^Pi+l$>{~;t|qaaQJ|A1Cu zR67&22zYadA-|xf6b>%`3 zlUzW7X7>-Czz>tY@H6DFw={%m7$}<`^kz@aTf#bmk`}?b=1;5I8 z;eFukvJcByw9ijHqdp7``&36DztZB~WW{cc># z7!O`f+O=1vX?}j&y7Q9Vc80Teg%mWO?^@OSLn$aQ;2yJj z;-fEXE4Ae_cbeay7PDw$gTWig)`UWhrj>=C?fC`Ur&uhR(D3lb(*@r-CMu?1yJYr6 zj{T2GW7i!QQ;;i{bYxicq#jLqcQEt8DThpj4xQZQ1OMwLOp$FksNHb#l2G#o3Dwl% zmgSKVtC~wUWpFed`(VTW{ppbfkIeX)|Ni)K!=m+qxR>h=qY3+(W<=a$Z~QM)lOv!0 z{|-O%KaC%j>_SX_!5=!WMXQQ8J!aDtd$3H*?BIj?qjKzu6TB5Z*gx)P=t$ua`e6Pc z=EeLcA0!;b9;^~GJ9uERJiCF6d*gwo7@31J->}^lwXn~b*DN;kU`XOlc7}`}5_cpH zPUK@}$Sg42u<+vVw3pxA>pKqGI=1T{40-m!f^RybglIy7tB=giX1+RSg#-DXFASQr z7yK~b-rm^!jiE!MH2;6@T-8S@wesv3q!yANe6#r#^?_e$!nG zj;g%ojt2%$uZX%uA6Wg-j@7;~+d!b?_5&HlT{0Kfum!ylIiK64-}#|_N}GbhrOJl( zB@K@(crS|x%H0!4w3gYGpzufBn2~Rmikskpycr8RzJ1IHyV7;}KtS7pM-mP47niVF z_SjYD=pM`}kZ1mTll|cTc9w91N0ZGCT@yPac*aM_$Kmglg4AvG@)HuzNwW)_k^ONa zoL%oU&-VU*Ek(Tdg&zd}n8&b3CwG4O2kAqV0zQd(m6k6oge9z(T(UIm_HhPPlc!?N zAO7X{oT-_NgQXAStD%VkjX+;HQBBXhsVPyT=XqW`k&b(r*noD$zxh{hbNM!Rt=Q$C&z99+O|x#AfAEad!yKFY zcIWTP{Svq;cuW1b-WA(z_4C(qC>G6P{K36!)rWavw%f$Ms@+@4@Lh9(Jm(ETA4i7M zIa|VC8_e}(k?8br+kS8zyJGC(k15PiK6gVa{9o2FUG-(#w6JOym;DuI@eM|kxw(6` zhg4lrT&4O;;D!Zr^n!OS+ZXcAQrf#>+8a^-ycca3bn_ivyFIYz`{JHsDcQWsHKcxv ztBQ5Tw6E+38+>@~@>yo3gmJoqQnmLEUUwvvJ(|gZpmoyOh1td6tF-??Y|x12#J=7OsD^ zf2C`&8T%Yn&OGh>?{gpijL249wCpIu4J#q{>PMgc$f!u4T%9-Ni_m1|x-T;}U2bQ| zF*=gvsitGrHgCxXtV_vOF3p~1)SLH=ly)DGn>Hle>1OlIqSYUbFz_S>2) zi$`0Q?l7NWT*B|z?)>n^*N8u50yRtLZg2co%&A^gkWyZEe~KwvmcN+Y^L^1@I4o*6 z{uT26!PEbs-zkbsH~fJ9;y?x)9-f3tyoWdrMlDE~+( z<$o>XG|1CtvSUB_{~goZ1&Rv}yZ!ZAw{S^K(RuMLfeRFvIRYhX*gOBKpz@cpPyGyO5wFZji_#+17TDdBH~kwpEM|Wm&_R5B-03 zA-qYKjfv^nGn2cnvrPP1mh9^6zo6<+C~_dE@q{cxisY&gq2-K|mL1R$*xT^llv(|N zOQ_'I(E3lfsPJzU@`Kc(B}VwcH?~wxB}(_3h@wPb(RZ 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Π&1$2ehvgHZduV{J|z zQxj5nY??1>h3Ct=A7kvFf1sm&dhBFYlll)FdTd{Byl<%AQ8h!I|3QaHV-tg6(S}re zHjjW5CI9_;O-_l;#sBPL5xphe@}jR3l3gZ%dz=?8X^7x409M#2h!fiir1fIQ%^_yZGRY zjSL2i?^%U+jF| z$U1e7R~5^F15;w8C%HXr?%N^D$nTi(%Oy*}sYJrc=;0G<%L9+I1@=C<#%CzDN3_F1 zR**}^c1Ft@c9sP*zBe_bNj5zQ7iXSf_rZswt#!c(iARmwEOK}>H@K>6nuxU=R9h00 zrKQ63NWg>X;1h=5eQv_6&TQE$_*_FuM5c=gh|ZGYZ*ybU<~ZLbq3l?o-_ON-pq7X2 zKtsZW3w!(?6!5UQHB^{z6f!nUD)2Mm(e`1V-yjmg)YHZFv4mZQw{-&7Melx=qs@*x zTsRy3m>sIrHB9Bi1^39i705Fl3*c3l`Jjbok4#%2&&LdoN`pQ=Cgn`aR%RZFB{gCU zAAWFej4)zs6mp1TJD_9v+#$n-U1XCwHw))hwuV9nj>Zdx6I^7Rn}28suskr*nB^i+ zuJ|G0i~>Ui+Y07+IcILHJ{4c^quvKJsxJRz`qgrq+YFQV8JR4MmUkr7Z=rR8vo@;K-Dq;KXVHFI|EWkIpi_j&{na^lwhc0kYyyl+4z#T35Rqe^EM{Ai z#g_Qu$vXYzixVxSLc=}6&j2GNfv@_BqpIY!Z7^rZ}Njh{~q({T& zI}eA0UwBi)!iS2@Qkz+u4mNfOHfb_?o!}R4KHso?Nv@CcgF|!j5+6)RWO?v{^&Qut z#7z$i^tn`7FCVqBPlTA>Y>Ji8Ep&?ZX_{c)QNsCAI*&tGZ|ggj27{(+JR%}o8ZQ&xi_PNva=6W*=V7CS zhXqgQk}Vm05mThtWCUB&&bJ9MH5yEOFhk`=TtUu(IG$z!@khtC(O|^h}$>mf)pp~<;M)RlN@4v4%!HDiuGhI?D%jO#6KvKIjQ} zP%!gh!u9Tk$_5@MCjr+NZM$2U6XYIU=aFSe6WVc5nNgtWoD#S5aRGJ3g^wE^b{}a` zdE|Lez#)(glyEo?^hj#ke)ZZmU+C)UlY5Hi$)6JuILM-SP%+HG{B!GrqX#4zAN+sK zp^_9bL7}1k^#27ds+^523z9x0s;yXh^ty7BVC@I#y=-doC%;p%P2T3H6;*LH_Km&_hXRZi{o5fS;N8o7z@dp(Pwsz{9RI3}5)YxNbM(U>FaE*A z@Npg6_dC3zu@#1e^*`Jg54mqVHIFg*0lODZWBbgn2Ch1GOWdVuPvt#b-QmyQ#Iww< zqSB8cqKL=fsi}WkBV$ZNr}ah;4z9!>QyL#PEK}V-Yu|)Fr<4Vh#XPni)W~KEZ`za? zWKj5hgMi0e#{h>~yC;qUVod?UJ=%prX^dAEt`qN>$GMzOgvF0nb%74!IfK>({*~MX z22GAfna!IPxN$lj>tS>jWljiVebDfs(87q7t6^h?1v{(5V@C}aj?4usEM}!9#LX7s zl>6Yu#-yT)F{-Pj;g9n!MSxW7R zNii|7`w*bnT+|BKvUx#Lm3vQ3CRmB49w>%t}xq1VE?dLt z2-S;+0xi@;uPa+ED>aDV&T>=OAjFYk!_IzKT(YCFcVCmGK?L`KN8OH9qI-lGdpKJa zS7=sDY2W&;qJ@_?D^AwUK#%*N=|dNvm})%dqdUmbsNAR+wGM=4eDeyb1v5+e8+nO;l~SYgVM5MAZN*w7TG$}G;re!BhU z_T!B$D{R>08A?7F+Y8>~XJpPW_~Xg^`2CkC9+mX&sf@)3nv_>7@js|#_#oige86E6 z596t+|5yxl7c(4?;bC0RY$LE>ie2V`4+4ru>*W3UyLY~qVQ*;6k$$jPj_HVmg6E@$ zpE{g4>{oeTnauvdh!>RpIOLYIZ2a<2!-V0X#s{N`YAlLhnJo$w`5XKAug+%wz`v`M6wZDag_>NbwHg-9yZ!lcMkYSLZkQ6ZIHFv@Ub_*qW7lA-=(Z*FC z%?UO-+!y@CXDmEud#u6kV1*A?7sEpabt^M1Mx`RT?-OqBJXW5?7<7E1Q2X*~C2mnukF$nv->%J?+7DM9Ou0H6ATXN?`F znbR39CWsh(2-9M|Co9ErXyuu$O%G&JA8eW+Ec5BIf}fO)$O(}LKHr-+Xptm41goH3o@*~<(0%nTK#Au)^x z7RaZ7wqD!HH&iXuzEBgJR^7Z<;e&utvv!zmsL)I{j`+<-uOFPi-tp>yihW~9gbfSZ zg99=GQ<=qC_;c7~SHE2|pTm)*j{W$R7d9;H<=?-RE#z)6TE%{-!9+ov;}j47)sE-K zKk%_Q33#zLH1c?`6&S5$KF8kBa4jPCQ9uO;pTqyMmIE@9ECy$68+AAo85FA(6>GyT zofg^auK4nCAJ_3M-HakLjJa9%z2G#G=PRA>*|s`)a>)1pPkWgw8(id=SPL@NGx4|? zvo|!(KfHjO;Q^n}LEb=tDU4oMXD1}jXPzmr@VWDaiOS0Tl?Gy)OAgFoz9Ze2c;U-Q?arPDo49y+W=SvBS#Or}MvR{$R}iU=L>_hhlSy=K;M=!3U|% zUtJz~Oc4`7x?6#33X=8=;MD70y>$)l#RpTf`kae<--@u z)~^R$(8PTDAaCp!8y-8hMgAf>;>-seiUe4?|4p6E_9bMoC}U>_AB(MExOn?Vhg22@ z9u9}48!mif{QiddqKh#9@yi^K7I0l}{~&R|E@bt^;GQ2n#`0{T4>vd{PZqNI(ZO&- zh`o0Q6Z6l^%FF)M%?~~-Y+1WMF3rYH>V)40pOrT>r5HjuB`zOw_!-S|V+Df&!-o_9 zmYB&;Y*tXTsj$&Ab!v!Xswns%Q~QoHXM?#)b!#)LL_q9n=KdKP88r$A9!+m$*v8G6 zkjCf7d04RB^1&A?rVSI~3J)ycHF_`1B_}eee97`dA7VZRUbw(F`$MFSJTudQ=$3}Z zB4UgUM_8F9+qXCDtUlS=uv>Jd)B+1LasCuHK9(JF6Ga%d+iVEq$XIfPhpXq%_b%3; zRvQts;A4fK zMFK|;Y*^jj^x%x$_%guB=z*RnA_J@O*P zNK(q+2z!%L;K>OwIy`Le_*=D=TNFPWGKh67<1w%NG}+-9tG|+q4%d-cAr>49w>NR{ z3O;G#^x|BwfH`gDiN=Kq1si-cIKp0Dnoz`jPoU9BPLT2ER}Nd3#g5%4{Y)#eSQj2y z@HjF0U;x*#;>G|@mI8gJ25p|MCdXqXGG3g_=QtKm;CbL$d@w?$CSQHO z7#28Qe7y9732S5ffx{nl_{9YeKLC|-2kPfBuJU71Xo|C8Soq_YCePs?VvHLVNHgz^V`Tp;(oDG`a8$9^On($ZeV}S|7 z3%faiYzY@b7I_#SVsH#&zk1)oldUPJC9!_bs<_JK*@u5HE3h?ocTaV7Z$CJ};X}&8 zgN)&Q+B}Cd1RLhFHMQ^A$WdW=EI>^CXt`+AhLjK2su9-hy>SJCq!f={BYDTGg$>8XH?j1K)=j~J%$HnJ+z+W)EMAmCDhDRKGC4yiY%jx)e8+ahKMGP zB?im|adM7_+nf?)KIAdouq+ZNydd|{K<;6(6{pD0z#i2~mP6+zoDi=*m?C#h+-9%V zhMW?ygee~%mMLuz>EL8#F09;WuqV`^AWUF-!S8ct9QHH{2JC${^ZNYCE7l8?S411O zviPfTDhRkK^b|5w_pr$5sxi+v_>7}&uAIZ3{!|g}qxozPGzzA~=@+HU=+I2q``|%w z(-+~UMfGlv7V`My1qOKOS2{@+$nZKD@N>yHF=*}(WVm!N!KN{J^>OW`Z>$|IYG2|i z_{YZmY2)=Nd*ql{1M>SH>``Ra77AtNxO3rz925J5=CVB!0*ovY#%zni``AA)E39BY z{m-7ONxX@{aN_e_+^kL!jvszs-|%3nd)n0lC+r&}86#|1IFlTV8>jL&XhAOD~xgoPTJ++QtyZeWYh($-7M5v8)v9; z1x$Ugpq#znqk&2fS5wo59xaJ?Yz+Ij+SVSJk#Z=|L4(nW>BAhyj$WH96ZoZj;zU`t z2+z@A3>5pzvUKiiZiiD28BtI6E;!Ubp_dW*j1`}gSRLxQ<3!n+Ix1F#3i@SA?0o$5bwV7|KXrjN{mQn`BJn26 znH(3N2fDC}#@*b`;v`|o_^80y?t#R|jN)Ztk_CT)uJK86aeJ7AeCTj)a!wPPCC3~3L>M1U;W=?3gnh4<^&A^!k&ZPlc3f$aIT827m!(0*z>BkK z2~UYC+mXB%$7Nq9H~-*ex+lQ?;MC~`_cMpzZV|(AmGr<#KGPqS-bq;ROWyt zF8-9g6^>K2n6(;cr9BkPoaAf}9pgmR`3v*g04?ma!y$m>k-*a>hxfZHzGw z{scKzxPRzgen*&1Y{l7v5TWmE4kuU@n!ef(@ zpwr1?(fgDm(MxH@M8k>*0}JLRmxu!kWFC4cbS-~mP}pd&#-Kupv8d^TAVFt1hlrRsFZ(11&VNpgmiyadl`E)9zV zY61x|4&oPf2zNRfo)_bh5?i_8N>t72u0ETrNM3F~8%5^tED2`EcL=m9Pf~dhB5{&~ z>F^_mS$qb32FwQq+E`y0OlWj&{Luca>1acwT^CcwC5GZgg;bUU|5nUmSX6Q_y4m2? z&IgB9C{Eh5Ly9l;KvxB;Qo{o`hfB6c4sl8eb00hy&B@|8yP^1KLWtqd#qkW^I}UYi zYvbqCb~HT5(qgHYqslmiDf^JXH=8Aii`DPxGD?W=c)Wz)a`^(Cus-|<6c0bVvmpNGA{n+jdx@|`trz0@J``%Drjwr(2?t!GG(H5tMcxE?~+X|f(*~u zR3AJ%Y22-_$0zs6gb63k?pf&U+<7ne*@u*y7hLSV+xTb(WO!(Mdju>v=*X~ula;Y5 z-9?82NkXDK?#u_-179AV#)oO8#5zb)bU9swWY!<;^>j}K{{iO{K> z$ZjCZ%WP(8R93vH`&&dI2cns3`gm<1Qn={~&R=m+n4a}5Oc zFJykarH_q;@rOdA@S~s^s~8;qYwfDBZ!9r(bbKkY>4$1((9eW3UV8FxW;rZ+ebwrl zH2;Gs$_y`5wZB@a_V44VkTBL0ISTrk4Ka*gV*>X`G&OjCT=+q; zZ_c{u$%lVfT}^$pz;V{$gAWwU!+2uW?5ML^y!K9oVx*1Lf2Px+4IWN^8fVruIMlN| zoY1l|s9l?lVNGDe#-@nrEKA*wG@Sk-@!}tY2Eztsg&Q_39FGEi`r4@QFOy*tVp$sT z!1nRshu`PKe_zDrz&c_365)m|DXNTyZ+JUY8jmr2Z)eE!si|XZw&l0IoIXc}Ywv?5 zhL18GwnqZ=TsDM#*s$L;nHv^_vNJO+%9Mv6)9 z#Sulu|L)98tn%lpL5E`Q_~U7(;*dVQ!NIny)O>j44REITr67@ zzxu9~{x@OWjE>h$Ne8bqS*RF&bYPsU`DjyvSa!E#2jh;5FDLOHh?CI@fA+_Hvu?}Q zH)6~>0*4T%yjvko{W{g8$tILKMrO8f*;Ca8YlEx6HL@*iM1sLH$8C3eekGYj)q7EKbvCcxl{|L z2Zsu-o|uskqA2r{y)v0`!CnD}4yi+Nj!G2@jj}S96L=3jV7bTGATN5=d7mZTfYYD4 zqr%Jw9PLzB@9wz6&&Xo&xw>SI924jNqxx(N2TsT{|1+y!;{tST!0vwfZ2yrEFa9SjOU~Guto$gZEKeN4e@&*I82%i^1 zrjtriOj#eaaI`fqj^jAQ#=4%vP4!WLEz@zP>=QH8jGGw@Cr+NMnAbk_j={kOi6wDC zfoub=(R$If4gQ-!W=3WNPx5VUZQUEW+oaAtmI@ z(xdr_Lt<~!0RgAR_Kq|IpWr*L3>u7aAK!2XSa4702Q}(=7#DmHkp7{tQeW@+*{1LJ zL+y|M^?dM;g8?KvkB5sjDWIRP`GCVW_9^%GNbHfQQ{kUFJ#{kZhAZ9-!=eUmhF7X` z@;~Zo{xLI3*s!oAKm4e)UOe&rbQa~KuZ|QSe$Qu@&(GTN`S1_HQ*0H^q4y7^21poxFl)Rj(6Ym5J^!PQ zRaY_v6gX8MA6tBgkJI_>k7*0qR$lMV%T=rHQ*88&=xS+S}`N#w%<{yQE*?7WT&TvFYR z3Y-^@C>Y5Yb12-FdD!nIcJaiXkPktEt^9%qpC&U_NbYPp7H}u)&U2;U4aSQ38Y!FA zjM;e{Ia$}UC^}Z3a7g+bmczDZfrdql4~Ib<*TqDpjrxr53lte0?{ui~7OUnL9C0eq zuW({}@1cK4sQQd@Q}PYTOx8t>3Sx@F%xWACt1K0tD2egQI(qizur^hAedq{sT`t*@ zsC^=+ps7W)Kt(3G;TKC^(St4NrF}9LhRlA?mH1c>{9xmFV_>!ZqeV-?LW46x3~>u4 zEo8M^l5_K7Lx~grWP{>KLj4Txd^4D>N+!rVJkbx~e0;&ISaA2%;`i(yq#0y*;=i^2 za#im6z9~TI<`c1fW zt5PKK!ZGgkcIP<{8fd*dklZrsq3{g}rEPkQ?&sjSf2`JhYL@?njb&VdV$4;wZ(=`nRI z6qsUcqsH0JXd>kI&PtgjVYf#dhmOPpTgIMsY+f%6Hw3O|h%vUYZ|7htn#%wFr%j%x zPt(MxS=!9Iv#(~zZfvhP;IAv!d^Pn!WyrPM#}Cu*y=yCV zW&D+sWjB}if6|BSQp*g3^*>OA0zr__Z*XEkLEC%dP%@%cd9B;UDKe+RxZwJpEepqxx^W z4CnuM)z58GZMiMN*V*{-ely2`Vx9~(jQE}0EArk%tcbSq_n&)gwUfZQ*DFp&{;1Gp*7$i=IgF zXR+(?;|~;0wJxuy5M6Y9E~Djz)9u|2eVdv7USkzr((<6faC1JpL&}8{53h)JIM~R1 zS$Z9mEYr#eF{Mq+4`*udo!euV1i=I`1jk$t{F1x}NL7C-^9a=UI9qJmU zv~sW{Exsor*6_*h@p?6pFyC9Lz3Jef~ht3X7X7X8h>cvG-Ai;ibc& z(kbutm@YQ+i%)A>)DX2NkCR(?iHLaMwBvj{M-OW4`Q&u5;Gb0PV{u^{V{y;W9S8Ug zcyccM@i(f8ok9QMac0$2|=6uio=cTKR%VR-f1#j4@{ z72z#D_Kh3Qa>Q|PN$JZk{-eRL?D-Un8lELy*+>7?Oyk$Sp{8ixSi;!Vvhml}+VEda zs+}64sV^E5>=+OJJH9i@=#judOL|4TmD82|Pb=qc=TcZNvwUM4jh-;wwKGG`wX${{P+Sh947{ zn}1|Dv4Mt5njbg|bvM`sR;{oT>TW+!+jxDGJi|i`sTPJN9=7&>`X2vRvocn^jGwBq z^q!d0g9gUtw@VKnbvUu%{VuMG{~!CqxqG+9%X(FBJWzfx^WVDH(JlM`e_WKBv4^Mq zz@e+w(+fCu|CRd2c{$M&vW#! zZ^qg0Eej{kEif0p(xBY3Sb4F4i%*9!YeI*Y>CcZ5nHduDl_k0@8-4_QTvE)NaY41B zCG=jmu@g_zH5YD%1Qx}H72G`6SQ zf{tM=$H6Z~(#xxKjFtNr+-%uaaCY71&TEPlN8F4)x1W2dk?i!K@S@0xkP~TPnH!?# zTBx@>yb@&jBeI9-;Fpb^joI_K+6(V{&f#6OaPgA!tRMFG*In!DxLVdMp~q%>{Z4^> zKlAthUi&U)7AOX!{_9#T_C(Zv%e*I%2mYm`xX))&0^Q|REf#!0Z_Tp3o&tSra-x?H z>@cc$weewvX0vJXp$~>17uYxPf1G*fgOku}uc?jf4OI&q7`~QBu3y~$FDP$PbA{e{ zHjX+rh6j#o#VeH98~)qKu`zGRzbJfQHJg}tlh6jkk4xkZ7(M>M+E8F_;}`p79UDhI zdqcw&=^xkI67I7%HtbQ#=`45r>|58*k3k($b8>cZWbvRJPH1m*$4G(j| z(FX?-xewS#@H26UbsTj#yr3q7@r6A5vHx%Cb&MK+C4TpEEL(io zu2QS^4|fS6lafP<+&Ie(Br0tO0iU|1+EwZz}v_FkxsG09|Zr!luV|A?ZD5B46W! z_E5gRwl1ZU+Tb`8PktD97wz$v@)x&tJzA7{n9SxJ8OOv zw#SIO{Fuj*ept&y)ovAxM0QI&nw_?;U~if-glKvP4_mWe9+Egd^pqaPRX}v9eU!j)rT4V z9vl&2EEQ>bSQ)O?actS~%NN{3Brhk-;wgOiH!;!nhUp5o2(4N>{zV7-8a`~aJl=OS zzUK3(R84vcuCTMR~--LJb2)i#M{%aeo4;4nCD;=+BnV z&h|@9)V)ojq(o`w!2fDN}&za;n7mA~FU z?`*uo@rp;a`N02qydR9154Jz}VE?>1Aoz;nT#LA+5r!784CCRA6l)v1uLwU~fV+`Ln z2)7AlCSGnm&L(BXT~#9A@aF1VrUPfvO5_?n-YBtI`^&O_zpy0pV&mcEjxRnMoOo&% z!O`}7c4WhW6M}~y3jEOZtm4QtlsFQoWz}%_pg~v#KkFfbJ3VU+8!haaCpGsf)W?-P z_~aJ)UmBx6Om|zyeKg-U)8zoQ&*63;}w~$5>zRv0U+x z=;QEx#@X~mN{nNkmGa?(bIT;_84L_klGXencgC$SQ0bLE5Y4<`;{oN*r4JpB6ckvj z=Q+>hoXEnpT&;0MjWNsP1qpg{7D&txc6DZ)5ir4pkKxDOhZj9``1wSdK4>tv9KGSB zmJq|=&gjP%G4ZK`k)Z3s4?(U;9j^U+91a)MG!!fnodmKkGABAY@d>jnUeDHF6=S2p z<9%>~MdQ+CZT*X|>a#w&s9g9mmcKA0frwxC7s!3m4xdlAe|jRI?0#4A!bjPFUZ zm(Plpb!9&HlWz{Ag=IsM(gX={#&wSw4qbjUr+o#tRf$g+_u-YS4<9NN9&=k{5Z80h zNvWcWi9xsVM?it_JsEb{MO|)>pYU<7IQt|~kca2Ukz$GPIC<76ofy#tuQI|oPt0*B zkSY;xYcXEXGozz`w*=m2bud_#8?>vl5HOr7-i3soX^y_ z&u5RajW)}na7hU*!#}D&Hc0SR=?Qx)7zk*5C}4WTmT$nyx+j70;oJk2PUamAv--Fn zpO{>w5YWgX(;r}@p~I%6Eje3+>EwYHKI3lQxu8qSU0e(rKa}rj%6($6xcZbroL0pw z=7NJ$&sQ`tYh=z7<+uA#&#*)KKSKvE8;8Tu|MLF=Kl}{O===Dw!oZn@flrqIg{%bs z!6xxNJgUde% zdpRfASrl4X)~ly}_~69B6r$G<8OCSHTmuKqEd))ZIzLViV1&4rRdspKY&wZh9ZeRF$ z;Dh|#X3m5U@;jOjIJAK_iF|jkKm31{Ap89(D}JzDb!1R1*I_k$Q7+ z3p<8K9|HRKtSMWavaLpBI!j*o>Tvh_e_7eTA9>aAehG`^tPIUY4cBuO0j!Pd4H-}0 zQ)LtpXl8m>VIbI8@nS)8;ep$8ZZs)~3clhF;J7m3<^fN}NixMg5h4e8q+QQ@uWV3J zd=&8J)psF9eimgGIj&|I;Umu)XYffd1^O`EOUZol;D)H5&7=0YcLg7;;5t}UAi`>q z)bUhB#YdP`e$mApE+Sll6-pcpsyYS+d|84k0+u)&;NK(8n8x_T;bDgzr%D08=p+`& z7u{?Oo(C%qa|p61URIQP!riKN>W$UhV{>PiH#xIQE)h2o;W#hB%ev}A0@Lpq8WR_l zY-VN29FIi9MH;Ax5;b^Xq zejvxQFx>jrCH8ZVlodV*D0bF=_~R{mW6jFL5C4BW_4nPf!awY+%m*Ac#i%m1)Nhe^ zwNYV@K=J z^*#Rr3L!krGSZ`AkaKAd>@hk-PE!@ob$4|yc2IOO$$qnIt+co+{{kf>2%&iLSc ze${`i$&UR0*MO!axcC|W-mqc+x%fkdeZcCUPmU-*$nUiK@WK24EERnYuT^{Xrri9) z#Z$*4aPWbGDd-9}0mnTy`$FA++~-*ZT9_=y#2oa1FWkZSy8F=wXBmSVJ_vX@>>W4oIBT@vI7}%zZch>#tcjIL-)bY>{iCIupqsOp^ zIZ=)0<)Z{17X3;MKE~^NT3PQIFgG2Tz_47&T2sV8u(83tD8k`HKp^Wn7GvXiJSy&c zg!tMHawyqIIUDH9J#Z8;e9_d#qM$DOME8*(M}p4-N6UMrT9yiW4=h$pJg`8KDWvrj zA6tgtPJtq(1qucy9y%EGGd*}NK6gF4!@_`qq6&yB`N|UyAE z>*#?!dV;OzHEk|v@iO;)h!axSyUrq@EX7Hpw@XP~kx}2A)-=?i(Hn zwlb2@huH*AJNeY0kPZrNEAVyv#cm z9RAS!-@)?T#YwxhWYodW`Dw&~G@b>_HH@!Tt-rZQ`S>aCzx(uORP2mu*%uchq1{;UFO^mC!O;Wv!uT2g z?wG>Q{@=s=Wrcz8uO(bL;l1=)zO&-T!kXsUpP&8@ zjn-;!N_ap0idZa5Lp{SUW`>$zsR{!p_J;qg5r1}+Eqi2;6p*M=v#$R0nahV9Y}mgi zG}y1&tSfv_udXwMiQyaLj~e+S0&-032B{8*KeVmbf2&50`PYOB4#9&D?9VPJ4BECd zzG=Oc4{f z_*n!pPA#=~{Wbim``P9Lb=&OOgi0g>e%<0ZBEc-)#90$&zn)F#Ae*?^Y8e40(I19W z5_T#))(}+CN)r2)u*=a!nWubDtND^gDh3apuoxuY`^0fz_Cb|Hw(kyVw3$7b;L@{1 zy|TNy(ZQfPwa4s6Q;i05Uxf;j))yDn1q)amAFQdG%KW0moyDoGWm%(PV1^Dy$GLv? zLcb4FUgzy&VvqTKC^w|`w(E*ST&E6M|^{eLO++ogT?bW+>CD=b4vTT!kw3M z-U7u(Mwxzlq=efT_PB{FIV@PK&+k5`ectCEIx>o(!nf9O?3CeW{Fh;%AkO$^Z~lxL zIW9&+Jr=7tfgdreyB6$`WBw!bAW=t=Gj8(b(3Zy^72WrTPJi%n;rgk!7K<9C*f%Z< z_x|TN;l=+=N!yM-eJ5C7z9XBH`J?d9^m7N!@87+4(rOFIeg`wQEx!6~`;1Ct`~Jz@ zXAt?T7K|@>ly1heHZtO1^*Z>&rq@#+O>Y+#|eoF5}s`G70jo9UDdQ(!~DXi zp}}?+?>#Na{sR`Zdsk=Pk6?fC`JctQ7*@#-|1{i!-fOSQ%-B5nVq?LSm2rm@KW+TS z7VxmT*@<(PRR_1M?M;W32`n5AD-2Z5d(UuU5ReI}YJ0`e;BL_Jjm_bNhxN{OlY=W0 zoLodS6wMcv$#DfdNR4F(;Aq;nobzNG7t;r`lv4_M4J}NEYz0D+n)xz>8#bJ;KKLPQ zp^%c}zQipq&rYauE_m80w5ise)#;MB#S9U#RzIP=;#$g#i}cx;87E)l+HpWOGDGRg zk%bo=UEV9O2)Y+&G`}xWT*}hiS76sJ*Y2!7H+*S;-^ULcCQBLia-X}B+0DP@-~&0i z?|Z~q?Ss1ck{cZbpEw-%^4)0sNWJUFoHSE8jx+OF|FXU+5-9NFSbp%xiw&)e3pOqY z>EIK8-rb}b&3KrT@z@c8tA`I>j9&0%0#o4?i6K23E4RDZMJcedA#|G)^g|7{^A$24{|KtBhc9MA<0N!ui)VjG6S3BnyTg9CK}KP9=&P0fKAd)Q!gxeF3tY=@?N>c;rk*Kc5vSJI=$ztZ zM|O4mnvh_&>Z)a&YX8+{&9Hl}@qx$Rttnls{5yr`MVd;#vu;<$*|xqdDJABU<}SN# zp(hv^vHaz2e*RV^b>Dv*1chevKQk=&P`IqSN zde5oMRvSKWtmAhv)thX=BW`tCgjvQ;k)fB#=ZgbZf)i8s2}kn@juQ705)Rl%@VF~+ zpF5a#*}G3r)`p{HImf{zkD9(XHEnO^bQj+v(AUSR*jnAl!T#!jv+6ss14S~WtQiJd z1Uu$E%4EDgjXSPONg?eNYb!tJ%5$P3LM#beWfFLfY9%GK$UQ8O{wKJv>C1&PGAS}X zhb}q@@;+Mlw92%?PS&xHSw^ahabi`)i$&~^|;FyaFDp~X{p7;POhPRlty zEx6#z?~%6mL6ht}j^*JyL>Q)?<5lo0J{A!6;mCrk4_+vk=t=V&6wzZlqVr38$%_L= zo7SqQLEftZ35(}IXcD`%dneQ=B6&*L*Y?75a+D^dSg zzG*JAf{4naWaaZbj(?Q@GyLDX(&^QToeuJ+y?IwLJXQYqrG+V`>&W`P=ON`K5t1J# z8PsLHE3j2%KlJ~7?M2}*E35Zz;hcwGI9Gptdf=RJ<-+xc71xR;?cF(XR_1#)C+o=* z+dp%yjQAm))Om}M;ZV@lF!7%bA~pa2scQUMarbD&k<*uYC1XC;2EADKbIpq*Ow2C> zDvDp7<$q$j?Broa_GL#D*bX~|FFDSk%CS>`pS?+d=i(Ff3PnanIgW-2$rD+cMO;qa zo5uQ*+2D%9RW}CdKDIW_)65qNEx6ehvl^su9n5ZYSZpg0<>1Kldlr|%g7hXwwki!a zjss^MgQu)$Qd$z>!B@`GV6&d3Awu(0GBbO@f#yRN4I!N@Y=;#1D?Lse5HC^;YGV=E zbD=Sgd4e#HJA;qjf;BRiS6C)i*a$epmKe-sR~6eLro!&AUWBoqyO%McwDQ7-(&~dI z9tNe&h8rH;Fs`uB;%a26obV#8{u~F(61T&QiW)saZ4PyF%nnadm~dbL>l2I4GaSnI zR0J+fXi{*p5#d&4Wqab1;3W6J$!Mp9xFExgI~@{CEshmgjtNPQ6}}F3q6z`!JREOK zvh1{5&Q~A)V9NfW+KE*!o=y2d=~@wXv&Kd|2>pwP{7%`p|7F=jDm@a!;LJZ$6jjO5wu$ zJsD@D8HD_~xlf;NpRw~noRH|7%gh@R820G0Gwo3S&>_RH(!$$ciA9~ALGj*)3JK>a zAJUdqUcDn{r6ZW*a6t9NVrIsseiaVY2Tcyv1&WLjjt@34&(Lv{nIOez^{_&}@nFMq z<)wZcO-h9mH2B_^bm%DUr$vJ$g zfgx63weKyI(B|M|sCX#CF4B3TSwP>fa|?I&p@1+65e_L)gEg{}6XICiZQUmudO*NWp(nxXeTKuYK*tCd4QVDjiR#7>9VhNq zeiyrS#Z!eAXz(dt6cBF`5~g6OJQoiv zV3fYdVxh!*A*@4#<;4OOmc>)w8!$CYp6Jvhd3fHJz)pspdjblMH#<0NP~&xFs0hrL zU|RTIgz>P9?SmVWn-(!l6`Etk%H7lCvzTE=i*M8SM+ZU_Ss8k?T<7Yz1gw}VdhKw+ z!n06J^P2nk|b?kA-0mpK-N#r`78%?_r7R;cC3@-y+)JT_eso5&jVSN7ddQFJg`B8 zCtO3rLP9{;Vb%8?0uD3WnK*=6uR;*y_uWa-0dw6K!(wCQ4HJk6TpBqwhzpRHrqf1`XDXp=b}|% zASuV;tbFi*cAMJ4fK;x1d?|4rnMThq8c$T=(bh3ozNh1Iql5Kc;jRT;rA-Ywef%7M zl&n4;NbJ*`+%chHf`Gz@01M?O$}BBf+Ab%$d0wirzO>MFbtM@%~;- zy+&ml&(%QhlW`@69DOz-?E3rG@K?Y3bn*H6PaNMRCd`pyh>(Bkvu)Dst&^!43+&t!mJMrc=}VaM2uK( zI5HL3Wxi812z?c5khyX3Vk;dX$-56G$S4#Fd}nD0(fKgt-h%{9zb1ubwnT$RZTXxE z-FpvS;J3`=%$seoghR}TPwx9(f!RwoIv|VWRwg%v1Ib;C0S?{gniM4D zzBty3a4Yi$bG_=~k(qsdkBZvzV+_l9qH3N@Y)D@3QgEf+$f;|ZMS{d!yU9&o0vuYJ z!j+j!60$gaA53$vzBkQEXTbp$XEl?Kf)mZBI2@T}I2?O^sckT6aq79gft&foVJ1P= z3Wbh-9mk_g8;YBN#rFB7tY;Whm3KP~qFLQQjNm)jh^7T~; zmzo;XgjpYGFuRHtb##%6nn!OzD-d~rgrXh}j+hX>CTg>x?^cJ+irJL<^t zv@CdT+q;O{(L%2&VSB?9rVqu81gI-A=0#QfqE3bX-uksV~Zeuxk z_gPbgknxotr#7FHc05pF882=2z4h=8&Pr)kh7&3b2K?;8yEGU(4~cy6zi0DtG`iaGF#J9debMpaB89%i4Fc}1jcHo$_AN*6 z@M&sn$ok%*puJN}K~dryi-3*X182qtG1~+4SRd?tUp!h#7r1%*lqUszo1 z*qVwCSjRR9Jt&cx&wA*l-5iVzw=BS#66auQWIkBY$Hg;6 zo@YkKi#YEK9fDltEeGED2OiO5V^~_9Gg18_UrL*i)jW}eCT=G82@WFuA`U)c8hY$J zannmyB)kjAX6gSM{P8`{In8;Jb38Jd4zM#;R4j`#Z{aC>T6XLI32mM`#>^MbeNNua z$-V1?v73U5TE#qvgU7Vk9V3_T6$s{G^!U)k5?VY-p~OImF?)8vUN^1=cLzUqKDV?b zTzd>F6gkeb9f%R_I?kGOkjJNkhlxocEg`{*shFMVz?+~wN-W#wAG#velDJ!w=clk^ z@jVVVcH6{&tE>*X?mGk-(hfZHXxzZlJY9v|uE}DHSeNp>&lhCc@~e+6nxkiVtMbL+ zgAX*8uHGWf@Ii({-M#6-Gsl&;6?vVd`cy=DT19i4PKbAGsLXLuOf zSr|FEk5{v<;khZuUZBWlJuzZRxJ>z;DTYmI+;I~QtZ?!9;G)Rp&|-Sv4R7M?V|gqJ z-#Zivn;H9E0-QM<4irxkGEit`)#pkG;AH-oJa2+=lOS^(kJ{c>-0rLmD}>m!&oKGt zY97_lbkRssN_f;*&CSKypeOl`t-0$vlf!~0?kkQF`YvLulL|uQxMtkA+?w>E;6@rh z=j4eytpW>-W-NH-(bn(Ebn;RPN7Ld-i&z?)8;VqzS$sG=cIb;TF&zk)?#xhlFp#@> zVa5pwKEdUJtUe;_32|)`6nOM?xb94F64a}5<`85SJR~5-9{ZAY;UW&PF7EeS9Mu;Y z{whdYR4}-3?`@A;^hR-mwP!=1!;KFc>Y1)A3i#nEbowBNg4UG%f2Qp3TAX=@w~j}E z{gGQUlWgdD^B){xWT{x`!u&~*O@pUosf) z2V_=w%R8z+{wjX`P2Wec4J8taHIfkqau@aQvlu=5#E~*DxXGgBY4S0i)(^Eo(`&rt zwEwbbEel9q(6Dqv?5TC$a}Vi!JkY`F-hMdHxhU~p&pl2C=7WL<+6v;nTN)S!Lr(Hc&583gkC9ptT_RV8Z0yR*soo9K4na8=jnbeKDN1Y4JU-X0{9A zqFwVmGGr_&B9v?w6k3GD1ZZ%mhch=aU5Q*Ug}1qt`Itw?fr1Ss+N}*Hf=#RE@HnhI zSnW*DnA6%E1-K7pUrH!$5@lmPBf{a4eUWv+q66G43To^-+7$PG zV~A!sXvPpx$;Kd4|o|q{fKpV`eUMo>?T)(F72(;rrFlaJp4n1!9m6GgCoPC4=rnh zwtBq~T9Cg;^Huzdwc%4w%lC#9j2Q4fI`&kqZ<+;ch7_*eOzhqs{vLL`jxk^VOVfI8W#!rd{QAbRiUhp!c zH5_kpbe7{`lRe51Vqmdgjs)L17jf2u4%`AP%m-P7_t*S}0MhK`E2F;bNT+GJ&qeCFH|HbszA8dFQGaTAKt--S-%q~P}y83?RTdltr zq<=JS*;%uO_xYvYhfeim8S@|3U$pVF>n+vWjGp%y#r-vzH%69e{jvP0=`e+@u`l4v zgG3&ur>UoEA9>YSGX}{Yo>%#mp+SPH(=|g>QNXz)!1IZMa3SS%_F6iK1 zu~u-V!Vb~pesdj;JT_8T;gXQW)gie@=Agiq#8&pb?_CVp8``p$dfw!;j;(q3JrSM`lU7cTMX)T9w*i&Fa{sI3sSttW}Qd40$$R za_?aXDpPrzYC`V!`b3dj43`HOgzc{2K* z1bB#6Phvf=r-SwIT$TfD?<*3RoBKC7NlHjIHHbHTZ+)Q4)AQjj>zA+0S3UawzR#Ix zsVmX`$iYNHV9kdw63Z{dt$zA5#MSG+!}cw4v7f#sMeY6j%h^j+@x4Fq0UibsmoAS~ z=7|fh2wv{G>RR{1aQPxGM-EZp?0K9F4#t;cPPCj_@R0GLNYjCtLToaD_dYhf>o9h0 za(KY{peSmG5BG&b1_cKCF%Nbq3VmsGVr39F%;3iGxEcdCg^HMjsaGgWNZ-z)c=h1{0fVz|*jQ%ReP=u- za@@$k$dzG2`w}6h&n*Y5%q0!9GTT&yeWqyn^sGJ1b;kJKjVKd#W~Rjt8)_8hA6mRe zsp@gV+8)(jrUz1j9QU+Y9iFgD3ilp7v|uNj3fsNT!;KC-A11JFoT13*WTT;HEaLd) zy=%WgV^j4B>x+C#IUcaGh&^#?;n1j_vdF-p>GGw<15FGEst-BH#h5)j(ZI@j$G$;C z!zhmZpa0i-<{P%R|DT=be96=Mk7~@LO}|-kGcD3oa<}^bj{p6&RpdjR-cQR3=dVBi zeEeUIeV4{m8{60ga#prqeFYgm>K?uRZh7-B3uk>c3zh1>zs`rLTwcg|YG2ZiDf_f$ z6nJsO%XP-)9(iAp#d>J!`6^|`*Q~X2d!gI3CPyS|fIu z^%|RFX>ym`1uJJ}?<3qz3T;Lrwl6vsw8-9Bw8BF0paj>UgOd+Ah<7~dWICYxlAGy5 z0#iVQxl4sWbNe1a7wtI$4vU^C*mNW)%knGYA-Dz8LvH9kl%te(fw@Xe0DA=1ZK zdZWZ;)dmH1wu3U!os4(HCoL+7>pbWYV9@6x^`a?>`GJMs#ES>ooVYG#9}_T0V|U-v zB==>4WK+0oTwQ_J{3i}k_2 zT@&`_Pv!f6((3ck4;$WbupVd(BLnl& zNvV=QBmTbHw{Epa!jI6CEO}1;@4n6Ee;6XA)jUZw;hemyv(bOf$5ZbV)Or74tiK(z z@POEdZz8tw?=BmhfBCtef3d0HrTIdqk2op*ENLj?q4DvfOMkD3KYHllgdD|29o0ooC0z_Ya7;;JY3Oh; zw3F7>_HyIwHZW87iPDm1jySMJlzkoJfiVK=hzOOWPC23|j%?fC{EYu80F$*!q05ckS{KauE}3oTboX za6rI~MT(PS_aZJumWG|rm=rvH#FUuc9hkvs&mbZeW+BO(zm(ws|9!6|wF#$}EdG#o z{OG@=W49Eao#y9%$Z#MbhL=gOu$|ILuq;d?jh~Tm z)y5x&A6kFgtaLczZ6@ERVOTLub>-sQW{s7+i1k<11$It>1*KLDk(a-GsO4sTS+r}BCjWg7i%WBqDhg!G9E&eK7iez$ z#Peigj%dk@Rt66qTZPXPW6yIcM5NmYG-RZ!c5pHZFWBOGFe4J;0rGT!60mIpO zF+vU&yqv8Gb7Xl6;w)4X7BDv{*ofM+h}}Eb=5?^K;zJ9wvaNs@`$GjbRUSqbIc7fA z!y6Cya-C$T$agz2qfmp}*`vS0it)^0<>u!ucF7a@t;~bF-Wf18d=1~&^map#lX7A8 z+0M*eN`G3!JJUEC!bO(|De1jsnBb$e^SFZ^SMP(fzw}sI)E<0j+xz?=ha6X&z=Y>) z3VMZ;8wC^&3VzUS?&7)VxxrVjm19oIa}}|+CWjLrdbFFq9&!knpnRuCqeHi(@j-+l z^ZNupE(YU3r=|-Zj9C``;9*HWzyJO}rl>_v6{L$V@MRcYXaBaMOr@`Tfgj^T4rWpQ zsksg1(K#tR_VYeC$nsB|+{B@g8Q}iM_wj?{&OfAr{{IPDQSHByXNrZfiF|89%MCaC zkkx!El=bDVv9>oKJb57Mk8D#iV?bB|OZ!Fc%l>oEK8y@Fbhw{~SHf$9q!G)^{|4d#w+cL48i$vlXoddlsN3` z&`C`UkZ|Ibo+6jja**R$fg*2(liar>9jXQ@j7P2XnIAr9{U4+#Jxg|?t!R+|6U&~t zd*8E66nw{_&>(H2Cc(#+sHKp`miQo1o8v~CQx(q3eh<52q{NsaA(22~Iw4pP#fndgQqCdy9*}iwhEL23HLnEu7~rKgAqUbm+9L zt2PVk;l70i2LiNNTGlBBpK-{MJuky7ugB)jE&x4lD zCp`DGSRYX+IMBjh=^)1R-o-#eiLsdRMK0?lJvknRuRKl*#QFQDCI$R+n6;p>#-5{U zjf7hWPmX}ghSaQ&4pY^qGE2#8$!q9c{q>>s{iFFp)$ZQ%`Zo3rJzO0D6&$8lwC(sA znP=Fra40z?Cwvg_Zc%Uuc1dsMZ+xI&%J3k8gN=ou!H)gV|0fcAyu%9Yo0ETk4@iC# z68bei{L#aUmmaepe()-er$*wzpG%t`emMF0;QT9x9Dlr=yzqyJ(8WK7sfRbQ`4?pH zNVjXN@bE-PwlX@oyB%O>m=F+FVpQeMEG9Q0LasxXOGDoxBBYP|B`@nre)c6ik2v@x zxLhhG*(Bci;KU|*lIcJcCxi9g4I2`e4%-TPY48OYv-ceAC~Erp#xXOUi}93}rqAVr z2f4R!J2(6gw5xpEeQv_!3dLsqf+DWO0Ire%_7}#H++zF%7yK&>ghUrBsPOQyzV(pk z(-KNN#D>a9!=1q&MAubZm~@NzpsrZJjE)jxS2mYpa!hPJG9M2eFe%cN;gK(l z)Na*`30SGXyL}3ycO#F1knMqg31$y!YJL?3h1)1}t>;_Vz3|2PR^D|wYhTxJ&l41@ zZqZ^{G@-F!_dyPW>Ic6<8SBczhpl|8D*v z&R(&jLPcv{lcdJqpdB?e>z5x{^yq2ggb&rMq7VNB^|Nd~6o0^G-{AxD^K1k{tiG0? zDycURnsEQGeQ5ZX$NUQ?e)yBNVaJO5pYPmC^{hw}n9}zscvfpzdXuwIV~@yzb#H2D%|#w+orRXK_xax%t;1Ol!bBy2OA zq1fag!@e$un~TBg6=yhSzd+GK%Oqx|VkYhi6^$SW;~gg_ zLr>#{gabP|q7U*MsQ9khSn1?{kvov5D#=HX#pZh$k;d6zxH2@khCzQpa-kx<~m{NQy#gglOwG0e5iSu4Im%)a0(=(th|V+aVLJa%!h~ZvV+D7&voia}^9?g(c-Wa4 zS;Q7SaW~LoJi~n;ZjBQ!oA#UzO)h2uHL>bO4gtO@9Z8l3v&zQigftF^isXq7MH-?W zk_S2XWe;?4tl{X;wG=osq0#cgKV}9khNmSW^ImQ5ROG0!W8vTu`m_J2a+2bQiK2`b zc;%Pq6&SEHR5-HOzGiE`zo~4te(u9RoCj4H4&<*i<4Aqw{vNze-9w!tsQF?2r`Y!w z&fO@nXL34oeRcK02EBRw4{W&k|9L*Uy2SFMZiL)xlSk{FZkd#kL9l`L>M9~H$skE33e+*Jw} z!k)O?>0}hqkgW1iln`ZleZt|v>O%rz$_F{7ZxQS5lx}onI=<+^o*As1=Qug%@VIhc z@F{3;Ui4Uy>Ai;*6Jx_7R)!Nv9hHK` zTn!JI)7>03(o8-zZdc+^OGw}`a1ra0Y%Jk$T+iXU^N2u0f_4)JPkV);V9a#R*22rl z9s%497M|hmQ>!Z`Jh|LBqn?f7gMky9P)om72#>A4;MI-`6POuSu-{UxU&i=A!Cc5? zc9-fg<;DjJ&U=NJ4S4<^_flM_;(ERPgLp%OfdgCUo1=;IS4?75?~Q^ zH}!fyPVst>CeLu;v%1~$C33v{Okr$_m13eCJ69RaC~y%oVpCA!y_kPtV0*%1xz ziy}hJ3}WmyrsjKJG<}Hb5nsHVjm3G1Rq-^L=W6eY4+?M}KP1%lj7_7h>B@?ZE{@C% zPRu+XT3Am!Xkqnv;H2Stws9i|TVg`cI~Orl7J;Q)OvL9H%=G24tHbsRMZtR=`rM1SnL4H(!Ws!SEbLheKV+y@%#dSZwpUXWYQIxhz^Yx% zl8~dwm?5`EpU;0?i`u-5*Dmk*TWx0<D5MfEsXMI-@kjEkrP~N1l;)5gesV`0( z{0qMHTvG61{B&wpon&RR8OI@}@3w-BN?K2O4?0LQKAMoswsU!tfgJa-gVIx;8aO(N z1O!>Ki0!dqv{+!FT42B@wLy74C!@pP6Kl7<6kerO%+MGRyEbbX`vzV4CYIC+ZeK1o z&W?NhZAs}XGP1NRIGYMH_GmB`Nx4`GDjc{WvSdqy2S@XQGd+{9vtM@u|tBtMa;dcXO+;^AG=r=|JVAUz@n{TT)J_F0lWD9PUTMu zEvpjxa_Sd5{E^XH8^e6`M*87LkL_;7`?tum1@remSi!8+{JikHMcvU6Yq`-fm`u?9#(}xCJ3|E*IPB>!ew?{?sxbr7d`}G!u4;LgP zb^3LXgXJpESR7&>WHAM@7<4Dp z7zoZ;kkOFtq9*syW5FW{g#g374_$4=EFOr-h%Zi@;VRKz*|?zK;F6A*Q(*yB8cqVN ztu_*jJzf)x+14~fMLDgzA=#lYvoYem1S_jz&|V>?Z%4YD1si90Sg2MRL~*w`awOGl z=szrQp?iU*fx5ulBMn=$Ssad7$h8>X<32u7AowgV*NP1@rXQ4vbTlwzx4y%r6!&dL zfWYxPhFtdqdfZ!;*mgcq(789`AcsrEoN&cM$891ckB9FF;5g9toRLGK-@ZYF??QMxEl2?A2i+Z`jCU^VS`7k1t-t*KU!6_yn7iTNMz=z*iR1D9AI8Ir4iTi>eW5MwyynasiIUL-S zTMo0cwKZu9oKWHss|;%0BGl|Da3SuAbBHg`Bi4gwmWWSd%@1u72od5cXKr{j--d@V zLRC$jZ-*MgLxm&ajWfgzEF!e3IXJxM2s4IN=m)azOfK-^RA!m?p(AL=1Tnr39_-AF zRW1oVD_EHXOz)gZ=w8YCqF>){My;sLL4h@zjK|nzcrG3;kmhGJC=%nmH$A{HpH)DM zzxtp9mouZGz|KH6Nrjy=bX^o43CM6XT&v{ZiBpvjop|q~!huI~UrK0jG`BcbB_tO$ zosgGsWNBxqKKw(AyFvS=Pu1naU*j8ULuM%Jn121)|M0^!v<$8c-rT6FhA^&QNAbAwXPyc<~`$kAqLs=nbwWd6CETvUtEY`l3HYQV#R`) z7ZR8b@;7jy^#y{dq>y^~d#dtaR5a7#EVW~4ruadz9YphZer ziwbrm+01<+koHN>w8CJ@x~kX?XX%Sfhm_cg1SED!ZS0j^bY@b7^b%1cM<<1evVSYt_An&=Ki!FgOP9CDIPth4yks+$S~Lf9>jD8y*KWGOZ%*d)N1$NxZ!+gag& z9Ph*bEi2bfzc|6bflZ%H|AT_-{|YA_#sl}*{#ASb-}>Od;*c0CR&AA8v0n=&*!Rfs zFdjJdkHcZnH_dC;P52p^co;r7UHUqUO_{x+QA9GbHoT1Q<%S9lDeornOSosq!@QNvxRUd9B5hK{q5C)rg%5r^c0QlOnAjl7aJu>OfyD{OWj;)(SlMtu zZW{YiX6Jx26~+~=hMe~V*&953>I$D)sEH@EiEt_VNjWpk<~qOkz^NsHPh?-(bt|cA zX&7km^m_}+2y}&CGBRL#FhOx%N7WKHP6zLdga<7w-w%uCTMbLF?R2mAj+Jumq)AN`O+DB3VQ_m{s*mj`XbD5-O0G` zGq|2Ky=G_0WL@Kw`DDqw2T@9v?_IbeS12@e#yQ>TR8ig|*cZOHaYBqhN5M&rGcuZu z1wQtTJc5UH%wpEY=zafpr2XIn1y?;bh97IZIh6m(@^`lfObtK&Vb|^tway0rxSA3w zI7A#D*q{7iG=W!${ocQWpEDi%nh!YCscJFLxz-3`z7lYms&F-`@71oT4;hRXDpXxx zK1g~Rv2OLBXM31)0~Y(We^6{?S( z-~?ms!z(;26E!}V{H$hief+|Pt+2dDds$)tt3vd;s*=N9v+oHsYhQBWf53EL&hvl0 z&gQlUXZVOZTb;Zx!_ZmzV1Twvg&6}k};}O$xmp z4mxU$8FpN9J|EwlI3lwDG&5^ng(A;67RAQu#s&#q*4GlOOpPs7dIf$0V(gC=23}}# zwmfjU>1ER;4#_==3VUBlTxXr3pO7NN{y~C0_@2K0rk$!yf3Y&=l zlf)l^JvDp7w?6#Cv4EZVKz$w08VQB>#}CM?TA_Duq3uT%Z#L!yQar4D%uEcEc-CE1 z*=fQi-pr8l|Hy{s|Hsz%^-pc6KiHuE^zc)GANA}9A1L^X^yK#q3bD@ldI5rkRUjgNH(+#yhqE&w1a)%xw@2#uEf~zJVJt*ho`Z{ z;oPB~1MH4fH7ZQYsv;X3*tD2CqHoA9lILM_Ut!QC;>~)=@vy_Gf*X!Z64{L`g?E%# z6C64BC@d|SVjwnQM#6?YA!}pF+q;w(YAvwt&w^O0TxdVePlB6apV3N zeeh@E23Ns*Jt28$LVOQW`3*%93$dCz9t!|uP@S{%UCTPoNlf)$6`wl5b z_1PO5*LVwM)&}lmbGX2KWOrSK;&g_9dLe#B<{#|S|9Ep~P2qKXpkU77P#IV(Wh2gf zz~OuSQ)ht+4yDlM=&Njv4HmnfH}3yYVBheL_a-lM#U8~S63pGFKgC~CsNfK-i(fDA zz^!j1cb2`O;c5K8bt~E$3>3vRzDHLW7O-Y@ZzuZXs zB*4Vrd_#)i$y6bUr2@tlk{t^CO$A|cAKvir@VuP-o}*3nrNR;gHlB|h9829R7I9n0 zeQ~K+;CRC;M~rcaXj6j1gmi-lSphe$9g<#C9X|L7G$zIg^oUhEPHkszThzS4I3b1U z#mtt5Hjchh0sSRCa|{e;a#wN)b5;Z>F;%EAY~ntqvSyM}nn0rx)5m55CuX-Q$5kB? z90!*)=o~g@R%~zxcU>@nS*>ysTillj6;L5?FuC5@AnxEXG=ur{hsSU7J%8tZ}$ZyA@hbm&?+HB41>;KhAcr}RdH~!bCXR?uFVlh5m+zsuQxc$009&BXe zwoPYAXmV^cTw$UkQjt<>@JngagAFeldjuNNs~ihD1%y=|3JFN=5olaqp~%Luue143 zW79b=rbB$6+PDw#7~j#=<#_6D`(RNj%kmas)_LN5vaI^jOc9Er^SUK8MZ|0$bll_Z zbUZ9jc#vbwDQh2r=>>|+hvOuA-jxV7F5dg1>5CU%N4Am_hf&z`i%nJvX>uG2I?9b4 zJPIis4lxQT@&~#YZ9jf+kZ&ldU~Mb-eE5eZdqd;)hs@shcmx_3C^$X!V{d49vNLEx z!ufMT3sUSECLCaT!1VCJ3JIOJUu~xIax{D`a&%S-n8~TWh_j)gg(13WL7Lx$7$J5$4zu;;!{qCnP&tV zmYjDzw9bpou}X;9F_Eu9;(%(4@x6}{GB=ek26)X_+2?4H=FD>Pd_stoLD&Iq4u@TK zPbORlak|%`>*DL8uFzz-$AnRU<=`H>S(5!zt7SSE7qGHAh&DKQ2|fMW7oK9#q0hXe z>A)fdA*PfS)r~FAf&vu}FC;8g-IRMNny3AscpkPY2ssvnf4F^^L4fgJh;l_|>%tElI($4|dxO&V zzSLyo2&w2{`g`xA0axI?c?BNKQ_?zgjRHBD9Ucbh^k_J=u^y{#)Zq3iF!oS7;gF*E zM(e;)sYPsgjx3D+A`MCwk!Fi3nSZfW~}Iyx*m=iYa zKVKc0&>%2N$fY&oZp9iSR&{>11!5DVQ{`DiQ*WM`(!{B7$mVK7-50*EizJ@(ooEna z?P$CsaGZ60K^BXX*8h+Lr?j61u`gm**z3l|&MwrXSIJ$SE8xhvLi$CAPMV1mvqI85 z4lf%ChQ9S0j12}KT$r@?EH!qV&1}l&Vina9d69Jm#|hIfpA6ztm)}{?q7nLHMkaSf zi@QUrO@gxMCXR#}O8Im55!i?c>5wxOqPwI$yOw(F>Ypy zLd1og%OyFNFXBk$@GyMQ*f_aJ)W$-!c-n$JY8(e+{2q9*Gc8^?xp7K>qEXWJ#r$d9 z7HU0G2aX6hufFXtfrV-3;(!og)`bfdi(k69^c*pA2(FfF5mHE-wdAlsz&%BckP1iU z$VZ%a#HYRr;kD$HKGC^Hh~1q@u*Z~pf%8QF>4%-%U$Y%H_$MQF@zVn5Fs^nlws%r; z{l~pj4%QTwmHJJLs!(rSXsF`J@Ssg#Dt}$|4K-zgnekd;IXj3V#0?df)$l zd+>>|@PS?a|E!Ob-|;SRE&lNLf|MlhNx4Fc2Pxm5*BDzpIQ!(mwKLL{0qXp7+sDxDLkC{ha6Y;zqL-wnGe=qUivS@R#C1+>1%~mg@Gb7e@mCj zMg4z2E9;(5<>>U+ez(KTMtZKk{Q}j1FOy{W7rb_Cz7Y5L7R!b;CUPwaCj5AG7r`nM`di8G5WofHdi zm^HKdGoCkYx*TO-_VEVilM8RJa-4iG$G(^0OlsA9jvg+qL&|NL4^D`E5^~5~I3+92 zxKc6mXyl{J8Ig}2XG~fgCplS`yM>K)$(fgznfIvhoYPR|acQ0OP18|fq7jG3_NpS~ zq-}>zsO2lP^L^sVS4y^WID65tBd8*Tv1{);85xd%xP}i-u@742o@JNlb6$DjOn~UA z_ZqTKdXF)lpUC|ovZdKE%Uwj`_C0Q9g~030iCc6F4)~Z{zjl6=uly-K&IJYz3=dyS z|HCHL93i0csnvOFGDFS*o`(8Y+dPbaurV`KOtp7(QGNf9D{b4vRqa>1`ycFJoBn8P zKxM}r#;1ou*G^(cT9Ei_<8Rl4yb*RT3=dhn!UPJccx*VdAFybBjjH|sBSrpT_;hiz zIDskRok@WOny0T;ip^zjXjIvM;6PKnh8&0UffUdI>rW(hFgG@FEogtJ!W`P)@Ps*_ z>Xy2A#lBno?F<%w1eP&B{QphpiujPLx0SVT?f-T+)D)X5c8Mv~V zC8ea_>|zmm^gHFpyP_lS8g8h>-*4&+zq$F;f~)?=j~>$Cw~mYWzkHvVtX*r@^D9~P z@yZALwtRLo6rIA#q-^vos_{8*+k+(cjyK&G4o0_aTr&CM;(OLp`Nj4Qb$IDDfU!{?U*K7w;h*x9^tX6}8IFzrLKLt*2cqa5#=dt^;G zTz0(DTym^wdz0eIV{WWg8obdb`ZUzkpD;(&w5%5tDKqPNa3DogiS1aX5?h~8PhjvR z$4f_CMA{r>xDRGgY zdnQ6_zOyx6eC{cIrt5htv$Mekp7aYnEtd}}yx_@E?wb(x;Hgc&2Tm~6ysY@}!+`w&FB=Evg9{SOj*UDL0+K;SLRXlU z7&Tu=a{j@@pfu?@r^5oy#s>2Pr$9GJG%WdXLXP>*gbMlZpd(n=Sj~D_CfG7g=UMQD z+s3{@g`?}B!>VTC)ocMb-UvB9uwTpG_`gMti8-Jmg83N32l)r9*%lm-Iq<8eNkUPJ z)xK@jl*aV-uiXb5J{W3z@c^Bus3IY7u)#v)DCn5N<^%OzJX`_^JZ#KdpcO<8FF z1HL~ok_NJO3J;E7lv5mjK{e9_&-OZ$TJyBP21 zTNE4;^A9#JjIfhocy{>X0y%*{F*bV4r;hLc@r&^vv+>-bJ+F5yx{!Ea-LL=CTNI8v z|L|J3QdVHKwR-nWITxpm7sPcJ-Q;jKxWn&oK2!6;8M}EGE!Vy@b~(?#D37PyN9*0k zyCp{Qt*cXl*Q-|_erQs~)o_YmoN>bo!vjYmzq2~W8F8l_{?dBhD1AkU1z&2jY{3LA zD+@XHr1BjR+S;~{n#&ju7fsqLQ`g~1W_$u_>69XOH5+3B*yCyu~>0(q^@Z6o@#mW-lb2CNqBy0tKSg{rw zUT$Wb7?E~avFrK7nBPYf?_{JsGhj>7KB7>)qu-;VK#@_QFX5ra+&j8n3a&w%=OzR> zwOFi}+~F|kLx)?1iqI!zr{n_{Hwh=5ydiJ$;mjWi$KYAw8G3O6++T#89hCZ6jxFd| zD$=cTh28eS0VRt^<$E8kcq3Xqm*=eSY^$#kRYE})pM>(wG&ko9G4y%Q(dp@J-On(= ziR~P-z~+TB+>~q|Oyae?&f%)P_y*H9J|0<~^HLTrOa&cvHU>;RB^r`)l5Brk9|7>VW$F$A1N4$%5gLcR9i4u;AQ0kEfy>`C@~R#FQxrLr*-N)jVjF+!K+U^R33@k z6L4NVL(Y?jkE1izHKlW}^UNs=la?D8q$KmzKu*gG`k*#v*XbW&`A;5Lm~kdH=}nou z!^rBSCOc=X(hMze)|ZnOByWgjsBCGx#=$GZa`2--j?kqki^O{k71noccfDf7xmR02 zo~2<=h`ADPQ-p;EyC|#9#Dd}-I)bwtDrd7EZ~M+WrKc(U>aR_v^Ij>$8ucx(eJR$} zD)jt?Ds$)IglSy1Jgz7BKF+kRZ~G-6_x7?|v-;)|8PQLE=Pnf5FJGAvx?tKvha6#+ zMQLpd#AQ<1PHb3zxFU&j-~6%HgThrsFEtcm~ zGaNLuM7ZYNJLr8>JL787CG#!SOh=Zq`7tRn=uNU+*WBzL>F~lxW=`6Kp`BjkQ+<+s^vR)Fb1!uzjEDyIVxjfM(S)PB*!Kdz!@`Ur(i4_+*z8%;T!F{}Kfu9stTqM&$?S&0HR5!|T9%*^F!B4O0 zu=j)wzQ>ldEO>l}J$M_N`MnPpdka|(&c2Z#Y$klh{HJRr?|UoPHuVoDi|0vhP&1mx zn%A=<&-Iw1_lJ8gnHdkp#}*thZZwW%cS{!jC;fVX1NX9?CG3jTF_Uz5YAP%}F!^RR zgTjhWZYo9Z#hMNzw8Vr+vQ6-<(~oa?bHVq(Jxz8;`xp9qSx-A2{}rnAa{12bMjs7g zST8hPG%-?5iHp!OW;`aIrIAtNRM2i(zc|RTym3}agm}*; zA+Gr=vW#80dmk&Vo4z5hkLywnn2XneSSOVDh|`IZ%|?>^ji@!%6p?Oi;_ZPRm$u#=3(ZOl&c z?sq8UexQHH-J*NZ$N08`+KyLbY8#&R&bE6c=>6!y6PNxE_c^~d>_4j5;eRl}^usaE zwEJ!M`Svk9T*ofBq2S2;i>d+ajKYh)-nkI-!b9Sq-scbZ6t7ANyUbyIF6emtyW>%o zf6{;0Wm6d*|B;cHm#Xk^`69>V3Y-AvRXE(2K+u%|5fl{pu#48My4Ip_!<9d7&z&L*|74sd}!fkWISPha1W2_ z-5--;R_rW%-@3@LU|LLk@u{o4^&*;F8!G&Nxilmw zt&lhWzagQ)j=kZ(j)Yg(1-4Fx6QSHL4XMhncup-`waZTbgQlE_V}ce_1zUwwC+j1F zKSo_sPhGsvAG>LXW77t8>vipiCDgyYS?J7SAielsg0an}!w(y_t$mk0mxrfep3Qml z5X0^B+sy8NICi^E;&%RF>D(VlcIWeXEjMhO_u*v!=C@}#+pLdIFPwLwthdG>@f_=m zyahUJj%w`6>1e?V2O~~=_%dxp+IlPju~nRIbWP*_;ilm zUodHx(!uN$4iUD4#uwr?L@=efNVL=>an5^YV7TqRbAXzF;{+?teU6MLly~egYOgWh z#i#WA*O9%fmnD_lgbGXo|6V9id&ar9^ss~K!NUge8~pPZ>aVg0P+?g(L+Da-tB;ss z!-3FPcDZ{}5_%>ML3%IcJ~dD2xxVM|-(`je=Lp^Tn|$xylaIj*n(CPQ+Z0rd?f)2V zyT5$zfj-TOq^96+_4j!arsn=gc|P;aAH%=*+w5*Xj%8%*5!T(uW_SNP@4VkV72!X= z9FKdLyEmNu&WB^1*X}Ls-}?>}BNFPf>m=^yAL`iD_&}kXz2V;!Z~5ud8J|W=$Z6f{ zwX>7wKO}#=_0+!gj-69Lx7)`EwCrGfaP;Sb{G(U%wi$6SNC~t*{oG`JBv@Xk{qxbk zZ+iqAw=f=9B;>w!@t-MEi;Qxa4>;Vj4_LnT-h!APQ=Ghy{ah?0u!2K$$v^2*;pRmT zHCrAR6k0^Ask`ms=o8?=&&X^siJy_FvcQIgJ;~vNLeK|0*1CWcIVJ&t1b#L>_J;o^ z%=I-Z6k2SUP96UskpMb_%lsgR;@=fKCPD`vB&ahyNHBcD;pC7ZaIi^em2$0fBTEhM zAHipPc)M)`7$+}TaGK+h{mK<{Bm6>*0umfO(}g!pb$u_{bGc#Tg&=;j_CQW{cBYQf z=}Q|O{;;qzr`EShI~jT@KUK`47e^V$F#_Ad$_M{XE_``$ZvVhU?Z`^Q_s(aO=kMX!xs`2m_-uI#6wo?(P3|BIHTBnz+oN_ z<3W~cJI1E)u#goIJd6iE81Of77&9~n)gHLd#{57wnuCk6qiKeLhF61>s%EIxLY=Z1 zMra$CorE`DXb#VKU%Z`cT{y0BsP^ccg%i}{zj(rY;TQWQ|aD>j0YRJ zX3XCp$EP%_@rdQY1;WjO!7)=4&Zy)FS4bSRxcwk`+5H_&%@S(m_oUNzSoH*QAJq}Q z>0p_{DBgC1Z?SM+n_hPF0{x-`PeSFL*7M|kf4D$cZHMHX17GF;Pk8r_O}*ybmp%*G z}J2D zYs5eCoD~uNFtz*WV?%Ft!5{g8JNiUU>6f#-+3zr?;qg4lM%}(VdbrQGp9`8}ElK8+q}%7i%Q; zC@>#zXk&bEKyGzGg{slo=7T&E`wtwD;b&x$pCTR^dNO4C-^~v$NHsgy@m~615p(k6 zk0}Bnj7MX64%|BYLhdWS;}JK;sm4bc=A2%^X~p4rT6*$AqmKJe3tK<0V@{Zotkl=^ zEdTG5GK*VDUlX#~h4-2@JluF&^ZMEsGwv_f`Lc&yK&|3OFpGga6W4}B9giszHw-2* zw*F)Izar>C1&6?q1xXLG7=Nve`>|t=924t=L>0-12|SEVuC0eZ1U`CXa7M}@`{M^$ z`Ckl<6-JFOUSE-T5v(EeYXQFy6Nf>M%Gu2A%m?bTchn%K9zqpb%LVu0w?BI$D>&mzOTGjwm^yd6@O17kAQ8e|ID-9YY$CW`fs9JU#Oq7 z=$cfYz|RYPL>sCW9j*PizDxh$9)W{Rf>j$FII`BP+TXeJaN{hyh~$egKbPy+J=k{P z80WXU0Vh}NP)>T{wC?XL6LlL21^>ry(*B1SHdQ_keb%Ob{)<8BwLRkN_+}ksJiIWs z&GsEH!`uZgf|{(G+n(7mKA3;t`Yek8kq2j%GBKK)d0(8d?%@W%56TG-Vm8D*@Sk9u z+W4~mzhb(D4&!n2HODQd2$&V>H2DI3AdPIAP8sfucwIa)fszcya#;;F> z=-_uSiBD2d#GpXO??q0v%?lOO3<~Bu6r2^6l>2bojr+etfyH~qht3ZylK!z7_-y;@ zYIxwWVvo?z|2(H8*_qW8;k~S&t*kw*PiTJ;^Ci_i?*8Wle$Q^n)#$cGtel zaBt`kdwlDrK)KB1;yJBN1t;Ys_lPf6V?Nke6=Ym-@{h7&^?aU$X}KTg*d)B=n0e>H zZKqufGiP&tR1$LZUozLMY0ifmYRwjUP1Bvq@|rs~=v%Z++hf41FgrJI)|&@z?-|V- zd$&E4oMFik*rj24Ch^`n&h z{`ma#mLI`f&Ib@_vMA>p_8$_EJz zaXjl!JEW~&QOv1QI#)v2Igk3RlG(a%#dZrm4b}q(mzGrA`qstzhVQcRyR%J2#(&-15`sBS zu{SiD?2!_0uJDwb&Ny+^LWO$nt5t2vAKFwayg%&mkQZls-29YFpEtTpsLjCN?A30) z_H8qdvu?TW$GDFO# zX*4Y}int|Y#-~`wWbE)l`@?O^Uz~qrcIeMYC_XG*`P(N^BZcL?m!LB1|5qj&7CYwe zTDZZldBQ{kIn$IkQ+&0~q}a{u@#ATCh(*{AqKO^?+$H3T>9WBbMYZUH;X zADJNalB6AaHfHBHlykcJruG-MS6gPBAmmOw))ci%}Mi`$Y(+4xoj-EJuC+!38T0*ZVJiT}5zT`@WCx<>w z5J?eji|Or<;W3+RVa${wqh8zH^t!pR>W6f~-}?U>q`=A*9iQ*E9VqveuXQt!V7beazxUw=?}efUMMlmcf!8(T zm&$NSzAsk{Q@DGMm1EWc*~ga`I=Nd->Hb&oAV=uH!zRULPR|u=#sB{it&2Ml|0~14 zo!NL7pHF5A=Rz$f{ugTZ%oj|KPF%wy>QH!O)xzVmsE-Ib z=wDX^pHu%7)g8GP3LRCec`h{1KifT_)r$G+|No{TM`Sac#bksn{R(n~9Uj@KKlpS1 z-@_@UVeJ(X_V*UDzJ4R)`f&e+A{K?mGcKHB?)x~2aXP1`=U3M5cM=CpeLt8O6dbs* zwClGD%Y9zmCydTqX%hXL&mVSBXFM?H;NjSVhvV4n?tM7E|DQy{-1OU5qVytiU+y`# z`x&3}LcaqEHjA3$4}Az$Vl(1V=~Ot?V0BKs;sTpE^TGe8g90mT*uOstTKK}ak$da& z12dcD+M}iw2;fT+0W^kbmrMV!TH@bnvD~LTN*M1j%-vAaXmG~VEJ0% z>CH6~3Je(vtK`o2-^_|IX80Ay!N|N{|8wI5`;#AR*ncV zxGdOC=>3|-l`x~ii6fzr{T+Kl!x_l{gCCwkj{A5P`f1tm=Ez!j|Exb?q1YcLzWexU zVeh`b%Ty2c2>;x*uy@;2p4{yP$2jkO4L>Ht@nP$Gx#N~g6lNGURlW}~WVHEsJjC$X zoyA8aK5YLH^}J0&ede1V68G{Ci+(%C?9Y=hH}|8^ln-$>hVsdbi$C0Bpa1_);K38k z3e%hCU0lmrC;eEUc!qV`p)k(%3#=RVemH*n-s+N#OM08xzevom5oJ4QVc-yuCDQeA zLy-upDhrP+n~RQ&=ZQ^^=CK{L3}l|rsv{%0n6**(p@R;8!r@kB6ZJK`A(9K#&L)Lk zXr5+qEoLE?fc(Xf!wIt)ABXXA?Fr&jQOj=b^z`DWI6aqN#@9oc&5|M9mE*!a=Kkin zEX<1)`wCu|ikTnqFG{m+Ji_^KR%u`Rh$^SIVklnuda{WJz z5BE*H#T+;<@x9b=IhbI??&W@x@nCq{4T}_^f^vph75m0J8n!$5JsBjHALjjfqVB`> znV##~9OIofE+{&3wxD>2)QmG%SNNOlVVB}8VyrmPzi|J7lM?(I>Pf%&4ir5Mi;>}e zCRkv0f#;aB8=uA_yD1BlpEA6gci;t|hWdxwWV}*FrVx8F@%TJmd#ft|?F#s}U) zQ=d7kk=XzEMUDh>`-3YYtPd@mg_<}Nr#nSHt^Oq$|67Lbq?(@7qa=qOh0RT$rpQ?6 z$!j%eGHOmJij#8C77w{*@$BeAU&W0t9I`4+Tuj*R^NSX^v>!0p{riOrzN05;^$L;edny z%R+tk)O#%qZFWM9jt$4W8&ql?cZV}(E%;%yt0L{7!UZqA?^7S2eyesN;gpn-i1XnD z2_6B*y^P%ltT`L3T7=%4f7jMyxcIStS%mI%(E}U?B1Z)H8JT8)%B&9p(yQ2lPh6ak zz{ken{J_R;f{u`5%T|XP&%b_RtG@4f_(5($eO#RFg%gHNmD@w2*6}F#&(FQeQ@cH3 zE>H2CuHZXQo5ht9*=3#uwBKWGTp`?F!pF5l#`Rz@yY0gn!X1u>K032J+mU2a#&*Mc z$!Z188OJ*oeKAt26>pUah!E*{as7yz8N=;B_V-|(=UTOjG+bKvs@#x7Hy%Iz0!s5=Y9By=-XFL>zA%yQ#McH{B=ZTB5d zI8DFo@bp-sGdoX{S<4ccJuL6NjxcFoWK)8q zE>HOonGKc<>zSvqOWD4-_uKJ!<2jZCH`ExfBs8d(u(Qf~Iw@A^@mi$xq=?9)2ox;}HETJa-??jtWlam)i z#SLB7&kH*jGPNDNsHt#f;&h|=*V_WT!*6$bXB;TB>L{MGqIO+Th`|+^o)sH%s_uMPrXuFZBFFysR(we2g8WsRzh`Q& zb2@T=*r##jnal2{$uHK%|9tt%gZ-^sO?UGSH@2%6^@R zez*4WPc8qwea_@1ia8R@joqtqnlHX%UmY`5Mlt2$rf*l0Znk9IYO~FCk5QN;$dF*P z@P$#ULyg4kzlz5k7cAXW(6WZ9C67D(oBa2EYvbJdI+J3qwH!XN__6eSh=s;tQqlV>=P^y!x>r?~XL z9STiM3+z;nvzo9r90~vp@}DrQm}VRNTm5Zj=N=oCW)_A7exWpe@ArolDmeI@7^Vm` zb|2~IRAk^gTH8LAg(1UUXb*cuiUJGM$G^;rFK~vbuKLik$U<{rl82+vL8mph8`}>o zywLt%U9x|U(!c$@ToG?9YTvHx-~6@W zb^RB;T>%?TnC8h9En_+By?2|zV}aYv66*0~YzHljS^J&TBzoK!%_J7FJE>&|zu}dU z(M-S1&U7Tf!konl1uJK<>!>}L-FVoWIlsXoq2;||qB6Vui`>1d`g4GD*Fh`xa}o@W^drFtRyN z?|4wYEsc-0>(H{+A`d>B!+Js!?Rl#Izl>PE=SDKizJ?Vr;6N(Udb zM9TN`ZYY#y51e(HH^L%CyYQbx?}O<-lJo6(YM(!ByP>!H!y%R%YCHe%)NX&+yX}uD zQ!2+E8J8OtGv|Dq6%^oR^Fd{%lpRuZGTEk z)9y&KyuR;vn2ASnam%t@n(sFlZvT3iM|khwS6_BSG$x#uQ8qY!-%Px%{zJdet{s|A z8!S3mAHU~6Qc)tu#1hcN&&b5#z@ghc_f_os*_*!~YntGo-OR*bw4j26-?3#uzHf-C zfB!-MpX+DXJTYZ9jSGEmQgr|RY=It*e@~Sry|-=-?w8s^n;zRJ5pN7OfA&ZJrF7=}DdKx1jNZF#ZMSrqyQb)dZhpbr z&i;xGuj14**I9k%g$%08ZvO)srhD&@oV$@{o&dTiv$m!g9n3I&hyGQY2Rf${h@Jl zj6;t2JgFTPFBDhzOGdN6!hOxHa#FWdOms-pY1W$_POzBSbRa21{GWtb^)mzE9~lXsKQOlD za#$u5e*3YBDc?hl&+?&#HbX`tQ;uBy|Bu1<8~gYCG2FYq&FuDv3%~dtDLGoR3;g4Y zk@3oy4Vn^7&fm{-CXJ74N0Nv^(PQKDhb7du)$rysx8)@~{v$Vu!A|%`esh14Q~QG> zk2M?*_-u*WPmNI59=0wk^g*`_O#e4W;ZNlZ_mF9z2LkIG8jszHNb@0?)w& z?VN-hrG&W$jz{fp#R&9ke(Vwn#!yI;U<~L*t^_jjtYSH#a37yJ@Fy^T3>w zL8Y5#zTUAtryQhKN_K5JC1#D}vJuj`ft|FP0 z?dH^S!}mP7+aK}$s(wCiv%te!a?jcJ{NQGEW9OcxVfBOgy66{!8J@F0oIIa=^GC-~ z%X0-=4NrJF-#Jjbo~L21ZJ+ytl$zqlvp?KsZ8)NGCq|}CN@PPJv!+AOlm+1rSFU3| z=2F?b!t3aP-7^xm74GNBD+kXT|E_x2Bb>XF*_fTDlg)*{sjt2wId?y(5MKMB;DA!X zgNV6_?rjFX=0Btp9z^VCKJUP$nP8EAU~0=h$r%=%P4Ah{A7In^w~?bDndNeR$D9{B z)y)oS2M>!RGvAO=ujy`F|ER|2;E4$ihjw3>ljyL=h$mrI?gxXsoAjsY#9bp@R8V3j+>!{cnB7F)gGOnc)JVcP{N?83%(3gTHe9A&wl%lt#? zK4(PwiGXs@c+JC=&21{@Kd5H&guhf=7;-pAsg_+@ctgSL=7rm148QO1W9|{#QK6v6 zlQ6gP#MGsfP+D~7u`)gQp zpXTBX)Nn7E^Yg(WmWlk+Uo>Y16d0`$Y~2*~-9pcd(NBB_n?bzIpy*Ss&NIbU{W$(Oak$vyU3Y&*7 zxR>}E9#`X$Oq%oH`1f)iY4#9?$7>%HdKtu>RqRt^?XZ}6Cn1C7f`#v)yki$+nig6f zxb*!+O1=Cyf#SIwJORGj+x#EpI8=Bp(2pq;7IZSKzri}I%bm4`b(6WFlEH$*P9M&2 zE-293VA0RK;>_$1WH~1e|ENHw?s9-g@cn`0S zOpscIOo#Z|dlL7iKiuwk=#l$_Zb5?+YAA(@?veu%VpUze4uHUkQ)4B3Yh=DsrRVmz|G ze6c|6hZ8bd$wm%^p61LF>a%OgWLDiQYo272HtW`nJuhZAJnr22U`8F+d9`yF53Ijl zF+=FeRHm1f-1=u^y0ac8NhFFrIFRsNM~+PD5!HpKs#FwmbC(s=Ci zKZ%Cve|~>B^S(lo;lXs!po_>azL+U$bH7^n$0O>yByQ(7PM)8i4_@8Gle-->-eS6skM(%_27c>;BP_S`FR^Vqcwk5R z4vX~D2WS2lS;$~}o@c=vn-6N%Vo8!Vr#T8AEK6cdcocAOb6&wIXV%=ARu4cchCn_4 z8`++1;he^OYz6@~UwQR6#B4n*IAy`pqrp7t z7vi`5i4nhZNaDeXgNJe|K{Ig=dxYQaTDUJq#^qpAYZCjxjvX?!J&KF?c^=G5_;P`< zYd7Z}^MgmZ7fTtGu=AY!=%Ev?;Z)e%u}t!y&BY#PfueI~#26k-KWxk{U{EN}UXbSU z3$#`uNA{vMXdE-V@ebobadxIx4|{~qzGQY&dhkHTP%ZC6g5+08?>z=HEPOtHIR3p( zI^kWwiGJpmA4^i0=N&w#-d5gFaJuc~^8=Otd3iLCe^>u-xF+;_n;*aJ{~xmh3g-R? z1^za^m?;t}2@hi5^|)RMIrwt_fAtUdGu|r}6Zfb;EM5B}ccFxrr*D^(LcyMpg9&{0hZSea zw=LsSsua-s&rq=ZaCD-x1kc3XLW=BMe+-L%7`yR_R3zu_1SR&{?0Sxki3em4%)G@X zF=1aDqk7u{U*h@Y!AK5^^+;I2EN9)P6Wq$Kk&BGCxwND$89XI&btk3j*>EQjF z@u0~3Ql4GSo#LY5FD#BtFsS(aModWV+ok7i3hMW*ZaVwt{I-ACBf`5aoPU8aQ|%cU z?s>JFdL-TO|X0bKOXePP9QI6!^gUmgp6t^!*Vh8pEn5(jN=uadZ(e_J5A zSwemHtc6R@tBA81O!&<{@Bg2)|2+4b<9ZC(b=(e~n6AO`z3rAkk%52W1ic6yHo>B) zZF6LgunGh|+{RbT&cn-9&y{dSrlYm{;K3=Pcgzna=(9F*v-1}4#mM}>P$YT4_rtN< zHANB<2W|IVG1xu3mZ$dlffFYrES4-;`1Xt8-uZ2}z9ba3Ioo|vNqVQO!OnYV8TWkN z4^{sE&p!Z-j7i88_f+wT{_1jX`d`pv#(8itJI{g2f6w?>-m!hKNNPOac9QY1pfPLH zSIK=XYvgAC|FHUU@HAbYDPfXK8wER8vpOyi-pel1^qG03rpJky|C;*>jGys2aj$q_ zBgU*ePdek2LIR(g(@8hBok#MLm1YJ;cnKvG99VF9kJ-WF8)i1Q=E!aS|4AN{pEme3 ze|F$Hc(G{S8nx$X%+r+~WF$ONGc+sxCGmy5^N-oV(+gf$TnM|Ss_MXJaqvQlmv(k} zOUDI~lAH3YjwL(0_r93A{Ri7lW1a$i$4Z8zG%KMOYoA}**wEv_chN$f?Vy3gx{aI4 z9h3MpxPDkM_iZR*;V$t%a8FZZtDxgKJ{LX*?GhQISiyzi>`b2z*U0$q;xjQ2HjuZ< z?r^nhsgu0TF2cOyedD2g-pKz==}T4!er0ivfAqaA!IycrZz-emOm+$8PM6z_{bqmS zK3w43aI}Q|Mp75gHFiatS8eP+q*raQxWQL!vLm5(F>51pj4ZFvV(W)q$CyeMO(?XU zCvnhr+m*C7>D>R8u6)uvFI>K(Uy;OAop3;AgUi>r>3h8c#8~nxa&-Nx=NKB-nzgAj zPHj>A&}CA<+Z2{MF||o;kNe)3Hu(@4eV(IXR%|{y|L!zXioI;qaVJGz|L}|qFQMp* zE7%;`>>AGe$dWWzu>10-Sq0I&o7ya|TuD5tYy0b@z*>eJqlcahHN`6*9ODwZt&q&h zoqNIX+nvMG|Emw@vS0Xc{B{jb!ou85e43mwMz_8=R6(3l93AoM9@NqrMGb2|kk4*-h%`48R?nutJZ2Mrz5q_b$*)X16M5J@Z>cbA| z=du}({ov!8tI4ix8)CYR?}dfxyyi|T;exX)>^vTO%nsCZRtRtC{34UVE}!rq=0`sB zF23>y77H${UC6F`VKVb)2kwVW6*BIJ?U>R&+-7{}?2;?*maJ6AXWdw6aP0eaQC+{H z^CI#M6RzD*_viFvsNJLRtW%s_c8d9g9;<-%h1TpsvI&pu_Irvg`@Q$M#);;`&U>Bo znm$@fJ>%14cmB)!pvjdN{z}7a)et|nd7+S z7#{bv85k+#Kh{jpb(A=e$dn@!Q2qbFJ&7JRhM9+17=6}B2Fz@pIH^efOGl#oq4c%| zzMS(pHYpS?vSUkUW{53GW+>;BJNW$nf0ae+A8r%OV>%$SQH-6tci!IxkLr29I6R0m zC^*Q<_&(ts^W1|6!pG0za)eU45Qz~ZRgly_Qusy!D2phW6=fXt_+LMZhTIB55nKA*5CWEN7(lr zTY&H0UlJc=DnFPStlm)hg5ls1og3G|OOTs#_nB@m_-?!9u(Blch5!F*d#!ib#C(uD z_uQg3Klxyd;r83P>=(2{*HyQkFWCFQxv65&0-aZ97?VZgq-H<87{ATkEkNw)#iv)} zr&hoEf4(YrwL9Ym--aBSRRZj$>pC_*zEB|{@^5`!Gl%By{4oF34A1+WI5e|@zI|Nw zOl!*K+nJ#cy16{hGR~W}f$_^?;Wa(it7;0Zw(b9VOSf_5!?L}9I<9aw&5(A~kYHwP zKX52u8t>C0<^%utsjg;qte9TUmgF%_d5;_uhb%|d2MNBv9+E*H5**k<9rqgsII~Kv zVL$x;jTDRGj}G=V-7i0?>_2n0@VjG~0LSx=TyAGY{m1Wo)Vj`vx;sl~$mfBE@M6U7 zNF*#wco1WDLgI7&4S~jB_pR@orJQ5lWL@i-^J1IfSxtW74T+cg%OxZZI^0f`S$Mv9 z!i3X@lDpXcR36L-KGb%I`FnHQx$0^A7aVSk*vMOu#`3|c^Ao#)&mW%uI(q6gvK)Kw zftDTLXReUF5W#Xru8P6XnZ00{wCKkU3zaXc99FQqbL3Y(fRd`d~_i>rbUu4iXT zZ!`P+;ljb=vjk-PZ=9Hte&EdP!}^@ntdNm4^#_ld%=k1^B%Shkx3(Ub-Ix%N6H~c> zV}=ELZ;ct}q&ntb!UjhZj;Mj#gg>MoJaJWYV}JJl>uh$OV>L<-=7I)>4Q|`rZ!4d7 z`%kpUhbx?$Z_ZD6wIlGrl>?Rk4qlL{y&&_uP5=DNpu3JZUWXbIoHUyMtm7H;F=WRU;LwU70jc&DKM6Gi5%3dvyQ|IB(D3{_m7 z*zm9`hZXK-yw5R-jsM`f4-R_S_f{}p{%|P4+5fBk_N7YKbV9>c?)UULs@p7WAhMv3 z5475upP7mO?~morS{fC+SQ$$`nuI?5wbYAcLvr#{*L#!uwm<(aUl7mV;b=JTPxFDZ zj{+u(-cMSYDaerh=AB~tAH!|;yYJ|Tzss+FC%+>ic_GuwYR8A`c@h@<-n32OI9r4N zyqXE}+y8$%n4oVN>J%nnd*{NT%68vz9@Y&|e4(ylMuQ*3;d&c6p!JoNJMd!ltMPAVLUMF^9)ckRPByTj_O_B%|Db5Y-q~AAmdSeyKw4;QgzP^l|2QP zJk9}X$JC|SBMhbNn42XuA0+33M%^ARoFb&mu591uZh6aLS>Thf zfn6r!+z-&GnECwg%bMi)7Cn&JpnWoUU7v(U_OIH+mC79jIl_u_#ic|HXILq4{m|j6 z(mwF6;iEruj_ifgi`w|ygbmKf^aLF|tPVCN?6$&(+w3~V?1DyOdHJ`wNZa8dycFafqk=&JmqywvBl#*F%>GJnL#n(%|u6IO@o~>jT%0$}^3b$&U{| zKIp-^v?0KNjX8iXgoo|(;VU0r*syRuP zu&Fuc)N~Q1FM_Q4&hOVeV+crUs(r@IuxLf{*`1vc&K&-{XZDyfRe;Ju??>;}`!Z#- z%Uv=5)hT6ADE4|s8lU=sM^jJKm@ri@lTXl}&n{9TY$}ph(P76t?|a)pJ3h^b*2`yP z4Ac`I&hTE5$W$YtQhn9w;E@A+cmn*>4*AB22uU2Y-TnYHUlo3v)5fqkC&2`?bLKvC zZiy^AONAI?=NSD8`oEj&&|Ck*-ETW(A+VS{}1j&{;ptRLzP|D6Fx!JMNn!P0P z^1X+IU2`6cfy%Sv9ebCoT= zI3xY=UqP+MiWAm%E#o}e(s5ydn3{IX95c>^T@T%qGR}QHc(Bv?hs4@#ock7uJYnv-Md^49@v@iXp$PA_~J$Vy#Jd1UMP3WU!+i=SIf@%PU4{X{|P4h&TZZ& z;q$L5ahqhz`Z?@EpVz0_iW|{Nxzv$Jodw)6En4%tD*kIUHy8YlSL2<@&C9&P5 zn;vF93fQ=w=N_aZ^!wfG4K_dPZ5=!AXUp@e&9DC5e&F0HX5|Om-`V#CUHo8H?Mf+Sz#WdqJByn}MI%52@(%oBzvXq*-ph;p6&YZ^E!chI=2| z4GZ6+4;}@j1@M^|SS$S9!1$ZXaN_FdX6duPtLMr4d(3t*3O!W(bJ2&ZYvLBgtut2m zANb;ovE}POhE0jv4_rLh6kg%gpq?Y6_Tl*FIw^UkZCVxb*Z=?Lb(mH6u)`vFLYs^e zACG^5`42wfeax+KZQ0EY1@qfv*bCCi53}5`=w{0P7$p(q@ZkdI<};s@8O_BwS>*~& z%l7a#<$M+?D0gx*Vad2)%X<8$yPW1xsl9LoqtFCz_}k&bCTD+UKh+b zWl>GQ?JJW$d=Gi_F4I}=?T_T#o!xhSY`7I?H=WHOAopezH-B+XMv9&3dH#*8+t+YE z+z{7R-%w#I!;rM+P`vma&`7Al`5o+gPZ)A#{}N`CP`_bo{{P9_t30{e4Gyz>W;{Oo zLE<;&e)9vzZr93jm+uyM_#;PniA9ndXphPrUf;xmupd|Ff4edNp++*x>-?s}ZweNC zy7Mq`n&nNNggLn%x7@od^EKM)d2Wiphhv=6?lVUpu+UE0=lfD1QKO}~(bhn^%KXwS z$(A`&rIhD?vAufm#Gy6(jtr6t>lgM#*Hq}X8Tf4bA$h+#|HFOO#y>d*CLPas!c@$j zUnq1kIMaWa_d&tT{h+>Y8|S*(eRdC@fKthuEWK-+JtrAtc<`kjRB}Adl+k?aR#IGs z_C?_~4fWaSulBu30BsIhk^KI>ob=wy)pt8e46>89I$5N8w-hOyJe>GpMPd7k2{HCU zE;Cd(ncw$cywBpqor9_CZ(DFKQG5+%%RS~aQIbR9B7`{{kL$p;{*HS z>t19+id+w&~0q z2N}coH=9>|6=U=I|I*-8w?E^CYdi-G#K$e&2ie(33BdvtsVjJvp5HG8~!DjjQjS5x@80AX77F z-QPbx7537%Q*w?5#9FQqU&mc=kg2}8&)`h_xmL+3(dT(Cp0wh+keG0fnWeEugm>4% z&U>8kZEG5247p~%edwhyaoq+BjU9>QW22>-0hDytkkQ17bIgNW~+ z6pLF7az3ZL#8{t;29<~_&PX_De)zUQ;Xl1oC(k!IWV2jj7d9w&Hnf+R#60&{d6VXc zbDYz-1v)nr>2bH#_DlZB z6a0@J>|*RRc9U%GFEG5Ee>i{3lA9~O@ku2{v$G}oFBecx2>I~GT)j+6;`X^5_UFzL z>T)%_8%i1PihL;dvMSr@+ru#<%~112Z~*Qdhl`h4Dw~7Hh>8 zE`}m?o13vbQXB8fGwyJ+7iyf%Ge^Rqzc~NEtw&xPOeSu-@L@%e#CA#VzqwJid##Vy z1lchz-L|IUxs2?CHAw8a4By_Po%$ zIn5wSRI0#+g+1YefOHdwfntl^Hb$p_>E6#b)V^P>zsRI-V$4R5b@cdyM zxUDY3Lr=&~H798K_mH-P5Aqk9wSWB5l;;d`joXsKxF~jBX7Qs~y~A32;%a#BzmHq` zhFvkHtM26uZid1SS(g>18*b|^co1^MUl=<}pupDVL$S;XhXXcD{S`a=h%@`%8_8xe z7B{L28*cGgOFY_s%~HDVuHX*Ky(7p#y#l`?rYhadKvG>kE96(IL8M zdDnT@{)%K)=DbzM{5sY-Sgh&rbNg^Z{jfo-!NTUIW&F1pWCL!q&uicbZai0-*pbF( zdHzT4g@}glrLCWr$~ffBf8E^athe8x|FAL7#DIu4{e-Xe|GVxk*eKqzE@MW+1n~tM zcn&Nu>$$L+hw*rU#qtTpd{eIhj$3yMcHxyiKZd%!PYeMA@ zhI3n2Sj@d{5Fx~L;Cox`QG1yQ=FO%HeK>9$F=Bbfw{U`Q)BM`QZ>89#I+l7@MVuAe z+pu&!&w;t@%l`kF*%BdRXcpk}L;AoY8@^>L|M0~uW7S{qMA;;zPUIq zR660dPvZ9b!x3sX5<2c~6bL$OqSnQ#_fgW}0Q=+*<_8mkxWDn+|Nm+ILWeQQL%o(= zr0M;QWVVId>Ms|wYSqA-uig!8Y?VcsU++yr8<4uC4u*}9yA~^|Gtp{Sb zrt~mYNJ>~-u&i=9w)RI7Q|gAPAE&q|Ono>(*x_NLro-BXUtW8n;*Re>aGPDZn(_Gt zK6b$kRr&vq)=AxFU;6*=8PF1?|GXPYIA_@W|Nm(Fg@UAxcAo3fA9-3??n$iuR(}|@ z=bktBLe>5M_YS2QxLykI`8uPeQJL|&h1rFs#|{NYE_naqv-`y(QjzEQeE)yW2n)^Z z<{gGF{0`lhPoC<@*TTECuaJZ1!Tc26xvMsI6lGiwC|npl=P38acihK04hAk~l5qN9 zC;s1}M#7uneZh}3iGSx0&31fH!T-r+=Ays~kqR3Y_SCl*v_4eue|TwNz!vzi;!l03 z*6hss58qpM)}J(eQ28K7Z0eu$mn_!BmKI36KRWb3BSGEmhqm^rrlu_s4>P30Ls_OB zi^!Ea(k`-+@z?^3<|B>sUCX7GKg@2pq3zf`xld{LipC2KH9U+9N;m4--^k8r>}ENw zb~dr?WYO&R{t<1H*KV)io^W8VuP@U>ms9K}C!~4SEP3jbBcmA}A<=T^Y3hkeU*>+v zT!SEqZL8*reAvRf>PF1EEqrDLr*l2{IK?g|Wo%r0;J%K;#E%E~6@wnW4`lA$+3)-y zZ^wyp8|s6gIwM?hpoG03s%T6u}!Gp5I*?8{ydvpXPi*? z|7|8aA5?JI9(lP+%5k5pWK@RU+WTS@8KuV{FUL zbJY@a_nze`{4OA0$vf$~m4L*{=dWfQUU-5pCFgp~&Vs@Taf^yGEG{POx$Shr{GvxP zD|gk3j00aTFz#n=W1M*W6wALC4mlzsGEE^Fat9MU_|_%7;IleZwQ!q}3Tvv2X>x&2M^`6B!;P)eXj`CosiZdrv6o+thu8h_*kcaFw@7g z3)|U!itpL>Rh&!iT<*u`rq2~BBk9ic^}SFK*JajTwhf&Rmk8f&ZauK~z=PF|z59M> zIK&h_?BDk6E89UU{@ee5$B6egP2&^q=~%+Mq2L(H8o7B4MrC|FhkTudrXvFESnXl!HVH6w7nH!dZ3p?f8%x8bNq3%&&VZ>Qrz3k!wP6-R)AJPdgyfhPM_#Zql zyBV}V>L0i(m2%+0+#be5)BczwHdyp086;X4N}RpdT3~R;m|c!Xt#PwfxO^{}TJjWaCLst;>()-9C&a0oQgHL2Bq zzwpNX>edC@**5r@C_IuAHU7i9K~B(k_8v#Z+825@X2-ba-C^f#JTSlim;b~0-~at% zOYkp|$#0l(n4wVq<@JJ7_iuRpJ)F4hKI41-Zr0y-b22n~nK^{N$bA2--IF13V7{A{ z$~BEIB}=-ZMSS~ta<^+p9#pW9eIS`4vE14GNt0aR`~^XBEos^fic!kUY2WmIt((p9 z@^x$s+keg{I)x|B6uQs((eof`LEFl9&DAn`^9sJm^D)eLu*^V2bh=j8*=9}#IUW`N ztLaS==6mbdAKkMP_^-2#t!l-eDIcUcl`pg`y4rd~S?SYL*$5fVCX<&oH`e3{9AdZH zcu?p=GLu(>4sVa}6Vde>Uc4!@dLHJ)_d@@?(Z!4Ze?D5qaF>t&c8-qbQvS7v`2&{kZ*!jy%z{LWM7hF$zj z%;wi@bme~U_^{Od$YFy-1<3$swu|4V7p)J~yHSzIKJUBby$Od{1ukwo@i6pa<-6NU z^(-BGL?XXAez7oaYHaxYcAeiT&}_4G?ir)RnHtN#gx=rqjJegZ_x;`tci#lv5?Yv$ z@}ya*h3Ub_fbKb)=`*%|Ej0a|1WS+=#)VFhwksWiRae)kHfAxz_(}Qy@PV;=Yc*gJ?Z^F!^ z2XUqo1V0oRE@!SxN%~lERATNU3#kXe9cIdh=J1^V;)4m3@3b)_to^;|23nTkp=7|mmW`23kE?ANIzH^54f_Dqb+qCoNeNSQ) zvpu8q;D$Qmg*z`?Cp33Dtrg@xc>KRF%O5u<3u8@|$9zGTOg3J)!^(K@aI*NW<7+A^ z-zT@nJtpEp0K&*Bkqk}&vD zWi20k^wq%z%@BQc=0p)^A?phQRC~theWK8=uFUb+KJ$$tynN|4i zL?Iqg%lAnKA8dTY%gJ%>NypIo;LioD|0E9Dfu^*pLevcpZ9A#+;LAPxiocI^9=9xIdB<~LuHE^6%?r&Q z9g?WsqIqbV5|g#7%fXx5jgB+VR8r(sn4Q<$>E>w6&g1FH`Qw#<#6gpL4-yT^U5)N9 zNn+i2ll8;j z`rXDIP^c-)ULf<0PkGhLsv9@(znZ;&$J9rgEj2SC07~w~7?xJ&-=TD|xZw zxqZxE53uceC1Fwi-RF+xEP)DReTEn8NA^3+@vvijaF9ce|G!D&1jDE53>eIO7KI>7AOBoc7LDlW8$XzCgWIM5NT$CI!) zcNd%4?eDBR7JRtFvYgwpPn2h}MTCFBhqd~G<$*i_+{al%w!W`!me7!Xv$$OGT)~=~ z*IU2a7&f*34Kdty=N4zgLqE>s!pTS551;2rSdjnfO+hj%TYb2V*}I-hr<4N|tr<$# z4fLwTN+q_GUMTczXEX3Od$r*iQ`QN!dCtk5cP@W?B*puH+e)jN(|cO+oueg(I!(mS z^FAmz^7=t4TPn*NwS@oj|9>RzGY~d^xWT8@n(arBzGA|h5BaTj4R6bZli9u`y)n6! zG?$yXMn)tlaH4~2r<;OJz=2Bkwg#Uz#jeNkM-rYeJno(QAnDyL;d_uu;zy3K(~k{& z;`0(GDHML=)3m>T;P~x2a2sN0KTpGK#>0jae18P-IbICDBe->r7}KYwh#QTsS(kG& z2lKE#JEZfAPeU#36kAf>I>iHB?ioSPG;cK=X8A6)Jv2?>F{i+XW1Rm!Ypk&c1zg;l zb(feE78HgCH$5mk87i{R_+YZbvD-zUl{v;c<a;lfoN3by zy|vB{azhrmZO%NHVIdN>K$5$&HTnImo(nV9D?V?%aqGdum^GIf@@%*qq7@D(N;hn5 zb_?+}I+W<4S|KCabLH0uvoDvs^amq#k2bpk<`Qob1(OZpEayom1a3a_yCku{Ai3Id zx4<_x1&!HuH)YI=-tYVE=p<*GS-o~$?6>m0yX9^RNpgFh7oFD_ean(zZ^5S+G`?vi7 z4bSJUawu;4EtzdoVIw@D9OPsFP{F|qx^ITP;ol!G_J;pFiu?yX7$1edka?hS zdQ*h`_v+Vsb{w@@C(qu{{6~(7O#rmN`ayzb7|#mNzb8d2JUFWN3T@M5Dr{bGYJm;= zw+9C#*7^VNoa_HE!@Q9}z`OhSrRo1FqZJ$28Y&!q7VQarc(Gv_+XuZ`M+*fOgRB@; z!R7-Fn|R{*8UMvDI2(AGOS7SZL)-m9lS-#a$&xf4RZfLwbp{RQ8pczOy^R|d*s@sN zntJjqU$nO$j}RyC=7eY0yV;u;9q{6FzM7I)JNdK)?_>|g>)|(QLT2!JIB4sgR$@N- z)JE@+&*R=}C3ASEW>nfZvd-aDVZC;tK)vgPnDpg`tJcZAiV`Ww&{%cB{J!@D_13%Q zu9}WoA3D?L@8Lb>*K@DO=SRlwmW=c6D%>-ENcXT#DpY!&@?}oIrul**M+1zCn-vbR zD)=tmq$9m2;_$p(a^Jh}=~wK1o7XlW@J)}_}79(EesC}PRyJg$zUn`$FM2=`w^QZdM-}V zEGHK>o=>n4w*2mRWm1874R7si$>xO)E7usYb46G$v^iWOQ_kGwSUW8u#en0c=7OT5 zO6z%>3NEZ|%Hwf7akNHhgUPm&TpD~4vvpduzDiZ!ldSM~@_cvnF+n}n7fl`yJ7W_X zbQsT-ZUBwWhMsngJkI&(VBNRIJT0Dt`R_xyG6V`dg}A3oKX5YtkHic)Ce{jm#y=HK zYz{`+_A~j6&9Uf0%md^ECdc(?9Hz=Stkbf3Qhr)q<`E75wjy^fPDH zgg#dIAkZ+q`9R$hrbkf@;W`^tr2{)Q@k#(z=s^&V94zdgjhN2UMK+Li?$1ZJ;h zZ}?jx{poXE&mNHO3J&{&Q<)FcedA~RS7Go;{DMWCzzZ4XY9-TrHV#Jy&=JEeYa@(Z ze>}*a-po+oJWuejf*F?sKbu@9Q*iu@Gru#sRtgj|T-2S=CUCm!`(2(m9*2O0zflgM zeYgLuWHM=Gn>G8>Ej3=D&U(3zK7k!qnEN;kVmqxCS9>0~$?{;Wo=owCjd_KF5039-P`WWybI5h z1U(CE_s_^*$9aLz#D3}aPRIq18#zlH6DB@}6%!a-edJf|4TR zu}P7el{-=%w{&+;(^i)BTfgOjw8nv{Zyfl9rytwfFxOV?V%zNpE5ZyaUi&xhc+;>i zY&jdJGLx`Xa}}SO&I%Fv_fCfv#N1xTl_19;*45Y-VBf}lda3;CKzEk|ALJiSXV#Lp zjA^;__n^dV?)`z~D;|Mwn(q@N*Lck6==06uwlU$l#&L}+mzEjR_o%kHC zfC4L?7(2F*6_N+JABAsdn1A@dsrgJAB04_`7p98KZE;G`O)W@E&w0N^?HZdwkojGy zmmhX$a8$Q0^yg6s;&FMq&Efd$I=$mv0@E$x9vtIRzpap5x_{d;+gt5BQyewSxD-41 zUkSQ#%P=XXTt-g}YUx&31DwL^Kad>oBc68C-| zf5&zGf@gIzXpMb@&8f-@2hJQ8C|EtQ`28I-X`X~R=RaO>0PQ30>-K4$qujrIfx(kC z;iZLPVK+6bKF*fViEG?h-HJ*^yLjV;u{V>{BC({qK+&x zOB?%wLqhpab>_J=C3vX#@jm<=nwg>8%+l4&xbUCCiU3JIjh?IQM;dhWoA0t8{eOqI z$Gzc$faPZQRdw5UwOlyRGsA|5XH}y=*R-kGM;wEDj7?oXpWZO5W8Z~Y51bM>c*9+` zIcBjPoiE2U)7W#b*aQRRAkOIUjvua5SG7%0Xwj~!J{_ZJH=lL#v3qP+7C+5C+qBWW z!D4%$;`@qPQLdSSOrif`f9_4bD!Hi8%WBFLnUWuKeArHIVeB#3F3#iDa+SYpxzeGP zU6bF=ol~j!$vIKdt9$3+HnVl>N;DgHFgYYDDDtnH^+QAJ(1gTaiynUOY%r17qwqtK zGk$H@T%!sj+5R|@Lkcq##F?wK|4e(#(dqcW{=87*9y=ikJNEA5g%3W+KkRRr5hoe+ z-b(xT5dr=KwGW?M_OAd<1|OEr{lmLxy~xl1|DJu?<+CX6lJM>CY&YMD>D0FFlkoX` z{)%H?!S{uSbKjMm~AcSI!n?mf-F=HR;Ao}!M+{bJKC980pEvk9ml zG~K?sE4lr~!zG|T!VihxzYl|wK2I%ZZDa2~wz^|$o14vlq_f;+JifbJ%1KU9F-TF0vw=3oN!+hLESLKu>sc40c|yU7Bj{so&D4;OZHC#3yKeBtT&za&61mbD}7hxJ}|0lT%V z-?v=s;|cKJ-?nCv!A8I0dmoN*vE2;}ZI{z>OuwfkaH90(vIlWYZ`fKn{`Yfm9_4SF z#B_n%L90rh;iB@b4<|Uo_MWksb6kC$CP%Z~s=eRt2<&4#<$0(jXaN!^5&bhQFJ^Bi-1yb%rwIRE7+LABqh1SN{C4Vc}HxV4%{(pe7#lKA3rX zt0HUj0f+Jj6&(BrnNLsSW^81PFqj}9Dqi!vWvj1$)1MszQ<;SW>^%?M(B8LNWG&;7 zhz*}Y)O{T+K7KhEYsZ|h_PN~k3kCZBekEN0B*fh0*nG5ABZohc!;4|z&!SzcKYviO z;bD~HIcA{TAjaVoFdcN>PNPVT>ZR8kTD;^r3+nl756CiFH{B>>YmbSvpVDp8o&36? zO=A0WjdV^{JEau|4=OSL*T2~Lb*6vM!Nl{NakZy|K0f?CS5rQEj@|XU9pc4D9ZS#i z99Y861AqNZZ=Uin7_`;i|<9)FFp+?W4nU~cC4~- zJP+#XUg6a@C}*uP=8-L&$bMnshu23Y`W4^G?hI7=bTRpGfQCbbMUqzj!WsPRw#_Y9 zUBblQuwKw_JnXI*_n}xNaa)UKs;a@oXMAql_cKzQA2zZ4mSAq{)8kXP)n;@11!y<3 z+3hJN&kn0Lh4FhcNWYW#oPXO{M(Uu|uN@W_^a?D*_#Zqt)7-c>fJ?%{?<{lcqiuYP z72|h)uXgcXpgd`tY?sEu7dK`~GbsxsM(9g9yC!!3J|d^fQ;{Rw@b3fThoT1-p^Zlw zW}p9%m8`IfDfn>0oEO$DHAd_#f2KG5t^fZxW%&<@&-qup=PC5Xh|XBB^&O9bzp&Y> zHetow-_Cv&YZI66F-mQH7%pmSaFpeD?$;O%j}-@g&(l%&KFlGa@Wi8S?XHFGHy2I5 zeM91N{$aE3d1|Xgs<;%5y<9hMNHV*7tLDUuC`Sgn^A%QR+iFgWWAwSTFRY-WgHRc481 z+4!$+Wn1lMM}{5VT|anI-xl04xV`SO#u-6B4v`&aL#LlB_#3oTYn_Bzq~oc|(s_@2 zgT5`yp68Lw>YRHTG?IVe%+UxLw`21gCwDGi(dKu55%2O3TC9(+RW>Fayu4v%qMB@M zkA+9)apAekuQ@j!R#D-vZg(?eWn@3r!6#+);9xnMfDCsV^Y5xmPN$1pcVpil<`Joo zsrAMyrvr3;^kg!iZTWIpmo)XJ18P5;PpZ~EJv`KhxWLw6TluHtB zFWL^;@!8Kg`1b+xgKzc!CuCW1vD=<+;}Aac-+G5M%ZJ^Y_dd8dKjDG=#hHJMT5ROn zEh;kg%52Oy&y|*5lbDzA=l;J9N93yie^}Vuu|s)_=)s~5h1;(&U0=_?t|9f+ErX=# zZ3oTx9(q_@v}X5^JUIL2Gm#t0&Yp8P*Hz>QCw#vDzf01KkH^W4@5Rzfa%x45QI;wX z3NBi&&^s(5Jpb#7tS*5E@fNZAqGwrO-$;@<)F#98VE+56eXAX}Sl$X!vv{$%X^V>C z`TXiOfp2{mlIKV@I%s^+NPpEDFDI zg#P*}Wuu?|CpzS`qx_Dy9gOr-pCThM@9out1AAT9-4Dm*ZiI)U3&Z4*1Zi6S92FltgvW4k~m>=J^v1mIhnEQVQ%)l_T*Tfas`8fb_WyBNjuc;b(TJV#&G-GHHOW}kEEkGS|%u2JUGVr z?B2qDvtJVPGx%6ff0Vg!uHpLAjK`NQupU^kuZNZM()X@LoeKRp$=}uQKl=MHv~#t~ z%RRWE-cS&5@UAMmJ)6eS7#ZV6wT1nA-bvj5eP682_SS)8TynQn3=XV>DXe$+(NwC3^DZZA-}r701-H^yIUmhOMXs^GK!epXT6Iay!LNa49r^?NRJt;+U{9vEEjp4QPho#T{%3Q_JV6!5PvE;pk?KX$QXa3jenVvVi z(GC(g|ID$v*+A3r;7oZZzF4WpLTr2wEJ9bYnf=}+%+k{EXnC7K(6(1>cDFyA;&P~b z|Nn{F4dK5I$L`feIL$jP_8_j!AYlL2g2cX#WLECH6`;kwx!cV(?Cw1{#Padmzr`hc z*tzb!@W?znKmFH@9J}w8FHfr3I#o+KwEHcd{c(e;Y(X;1^ZecgcAV>Y*k#+<4E+AR zYTK3Yj!h)sutA|QyIo@Mwm*ekbLeli-F{`u+CdI2SlPmxgOBW2jSJ$!ihqte^ zc{GpfR`Q?aq0y@wZg|M|zOXFlI^KMLNxE6+s#~UwKbzN1&Cqv_zR&HlT)SyUY3t$l zhrY&zOIqIW@%J@e7!d2c$?Yp565rU-S80%ez|m3R{vgSbB(`W zuNy?(ncP>#E@ilm%c!mIf61)r)uAVN{Nn#>Jdc*NeYiNtsXl<|e-*c&{}RQ%5Yys} zf)ojdmG<+C?(h5BW)Na?lUX|VciZ8lLkD^f_K3WH<^b9ft9GLB`>QBp$u(E@7;gW1 z@7Q7S4aXS1m!=sW>=EhT)lt^vtQOU{W5JEKBNh&7VtdTE47=>QwtF(3U_AcAf}K}_ zkM&$r5PRDbg~xhAaUWOD5c=TDldvfFm1Lt+IdfZxOq*@PgP6U}oEKy-HB8+8=)!R} zg8;LyywxRglmCB8z>s6?fa+aK6J9>NB7Hc3QPg+`_P_cKeFt+}*n+to1n0$?xp_ zux7@}cie4p-#JWle&2iO=oi?vIU!k9$LO74!QbUdwi{jFZpqSSpYpsvd5&uEkw(>^ zss8o*A3w+uKfJBup?%*}p{vU5Ob-SBH>zy>5pzb8IZ=msYWvZDj+ztpiWkmV+^r@2 zs^d)i)3Y@pR;r=>+^XHj+tgmnJ+!PfLFL}}P27Ete|oYiK9MQD*e3k*EBl`eMJ;{i zt-*KVCYZ22=U3{Rbo0K77#sim|N9S1XwA-xmOlPYIv#;|GOwi6G3 zzcDlBF$gX_VV9CG-ewSNc2l;T`(4Kt(?>=9nO)4A$`tQGgU9hP@q zTOT-f`?5!}+#FpI6A=Yrmf3TjwjE14)O_dSgFW2GdDr+>F5e)%L)&Cm?K|#m-?=%R z-&ci&o;%jFQlg%>YDRJQzReQMlkVScZ8Ur@QLuE4V*eKIw^kwt9r%|XWDWSj)c8Ol zmF?FWh6&v44UH@kb*das4oC=Gl^1eZ-ne1K*|?qxZ6ltQ7EdY`UHzlyBI*^UAI8qh z+pHC|GVVd=!db`Nj~{icShV#Fo5KEmyGtEpSp6%Km{vZ1d%^J8{niEX4(u(AIu(p1 zKT_1Wnhu5PPLeM(T*h**D(S$T4VUDZA1OIMoVq5w#^64?l0<7>dc}leT+?n(Tc=gA z&G4Phi5!t9t+FCU4H1z}<%};Am_-fhG8iLeL}Xql7)IyFaPxKj-Q`&EaQl9qgeC7o zgyO#MlTZjUCF0D&GMnJ;T)G4XYZU9;#qMI_U0E0+~DK6BU3tsxy{3WL&3@S zO&6}W-dMgT(O~(`^L#sM>>i)XWS*yW@55o1*AmRF`mZ!w9cNl!ytVskH=ASP#vL=? z#rCLIB(pq!A8_pU`a~a|7VUn^cVbs|ge~Ek^I%J~;_rK{O~ox@+{bO-6inHe$b0DU z+Tu$u*L<7ECGey2UE3P5lQX;%w`+1r9B$ZK-SqdvF|M@R3j#SUBm>OV(97zHcLIO*%d;Xp7x- z_B%&?i`L|K8kp(^#F=Fov;;!$!urS)Y z_|By}8WJypcPzNX#dh#u7`yaKxpj|k*PaL6ffBS_NL{U&Pe!s~d!O)A?3^?B+1XNj8TA{>^)7u{uZSCF0 z>U;j#``xcD|KSmEY-!Yy@RVoHESUUJ+wN+_8|K4Doq|?=eAW1AebliPMayW(z zT31*uSA3p)`QGQ;E*X>O(asW@^K$xkzKO88yqay+$Io%ntm=$+xeDLZHhf$gaOrb- z{lbXv{c}DXVikOLH~f~=bsMwaj!!Mm8-A?5we!%0>Z9+=Ob_Q3d{k_oVIe&G+ob^g zSZ*Ex^%?fl|GzQfl3TRJ@_kr?;0F=Kp#R-+50jhucyzvfJ-+c>j%~$v-G{aBxtspJ z=Si6R_e0>$^KCY_zaNpP`)>JqN8aytU&$WlsjL4@En+NihNU7cijkQcMuS0|5Ww* z^xyJH+fp=lh#!1lfAEKa1Bcge55HHdR{Z?FOV@-i?*H4Q?7*gDpb;tHe%U-#=iH8pJ6tCJ4 zak*z>f5pahi7vhW2ncNU2O`VQ5h8O#QC3H0;}Bem2k*C(l~=88QqDCaG#? zwRugQWy4|+;lt1RKWhIA!)^5+d+l`QooP%;kXU6H`oM7gjW?2#`QeF`hxVRwTk*3Yuf=TY(@k3WOD!K9d~vMs?e-lXTR0ZWJ?9qtzFXv$z_)i5 zn}WWmEQotC)yBf6A@`kFvdlzotM3K}-{qL4Du~M2zAN}Wi#x28NBmsnLD%)|M`RMx zo|`P$doc0c7oEn2J&}CHJKAPc-&MDJB=gE)*F7Ek>J8VEhbQ34iNyKVH4iqX#P9u^%{e;Y6aoL9#*b zVPyl|oH=6aBz{%M_y6B?t3lrU|8|W)g))Z(?+@|~zyJSTp==@{{5)*IZ~4Ei5+SFm z_xm+<=dAjt#Jo?p#!lp>1>=FEpPhvEDCx^xFbLCS_|MP%CvMg6TO9F6+gEWsH7VhE zYSw>8TQ<{SrSd{a|G}fp#2~h& zDu(ru0=JdO!8WZ6{(2Yu<*z!w$$23Y>JnalIJOf#Xaw z*BaQ*pBg&VwCrg{;`^)4FZb_Q{_lIk+Mmnic^o{?~Ay zD_b{mxvf*0?farz53P^R`o1IA&*C`ix4rLo)ar3PKCGa@)+3`{JMp>Q?e|6Z4&?UL zM8A)CZYg=PLZ8WS@x+G}0S|NAGWic3SYh;W>s*V@=@}K;83&q@*y=8vG4eR_!&>w} zLgY3c52bBUJK`DBl&`ks`Nk^DG2Fi3*plbZZLE$RJ?OK9g(1Ji@MqDg6<(or@pB%? zNHsGtm``;LXMYsGPr&=poFMC07dIa`P*caAb=6pGi-!tx#uT;}CiCUbIsOT;?%XnC zXUvE1?u+Gr-F}el=zCJAZk1N~|KAlgBFUGEek|}&YL@z<%yiecQ9aQ;xKRABH_v56t$Q6@PpPrJ&eENPq#d{|G~_AL0b$;Dxm_OlK02TEq~H491? zJ~_zE{jTvs#rnU81PnIp*cqBq$HTROk4;SLc&ouN*%^$9{0-?Rt~Mk(H?r`rU}H59 z;Ei=@u`2uCi4GbY-HKjZ2E&WRgA@gXMvpfe=C;udu%d0r2jQCNQgZC zP%(q);OG56|1);}Ep2Bt$Yt{Qp{TV-Uq8T)pYfl?6amHu3YH-}Y^RURUpBMhFhd3Z z=k$Y3ENp@dCK4PDi5WKRUl+gPXJp)eo9*W6RZSO~jhG)D;1gKaEYxb?Y9!vtdW+p| zz3>V)F)daWUxz7TjQ^)sh-_NiaOgq{5BrhMTXC_B6A$J*S#V52cF98@&3{jmFGz~F zw!Ug<{8;~?&Q9;QrS~2keIfS)RgIh8ct6Z6U$p-Qd;7!bH;+%(Ncj=0Uf*>)kfC7% ze<$myeQ@5`>1Wqy2s-~Av*-Ab>iC2kw8fB#bYxvP)i zW?I-^^%!q2)yGi^8ZQ0QH%hpielGfA>E_#V%L*l)G4nUJAGoLAAnjnHusS&6l~du* z`l)3HWtdzRJ+%+d&0;gywNh@W<(z`ZDz^4>JKGi>DwugZ-mleQZq}+5GctGtm?S1L z96vC5t9RoA1#^ZASv+fYNVqYaS|cftW*6rCg*m`Xpk?CY5D6Fk1@8kACM2CKw_2#Q zA;Im!Bs-op{13|5O>T&BA3gBF{`xjnhX-~c43F=3t?1q$uf$O3BXflP&UR+K^K@UP1OhGzH~3Bvd!4 z<}ih)yC0NrXh!$5(d zf}NRvs<`-{UHul~oX)RQj@D1Vd8p{q4^@7J_Z~vaRqae3K3JB;_thfx@o|{~t$EG9 zjR}b}k8|AXYYUNha!XE^}H0ddMIwEqx$ipR>1d$ zfZ&w8SKR;SSv^;K`FU3jn@-7#rYxD~9NEr?jS@}@-Q@i+_tZkh*=<7lQ_@Ntx3)X0 zb2(=g_gYEZT`wnRcy0>!iWlDu&q)h>+n9ay)^itcRf7PHsZno}Fq6J84sU*z|`Qm*biFjS?w_iwfTNTIg8w zSU$SW)1vmD-}ar?wvQ=G_N2S*7gKgi)ZEVF+q6YTRv;jLuKZr1^$teM*m4pVSeG08 zsqSOdT`!2t(CV}>p0$*45J@R1@ew&FZ} z7`4`3JIlg<@Y9v#XN@i9FKRTo5^Mz+7hH@mm?ofM?y`U{Y+nD{#Re7pFaPi}{(WI8 z#FF%&@l9le!5Zd4djEx}^j}S7G5Tfw^?==at+>MvSp+Um zZ+`Osn=0dzds3_h3masM_^+feKOo_1* z-1~#&_3497svF|sT8uj#Qg<9v5N$P%Pxw>o62X$NMd74q$ALpHVi*rUb;$H*Y}kKv z=?DH*8G9oP1bIG9{vnp=bFh*B=+iR{7ZRG^ul~`q%AScOG^vY!>i-*#EQYE9J@E;` zqBnS4-wC%`l)pOIK3}kXN@gfCr;~#-tJ1p0RHySlc6fwbu!;Y#ASQ5CdtSz#ear%X zxQ_C^`p12WYHCG6&-KL%zjV0T)V%2RF!}5_xy@Di zdH?*1i@F={itn`M>~mh{+hewKMahjLUb6fQ!8cXgnLcW#KR&GJxT3fv)JTryVnxbz zeh$xdrN;FC|!8$F{63?S2nYaRua6$?lOjX1*{gD#p{|X zYESmGd96RWsQIIF(=JI_gPzw%bu%xob8F-3mnqv}+A5}Y;827ui<3ifsfiCYT|(rT(g%r|0=t@Jmdk!Vaapz}D)Mf|qs(u5irs7>GR~hLy6!oA@590m50wua zw#>A+cv$-4;k@=c3)fhclqJhObWWS2q{{cfVEc#9Q@vtM51DUx@9Eh0t1XY~?E!z2 z=lr#Yjq@1K70Dpt3=9kmjN2wAc=EHk>85hEetTKG_a8R$KA(JrDx*8nX*`+Pv+6`CE^;3Se@7uF1~1*&br{^hNJK0+6yBD z=byUjG-p;*_VEQ<3k_N_GCn7WmK69{s&jfCP&rU=o9$h}g>r!sK1TOL&PBxw*2ccz z>2+EyYU{|#(B<%H!&L!R#gD>AQ~g$UG!!3EJs6RFJh|nd$BUyEOJ-iqJQ2smU}UkP zgwHZ2PhEojXj9P>6~Wd-O@~TO_X8qKT+^0`sY=wAZEPxOW+-8M!N2Hn`$2;(dXFAV zec;W?c=tgIYg>T^W2IkTlZ1_B?TfvZ+ci5hdCus~e`K)rabmN~uH&vrlNT#GpL(!o zp+uW-bS4VB0XYiqEjQAK7CQG_{F)3U0rF{ zMg5PP1ZN*(IIJAex$WrUML%w&aea&9x|k7RJe$wy(*X^GBO2@n8Xe?xG^>=ZIc+FW z3Q2C_3STIxm14%UIC1h*)+Ox64zE^jU34Kw!$QnCk@ar6#e^hb4!w&L^ ziI~#zIc{8m87rSu7%00u@vjJ#d315(^C^cGC+kWmkCJ^tQZ$a>p$pM zdwZz$r;w?)f8NGk5-=wYIaCn!EFMrhH8;kgZpNjQAeE6Vi@Ee+ovXe8U|H^j49bML>`=I}3>S-i!d#ZIsJ(xb1={}cLFfBvxX!;LAbe*=C< z@G)d4b_TB1+kQ8W!NG}xt9I3@jc?czBP2iS{i*)8A!GHbnb-Lgyq+j?d0vU0fTbvX;GMf~{UPkOx*thWMj+D@o9gG|-2NE94kSlvB)Yu@) z-0T+U&a#+w>7wV{yy^G2SQ4ZX5;C71yu*D-FrndKQ`1Hd56goF_AGoR4IvM^4_2@~ zh;xve)bPFe0hgmbQ{e{pi}SAaaX0M9yGtseqhrm!2dWg`EY|l`g|K9euo$V z&J0z)MyJoqxu-E6O=dVyR^j4yB}$aLo!4U5&Lv7+W;Vz8cv}lxmAH?vFg<)yysGns z&-3PnK2eJjg|31R^B;3r+VHXLYdL7}Xtpr>f$V9mD>*g@9=$T5Mq)lYqr{!AHB%Ox zaLaLu5qpzB~Rg7O-88Uv@uy7=@2sk!zus5Eceo-^P=`>d7&66&r`c@|PArBps&lC{2@*?{`^{Ch&i)VDnEt#zqE-9n9Qo4!wvE{}NB|+vIf$lw*TQ>djS+8P}BJVzZ(!YJovft0iuz#rh@>=A{#`4BX@-H7ZyfbVt zYcYJa`r(fsH7c)@?^lSrA3vqw@M2=gF2)N^VTT-_&$5V9@vqr`_=4%-)CWK6|Ll;z zCgidq!0~(gKmD%It0J`rH;;l1tx)xSU zSsO9I{uY~7;f0rq3x8Hj;E1^H63n${P4zo->0<6IDK3ULLfhsDurvs)K61ddS#?JamQN060?OIdls#9p;W4$n&qUWlx=jnt7y&d|*6<_Hl_ z+7j3^Bke(kk%f3`@1qMF4*g*EnPG8Nbh%D?TcYBQ$vZ!ZeQq*u`k=_@AZgLkcxOTg zE9cxm#>GtnJd#gzA98Rv_OU2Pv+dMiaad5Wxv@rTdi~GKPai+jjF=Yx=+S%4g)o*Pqx-ZP6XyZS7!+)LKk3R&kFj%cEvvK1Q5N+aM zzj#&uWbeX zkYzg2zTnVBDU;RBjB?$Kf8N-$a@OyD%BV1n$5ubgY88j>6CJ_U&OV^3}D zTMGmkJZ#v1EI4(rW&NX>uXY+1$ma%hrN}Y=`q0GtQDx6=@2g6Qho2^&|Leb~|JccY zamuHeEmlr`aD#QBoIA5jJ7WXKL*s^jy%~lT3eDmg`VDtE#2=LL9eAAV_=iK`K$|`D zzqC^>0xoN|2uy8U^jW}zgW-b#Z?m>Ohwt>PNw2FNzV2z8`gGs3#hfMDAeaPZh zWO#IYm)DOgN1EAH1P^cvF?{&GQz73&>M$e2i7-WmjgA2vwoO(FPuUn;be=ezo6zCY z#XVQdMoH1U&q0Sn#6LQzqj!(Hv+gpXbiS=2n8UNr8!$SfGd&$&(H(81Z#zDmuZ z=j4_NF1N|m(b~@J7@5)H$GyCb@xa+f9yWmvM=l=`2t8-r(JXz)@#-PYL!b7{YWcqB zm#M45!(P@47Fk~wG@K~tP;GN;IL`P=bcqE=|AOPp4d-|=7Zr3Q$?>=Ovp?K$guP*l zazKsjiv+FTg5rJ-nRg2akC)m7ibXUMKtcJM*{L$+YX<@@Yru>VtTR5{r>u#fqUbO1bqfBwX{~TfJw0cl4{U(^L`0Uh);;}+AWrbGBb0%+iqGIcy zBFFLg*xZwg9xr(2_c3`A-_+O5RyFd?tj9es3pdN0y3wF{%kbyJKf>G%Hy9V3df{wm zuU}WVzvua3qu=Wb?Axp+O8%S2_JW;7vMV%cd8g~4__fTo95XoV^jOvZ*?tIE{I?~y zr}2#_OW^sV2j(xgl=BmIGD{87_QBC$H|gp=i>vq}d=bpv~3c`CeBZOBaO$ zJ)s2}5@NiE3>y~hYkiz>d`cAasYAz9q}T(E8x?xo%-9`{i|^2oKe+CgmFNo((VdS^ zx&|^H`4XXD@ng=rUV)&fO~<;)01x6&@zS0@ryZ56IcE z$`$V1Ag8lJ~hfiC21ClMh~r_UT;Z(j?eurPnC%hPm}fR)|ML zV?=>rX0P)h^OF$XUtyk_|Afj;>>JphYmL@KhUo}D<#in@s8`Uky+1%Il>yx z+uNE2JL+c(Or0acC%13sqlTchj~R-t$g-}i@Q~3fP-quDdX3ky?Em}%4_3)%3zmF1 z`$p7JK}N(znYG};=YIAFUEjMJ&sSXFv@ww}Wan{oED&>Hbqrrp@aaRqxxMds7!r<8 zayZb$Z+$~bVTskwQ;trIA$|t`T-ciaw>iJRD8qimjY;&^e%odDx z+x7kV*9f(2d@%LCc)!h^RlD!9AO8PFGC+=%_1F59;Su|HHyj8|X%Ee9Scbg!bJsD;lzcyyHT9p?+ZCO0+^4te&KIyS4vgga$KUz? z_VEwJ4I0eMx2!ooK4hr<^!r2LmL-OAmy(w={yDHliZk_)zleiGObpN3IOfvuRTWDl zq8~J=^sA|gH**TVicax;s$&_yCq@34hd^Wdt3v{8O%lIPaj$*x%8{W*j``1pL>1{* zjon9<#=I#ov1Y%^;Ra=)W(KYDS#0z8)a+P$LNqEk zJs*B}&vIZF>mBxzECc4NUIlh@+iF_YN%P2AS$SEA94O>m@FRQ{*So2L*9&AkcIX^( z;E{MSgR77AM9B*!K2EvC%~K~m5|W72xRK@*@}_&moi(}(9y>dhE_lY8Z^DtZeCd=J zIhlfj8)+Pi9lT5o_dlNeu;jUP?*!RMi7kSzdTNFo{_Md^-TpUP==bYhY`Bxc(bV3d zw8AC4|9H8KL4z5ehs=i#wx;VUau#6*6$gaoNH<643bg1pF$9&KSh13qqea1|Tt&e7 zlGVh62h;aHWMO;tk>fCvhOUM4olg%rp0eKMZ2YLz#Q*Z@JXNhU!R8-j0ojk7HtOu+ zOej0~Rd|X!t9+m1H%T@@ng6MHQzxE$iT8xIJw z^uN$;Wzcn)%@k42wnCYUSulGZM?=hkSsi*@{S97X+r{ z1#3Jk4?Wl*%zega!_Eo#dOh)Q(5MH z=y2F;A;`wnq~RmqEuqLVqk?^BQ^RD|+w1}@`~q6(Z443OI}Do=ww^2MI(S5c&q8x& z<1#1CJ@Opo8haKxzR{C?m6-6)AVi44|METsHa#K7Jv{6$ejhjx$CGk~b%Ha)(JTiO zug@|PN7>fxk>~iJz$xG*#JzFnbK5-%pH&imnAz+&dt8eBOVZQ2`vC%=KF}0_h7Z%0 z)H}SIb|Pt`_!J*I7M&mOg%dq>j@p->Vg8g{dcMm|afWTX!4&(Pr}Cjmu5zo+9zJ@u ztyXP$>$GsHk)`vf^g<(O#}an2ZR!=9xMkK=qs)VZiYAo(98~ zwUq|q&Pi8}u{KsXT?vTulH6k=(D-44F{^^@!7Hbm3!dwUUphHQc}=g32*b*TiaMrg z7IPxB{k)#Cu<-{sCt9UBZSZCKk-XTQ`GNP@12d)^WIEJp6X0PdJ3~}#GLK`0tT0Q1 z3ODm~Re>4WJQY@w=lkufSv!90T^-!h{)v^5g}43i|D5AB63k5uHsXI*HLTbp!2Xc^ z=-C@HUO2Nc9Q^V6f&51)W|Mi7o5X^CUJid7xIjbV-`~s!7r1u5sPs7CCo0ac<5i%7 z!YZNARcy>tLw+*|Nm|GsJR#7;-m*iL`C$G1gfA1@`zC%|*E4}TefEnK$>tx&?yo5L zb@#^6hfm|%yQfw!Yrh`yK1f=A4tt_(0DJ%G|E;gsH@LPMO!4}(Ri*hsvRa4;TjK&9 zj)stPEDeWtD6)zeb2y&)vWrPdton$8wuWWg8AndZ6OFwBUpN|~7HwQnyjY#b@?h~1 zfp-tX`#F}&YO0wz%`xC-WK&aYSt!7DK|`oTMnaVJ^$CRz+2@XmoSG61PEJNVfsPW6 ztP8f>QE~Vb-tH_i_2}9Of`Vl=0zIo3KHIM7gVfKT)whiridn}J@FLxn;><)^1B|4Zk6na`aE3q`a=V-W6nDDOPflPTi)5nl-XCcGIN0n}9J?~#VrCdDj z5PPWGJ^L;ZW(Ik-AOV-gf1O;5W}Ox7-?RRr(|VtY?G^l$VJpn|85wuTZ%~{kUsK1v zyQ;=}qK^_wqwjO32Wlce3{Nl`?GbNSBKq}~`%{q%2@M_(#m- zi$u+|RR#hd65q@0udr{9+5ayxd;av@A` z@QXCM@6|GLIv&o)TQGsOxQ)fU#X-mTVqsS^TlFPjR)Hg|3)APMwYws)Ag6g8mZ)?l}q-)XIF_G-(U}f@eohw=UugJg&;MoI}FYOHPop zjltuchb||JgC0lImo%HFep6Vw=1gj8nIhUE5Thp98jzqQ+?LOwzDJ3NBVUJ&g|8|h zViMDmrXKp=cTMxTxcK6CJ*V!INfjH0<89;r78O9bT@z zFIH3}uwD^g7?8x4Z@?i^so=yeGC$$K*~XH#_DK;hk53JfxnbyYv%Q~1aiWEx#KMOO zg5`2N&8r*FaWYIjwBVhHb;=fH5!S-P{xUB2zVmap^>v6nn027?^1%a1O`q0uG98{S zXb`vL&odv{JSS*=(kmK==78ZupR~EG#6j5k!5SS<65F=9I$T-=? zfWe|)f}x)E)Kiv#?;1`9?-CA)@$rfXoWHEp_&nG}!9wIi0@KHnF-DEO4O<1Q9V)oo z=bH&R?6LWgCg8BA;EY1U0rytHw(3J1duj?Q)*L|%_#iH=O!dDN46at(ZD^_vO32B<*p}&OZAqShn-XkgV zoBbI8i~0v#%Nv)7x4Fx4Hto5tUDV$6AdGo2g9f*VD8rL}4}}}L zB@?u{mI$#c2?aDI+c+|{v)_|&xR|V%JgL!;?&F>_!HYxVib~UivhOVhF-p&ua2@AnQ03Tr@PLeaTbdx}d#)qt zdruYY2r<-aR4Dj9QQ+QWeFtZ~B3?UtvSx+9)*s~%ERtZQp-?Gce$79!3x(J6U{NYh6~O#}Uew$|mgk2t-W z=5sbID1Og)ywT!eoosby65sbd3XKJN6;28|g%-Md-*X+?`A)p?(cI1eraLlb8HZ0e zOCNCwT7Bu=!i9p35eqDQ85eD8N}Qo4W4~xZVWigTsm=~d*ZFX7+04=)E)lXY;DRY< z4?~4Z!=4W-MD!Y_R(-HQLfR+Rx~@Qqc^bz8!Rw0( z3REQeT_pvK=QAE$z;dI!{S5O5KK8|p^L51}U!Qhc@Pc)5;^r?Q6POMz60lKX7iSWj zc`$-6p+j`ZJ4F_z^R5#l_{5u*1SoK5?{LvLu*der3^gH!1zKtzdWjr@EDIL&yU6gd zF*Ld}JG|n{NwbvXUMeHJ*WmjOy%uH1Re@7kmxp<;Jo?T`agT6gjX+;{i!hUWCp*`H zKgMpn9PO-crZG9FG#1YLW>D}zL!qtt9UvLc~H+e5bTg_=U%FG22O z5_}GoB}t!u_&waxsjx=4S-o>EYPtLwQ-bnVy{$S&MSy8 zOOvff8|7v@0RCk*M9kT@s8R;mOWl9s=ocT3Ec<91Lh0asI=HK z^@dLRA(GWNk?~HFLDpuK#mij+eweY83T^wr{%`%gtKnBT&ARr#(wtDqq-Yf)XkSxc zoRGo3AyPw;g|Q)~BS(?ZL20LBVq?H5?x`mdm@~2toY7(QvOPFKoUe|_;ekofzTQyh zyO%Vb1fEqmF_u1RWMvLBS-HYV$wHMWt-8h3ana7ll5-CqtoYue5Tm{Mo)dc>55s{A zQyz)&yEZCcVohgpFez_YAZC2ei^aM6P(kp{_hkYOZc-1XFp5?mUFgbw=X+Cw;JL4? zs!-NA|jo-K3IPk-Xg;DS*gBaVr$xL4sXmT<$EngzELz$I%^EsC@%Q%>xYBX+0 z?)NZoi4c^CkW2^@XlSv%#OWN^^u^(Xt$+dRf)gx_2WKBYpxuxox{4#K;m3sa2ht+E zAAab4q$PPHvqdDHtAj#dRH=|W`(DG4gXu&*4rt)5A}R2?AO2G ziM{w@^4F}7`+cRv|9FP2^51?=Vj+S6cVRVz=p>-w(0bw6nI9Too^oUk? zSUOf5nCuZFxLhB;%vhJVXyIJJ84twn@fl25(8wVs`J!t<6SMU}1xBaqD=Y*L=)74Ylkkr9 zVT}AAFWHmXGJZA8Q%}TissH)P^?^-{((d~~7e6ofSI(j@-uQ}l!J z3EKDKuu72ikF=E$pB=p>I_%xyy?9eXJ=4X5EgP~pR6lrp+W$*CP~q*(@_RoFEezP0 z*c;b3E-;W|xLUGr_0=Du)%OBc-|MaN=VdRAyeG%9AVJIM!2$-|UM2yy14qwsE3v61 zq#fi?R8*=8WD=Zsh{MqNeOX5l7hA!xQVkb(L8mp120a|S4ACvh8}wvfm1}6K@Y+ma zJ@S1Sze_^}M-$`5Ylqnw4lD=|ZgJevqW?l~-ZW8#U4je?ET67WD847euxcJneo1zrM0IUW7i?e2C)$DM*=|}3l>i3;oKO&d6-8w((%9oo&^%K z^xp{d-s@Yi;NZdIM;VoR4Jwpa6}Z_BXe)Q#6XOYpZ*g~QXIWJfRU{B$aboQ=Hjcij z3^QbwpJRWt;!KXSzk_$d4ma1bCjU7T`M6jL=_tUOu=k4>_a*io zC&N9?Oa{7)rPUW%)^u#}VVZF3)sH@AgB^SgubMu7f3DZdH;47>zl9HE1lku_{BdVB zxwM^$z`ZkE_} z?XY25_x$j(M?4y$wkKH*m`wQUA=zedtRqB8#34bv`k)5a%=a7*D$W--35YTN?qNI} z-Xy`jzQBNC>%0yLBZaiLElmOn=}irKGJFP#3Kz`xNKRruDy84ydfv5<@9N_V#)y^XktxOzEj8EK|#n>EFO1N0O-ih`;Z2V|){LUwl z9VZo}SR5*kCN^m33(t~$ugBAPMsR<))S@6Jf$vR%7as;R_H#NlG#=Di@T|yT!NVkt zfE`JDulz`4vz4-Kyv=B^fc1^G>j^~>z5`z@9|<%RB<*S9z9-+L(k%wY0Y zN?`kh1-mD)9f%PK_}(I*!OA#W!J~=IF};byrq4yJZ3%ZHM+BL&d=v zD?}K!yccL#+q7WigO-5j0__z(e7uVtCTK8P?^Fy75^rfxkv%7QcH0^OmIoyv{q4fM z{N@o-d(&-Hm=^3~IHb@tPnfYF`bg7<9}8NPB>R~Zd31PtIOSZY`lh&>W};AHWh z!^M3S3v&yHW9Wk!O}lh&@!2eDy29DCz>?AO3}4e3-VICIEf1DhxQM=AuzPX1KwIAu zp4g_FEGj}37K{af=U5wb`K%uPk!DN{Q?03bS|-bpaP&~n#((odI8^@&O}(+G&|>`? z`Iry>j4$^HaGzcqp!$B=zB%p-=Q8}V6SA#iznUQ0D|}VZY2th3lu7kF`&mDzNyg~? z|IWqgrN42%Xt%w~EamFSE!$K43}nO3@IOtEU>5wK!G55IfBLs$%>q_OxDQxg^;^!k z^wr))PuZOf>e<+}E@f14Pi^zBu%FS@&n#2Ff^`Se!5^=u%c&fw;s0|rb82kW4$0;p zp$mkkJ1c&y(AXooDugHV;4GDtRM!qgo(DGUejIM$9ZJscS%g~U9GM#=zBn=l~hY1P!Q`Cd;+;)1OE6bH$f2N8p(7$VPp&mZqP#`H zKw^+Sk})#2kGm>LeW@jevLWN&C( zBFFsuLaNu14XMdrg>#p)ziQd2pjc6*y82TG>xUmUENl-B^2jm&+0g2J`e6IKrwzFe zIhaG3MC?>sblL3qA4C~U5NJQJP@btbL@ti+;iiuY0u5GwBm|~9D*d0YAA0tZVCH>Y_a5qo8e3=q0v~4Gt?LRv$m2RRh})^q z#C5K5hKg8|R&c^&rA1u<=N$_K84rdFEPE_!dtyqH;JJqH5)HQw{Fr(8!Sl!uaUIHz zkrVQoyL>DJ92e~{P$}{e7h*4GSuYW)P@os5sMNN4k}y9H!-hk`Z43!bY%+q(Er;HH zEF?TX7&r-CUDZ`qHJfem2fkH%Zu?07zZ%2t+-3KmUN$tZ`~zRZ zp*KH_k4$=ySzrCZgH7n*1_>tisPf-D%%6U&*0fixaMb@NBhMfI$AU!B4;C;w9B2@zvsPknXm}b}!NPpNp)GE$|4Y!R z3R(-kJ#K7PsNw%}@Qu!;Z3bB}D?U?EXkyL! z(l}$0<8judMJ|#Dxm3&8+K!zPc^II?+RS*&b(PpD1Ceg4j>pZ6f&~#P18l^Z8U*G( zQDkiIZ3qrnp#4j|`Y=OaoIK-m)(371EsrF$rIz{j?vXLAQngT2T*skswMa3z!|{8i zViU8YL%?-*h5}j3gDD3WtXn9M@J&&OsnNKJ^RS21mk0|*o^x&o6D$_Im6Y-bNM>TI zatv@(SRl91y=n4e>Ep4T2}j;e-_Ub2`GSx|BN zL}n&N!vKbb$MV#fo;|k_Xl9Y?5WB>`#iKdEk?F$*ZS8{*Labd=Z%Ql3PS-cQl~EtV zbwGmMu|fUR>8i-E%-Vy4|w95mP%4|F7G%dp&8 z!X;xX5Yi)(lOf1(v9XGaia1Gp+GEmGuur}sf$RAp zj%5{^911Ish|Cifd9mY#5A$=s_6Ak)ro&TyHi#-tW=S~eU2#&4lf}VD>x*NOLBmTn zCZVRs8>HHgI$mZ~*u$8w#=CFN53>%#g%+0Q1qB5po+{oDH*DOnfYo8cqgH1}kE(>0 z09K8OOJX|Y8&>ErvoIdxj#hck&a5tI;4jJ1@WH0mZlO3^%b|w?`mBk221`T$BK>ysQ@p=!h=;$B3Tq$SRXE&p)YW*e*dGd^>SJ+OeGKg zX*Sp}G&Jz2G&9sNoUB>B^bLDHdqcw;=~D;y@wz{_75{tIRTF+j#`y=k+n0WS{BMs0 zKc~Y2J>^hFo;`cY&s)^HcTF`Zk#{Uuv}SFA*bGT=r+7_<_U50rR?P5!zG~H7^+d(X z%@0Ic8!Q-~ItUx>b)RXm{)@y6c~Sk%GIqZf|GNBV#f3k8ObG>C3a3RKBc?Gj#g!yT zHZ3p^h+mL5L1|5gKKtV41!5h~1)4q_FBJUF;=q`|U!ler`{jwE!qf*71XrF=)Ou3l z7_6Zo*&e3Su^>qy&6-Il?YSVs*@rw_2b1q8G8}E#B5JEp=cphTaK++=mPiYm<%1I( z%rPG(Fbl-xbatK9&nm; zWD-^xw>UU1{4zr&;a))NBzeUWwtdaK$MikfJoK$5GB&zAa=0Y;SV5t9&IPZI7;abQ z#+#>V1$2xQ(iNIJU#wLWcYVkqqQRaDr(WNC6?+LF{z*)Yb$8UGwExG|U7E6Up_ z%5#V{-T0Blzranic-iwXiJz_aLstd9ShckNJo5)$rYs|^4?2fc=jO8R`FNm)o&T|} z#gS!=X9Gj3@7OafSic3f@FA3iuSEeQGI^dRfNfs%z92hJUGR8!CiNMz{q;_z7Kp)cUbIOD;h z&k`bOG9Mfnd!HEZeBvYS(e%U3B4g!&4(8c2Zh)rD4|_PiSIp;dh>`i=!E~TOpCzfO zAmY$+7Kf1K$4m@#()T_%P{{mXjUdB{b1aP>&kkMWl66iz!^18#+eJ)PAcl{tdB@e0 zTul>JI2`0ydqwn}fx^{UP6@tm_*TUnVv>aNpx*b68ir^OZ-2sS;C`;UqC; zmUgBEExdchcmv`ZHXL}u@Ywbphr?o90ks}QCWbZcd)hgRFNtt-wy{3g<8C2-uw2Mx zsq_6EJL>E|Ons{L&O(lfHSmWG`}g18e*{cQMHu`Wx9q4sJzTyLmZIkhfC8CUsdlP(O*6)ew_~N-3j2Slu=`=R*u(-DzWV1flwc$i(+tQ|! z%+e0N3hC@jY`w=CbWBv(MTD1oec7O{aQR|F3=gBDg1)1J80WMJYMd@fJnOzUZ&)b4 z_q{$d=lkk|0wq-nA2ucIY2r9EuS1WEsX@9*VcD^ZryN+#Efi&>o~-B;QHy6|wY7h* zsUODHy{wDD`aqL_X#YWuYLRny40u$3NO%dcOjPuk6wlp$_OI_b?xK}!rhClndo<)5 z7ffNi7+|#3q0RnJ^RsIWezVwwx*wRgKYh@`IMHvLy^Ij^0f%p@&HTq7c}!R##gO(x zK`XcLxAfQVzRU+4s`wchSD3f|>k6INP~I{j;O3G2ZHIW}LxV#mGXFfq&&b39>MfjV zY;ST|bK&iyfHVQ~dpu1-y{~12IVCFU?lMfMHfBg_)m0LkE-uc`6}RrDhRmFUIi*32 z8eL-Utd4eJ$~JT44?1=?d{$xzu@V3Oy~5|cg)#dTGG8z|Qdec*})~cf}Vu53+bS2@0O!iD_yOlRU9t4bPRuO{)|NxH)EDVhiGw zNOP397s$-Ce4emFLPkTF-v=kg3APU|Olak>T+DIiLNIH?k(P2M0mD1X*%TIZSTYoJ zI5;VIga{mJVxH&7boRwjj~Kb>U9H83KUP?7T#>*fp`GaP(#uDTn@RAUH&ecM+{f$w_@nkIC(f!}tg9ww*s!o| zk?>}?khT8QvQKD_$G>9Z$y#8gXfY*v9V-+3-4!N$IkN!INUTxHU{6S*( z)riuFv~tC@^oIJaO;)FvphAf`s17oQ6$CEj)V#^!Qj5#Nr}z-&Z&?{(acO z>G-aalf_mbL~1&#M$-*NzJB9$#)=PhviBGCTx3X+v~92!Zfxq&KDS4Zg@fs%Kp1yZ zgToB{C@&t?1v`VdMJBNE)`+k)n27FGco1;#VAuo~gQPc8IGYy9u}OqYyw;VPcafp?75uY=0j{(CEgICVYoeUdooHQf)1sj$; ztvs;xk>k}X7oKs;ElCQPwCc~U6Md~kb1VOdF*sz|Gd%U`{(PbIp+tk!YB~NUq21B} z6`+BDcH5Sv4|zQd7dVEkKGm%F6f;jcYla7i^I9 z313hZ*1LlJP=m|~+d1M5=?AP<&Fxl^V6NC989r5;`M>P+X%+$wCi`mRKNUzEuoGc; za6H6Jl<|mT5K99ygX@DuZZntNb7p5cAXXuNU}*&F&imRMCmwg5*FLXC-tWKp;q%kF z=kPaotG>|j+c{y6K;PFl3=0wkCN_SMTD#yfxP7|(tzNE}FLA?2;@ud?>LoFLPmMgij zDEPb=XyNVp;K8I&t@t3R!{=duC_g7-g%w*ufrXWLOP`P21oOnZT#X50&0U_3f(B6v z&AW2n>pOETu(+}I#e|0fa_?ChBqsO-C>;9YaK^xnRm0+HtKJ@Vp{}D(E-v)AFt=gr zV+ZjGM_DeoxroT|h&4Q{P!B%P!OSAs93Z|cN0LMHa8WvQ(jOVYwuFbB9}J{+NcBl6 zx2;CikQgvH4R(67%sRla-omq*9v z!126K97mIuH$4b1zSpf$&mh2%06HJ8ewx6mh0mAnjnHLdK5)peK%`+CL+U|wD)IsIC*LaAZ)>7M6|We;*#xczN@{MjMEaKHD%>8Yo7?0swElz4_= znH96g;~9Ue+Zy}W7e243Y*(nTbamJ(x#hMXi;jOnp+SJ6z{M+SM-u{+CR8nu1Iste5TO$y;99^gs_Dz`g9@BQ5FJO`_Iw8hwDS}N4on7bWRLby0%4X{ie44j0H-{SqRX0!H?8*|Ce>h8V#vaAnmg!jK^w|sDgL&Dgu zW&wB8mLEoJkxa>NR4z`C*x;UdCr(Uh?Jm|%y9 z^*kr#%1Y0;?<;bd1C6u{VhkRzOt4saP|&$bJt#odzey^-qFs+BHZ_pg?pmxBL&lgR_%u#>|t5GU{{IMj@BKmJ6)6a3IwIIb2*rm zTMC3|v?MoX?RB&W5nr*0b>SII?OK34z7vQCl=^5ADYwKt5c&EXpfDjQb#STHv^DGGxGvD(#-U<2ASYTkua76C8 zg%i^<*6#w1fjc!^TAflX=6vMfy6B`Q&`_l`^B99+fg*ETQIH6S`w~&siBlb`niLEI znGQ^-cxZencv+~(g1AE+GL2z&A5)|>6qs(XF}3eeTJXT9(kIcs`jCVSZ}lb4*p?=t z2B~~g=2qMHzL$6mxvN=>1SHH)D6sB1!rUVWDpWaH-*IbkX3xA%1)=Rp=u#^fpDO$i~~juJfOYzY%Oe0bT7&oDQ-hRa{h z735sr+@NP^?re}@l2Lb%BO$?H)yz*Z5*tEW8FaWU#S9zOof$-81R3_&82RuB^7Ffx zm^MyI=$N78u)yK@K@Qe~{ZkkM439Fm87Ou*x{8EzxH`=}BW}!ag!_t*I7=}r-`>Xp zVm(%KD_YohXwPFY=__bS*df-wqj`@)gH3v8!-oq3T$aZV7#GiZCd0?#Ag(=8pu|If zt3lWJsKbuN1#4zLe7UXgjZ-)qi_LE>GY(f4_f1Pgn>&2&2{bw!S1}Y3voNp`aM;l| zVf*3AaAcB@ zZ%g8IXI;2Hp@vT>kx@W^Taxui{N8j~$&SFz$LDxj8X`}HD+w;*UhvADXMT8#e&Pvv z(Tx){e!ToB{lu$#-|`Ec6ZB-*WS^ffsz_k^D954uU_wH3r+}vgpT|O%2px&Wh2=Y% z*baQYoyB#RqeDhX@xz8>i;y$CllZh2aX;i>J5t)t%*-IRKyJ6o%8I6pknmMIo^v$c zo8ay8ibtV9tMZ`$o5B*&87V2{TrCYAI&y3WW^^1(TF84?By!@EAPr59#_V}Y5+%$_ zUYevy3M@Lua*d}W!+4$})8k6cdr6+>Tnsxr#41#nCqCrlt7w|TbMZk_VVql!AgjJh zz(!tH8)Jp{F1&|16n5?uu;emPsL_0sBq90oxMn+Zu##xO0#=1nPh41fczmMg@vyL- za}nKO&n#qraN>`wJ;E#=rWJO~GA9q8S8G)``#vN=n7zq?=i(6oA01=122Ddl?RHTK zB}V?vx4ktD0uG04CYn!hIHB`hWdip^){hNo3F<}DG$d4bJ0=)#^RT%)6dEa{J#^q? zVSS~bV5P8QiS85KCyK4MVhT+OL0oe`_dU01V+e?RudpHFA#0PrYU6~);Cs#t8am%6 zoKSu5(vUaV%27bT(&a}|mU-&ZslI0zhczQobyQ!>XTz*ban!)6tpi#bMRa~T_Ef8+>z z#FMYkAojtD=~`iB3um_!$ARLrLXsDJH8v!#_tH{Wd61)}I8#eGVaEivL&}{kiic7- z_X#wVF{TSRvObZ0^stFx0%JVS-^#Or}1xd_IjkD)2;%ayy zFu}0EiOIn7iSCI9XS8LTpNjuiD6p653f%v1UQG5`;}8{PHZ%SQrtH(N*69nj>4!cI z@OWT2eO0N=L54sjkuMHslsfb^3>Y1vCwX|R6`B@Rwg~cseQ{bY;4o9QqKTK6 zS>XGIgO^wx14V=+)Qg{}&6^N)Sim9X;Q8wIj1$oZ9TEbb6*%Rkx$qnpXz=1t zm?8B^pwLExQK8@-kLSg84GG^{LfrQ>GxPhLc=2putL=M%hPLdz2M#F+3NDQH;Xk4v z$ssCvM8UC8zjz)`qx1bAej2g~P2U7$uCQ`n<9iTfAI`?-!YAo)QbuqhYhywJ%i(*A znHoMyak+@IsaO=$F&)@h@b7W=)WC}`7W{u$?k~swp*eWz@5GC0e9t#bkPtXBpEGWH z>c4*WQ;mLc6~;X69}+60XMp+wi9ek6cg4S55P6`1@xiIL{}*-DfG&7T{NT*N&|1g% z$g_0ufBul7M`=<<{LKG$ZQu((kg?KhXGEG&V#M^Xc0o%8=Zjam1~9TUw60z!(bdQy z#LQJWiA9;|yHdjzNddQT3xgs<#(*}vFD_1E51g2LzBv4KX5jRA;KZnGb3jD-VZbZn ziWZB&iBA@oytsH`K~+zPA%~4|LT{6T=K&A)jTQ=xj4@8k3<<_A;s%P1GVe<@oEaqd zv@*C~;!fn?ewTA1`ih`;ierLKK!xv$9qJw$0UgY$+}#uH7fUlu{Fo)f`j+*EvW;S6 z<-Jeb{vMhf+Uy2CO&l&?91D`pNJw?)a2YLHF2c`meNl8u@#ZsvHckp1>k?R5jyEKp z5K;Mma#gbq4;zbP{2oO`#?vQUm-jd-&M6ewDO9k*gL&pV*`^IGEJrHr_|4Yr+`wsA zo4$2ng8h^RdG(Bce@Z16-h9v|aKJ*bQ}w`sg+glrR`0uz@aD_^gFGdx?Rzf-aUC!} z`thiM{t9u}=w<#=)B zJM&D=Z`?twQ<}aBIBzIoOOotZ@qMv@qQ=vN9VWIS9LkHhBLo??-szAOYz-Gt65&a2 zcjEhg_+=qWLzb4T*Gz?#CsbrVII-M(G2xVig2NiY*{qD&j4GD{795oos0?CD^yCoV zD_+u=$l)Vi<$O@8H;~bwn!%yP!9{F`LqI@S#yzcswy7=wUA%nk90HDl&1M|VO58_W zBQw%CT(oaQ=bV^q5#S@fkkk5vQsT@l8d+z!Pfxk{{+X+c)mMcW5gGAA)3417TPP^O z&SKCM6Z=)}-({2DT*`eMrfXZ~VMXR+iI5vVmK^@zn-{)z2OOr2S>fk@&PV`TS}*14ie+ zY^<_>;~)KCZ)|w+`hI+_ta4kX@WDTwmQuD4-)(YOt-g}yIqm~%UjA?_RWLYjyXF_KA9KRz=Q3Q2U%2FG%eyp5Gt0hEKPn%wCgQTv z2X6icx?csnWsmaMlwCYO(~g(%zSN}>U-u@(2_5pMCJRVDDv(=yKk)Pqw#Iv}y}9N+ zoUpN$<(IlJd+RUvQ+}KaN*{+aFOZa+)9e}%7Qs}o@KHxaj&{WgoeEvIr4OtndEVI7 zbO;M?JZLzZO>%Zqo@CEGeg3);igyA^j@1G)=5aW3dhGrI4)Q`)tO&+Bbbi>weK*l$Pt|H-}GgIH2>trUElZ2keU#@yrtRrWb@3&!TvnQ9#=_lu=%y69Jsu< zaI0UU^u3y^8S01QtCnWf8#>M43b{CckNmAg5C5$Czb~Au{J8>4k+ZSK8U9BHmMwawYQoR>FJl5fiImA$x-g2M)P=nkg+ zc`UB-Lq-%|T!aW$!x6@t#|{hRu-_Ko=Q+oBy#GO5RwMIzLB>soHf|^>DNZ=DMVYrf z`OC+}8JF|xpQ%fC%jr#zJCxgS#315xqaV*<#+Zi|S`W6o_!g#BGLcm(Q}~{X#fcR5 z^HOt#x;=^#pU6I#@ZgF#=ep&Wc1W_l(D6K+xcpb`+ha+e57<6c_}n;axl2dq&5kK@ z2HIt8o&p(JVH_!Y&m7($B;({fH*Ui7-o7oO&$KP(EHJQAl8ZjMD8VA@)5l}W<31kn zln`6&c;n)P4HC+%E7m@{lU4KK#Ex}VY69+CjQQ0a4bCw*pK`4}F3=NuD5LcGflllG zxnj%Ch_6gq@F{j)r+Uou`CL~1Z<(e@L|H9}md^{u)-Zr`qMfamGIk0SlyTKXk=DP_PqgsI06ka;TWW?7HBG z{LjwPz^_^H{LDWT4#fyv72mRw!|*}&qxXN@0$PmNDl5J}NPYE9a;A^`BepQr3p@)B zWXL{lzNk?j6}n=@rt^;#XDCc(sH~sdEBf-Ejr;+Fg!T`74IlRZm>!Uz#6O#%!r)ai z;|w0I4K+8I4qTrZ*8E?5dgI3r5@8*?AN<_^_kUC6e0BB@k?miYxeuIg4CB!ea%^wp zV+udW!_~|y+MHn&#pC!@U>>t9`v)ZhXSvn#89fIzj3#8oe~s^&n(=q3lgd4F*YITJ zi;H%D{9tIbN%BxaJ->X5fD?;Bg2hrdx9fs#=?D8hRB?LMl`t{>ykRx<(Mz^CImUuB z4f2f~*FMY-T`Kiu^7Df~s(ozkxR^McSo+|DUz^;mgco+4PA?`+<2vwAyr22y(^DoQ z3&gE<3ICHakzh-BWwJr_%BnVBVHXW~h-$Rg6T@Y4J$ua_nZmN+fy&d{_{l$|NZ$8+pCSFS$clDMEPNAlQOcNqFPxvPEOBf{J7;^M8L!RBYN@bG~H zg8f|#Pf{#mgesyJN+`_xxI|^y5_Qc_j#dc;#yyT5b5*U?x{it!&96wQvntp-SGZTM zLi5JbJ1U&rmJc=5=JDL-IaqMws+fywh+IJQpmx5P zi?3r1kK?J_Lro`+hlp*QAkWjxoHIjLij#51=4QvsiWb{!#69}WxG$WMXZzY9ZZg4G zk=^NdV!LCWle}-Uxk;VK2itklgGn<#XO9dZknw6fotkJk}wpwST z$P&|Iic>5M-v@kURwy=Ta%N|J&B<~@)||OffNkMINrgl6w3wMbY`hrF06JswT{`rP z#Rs0!3f*5M79?p;-QpuOkugB!LjVUKA~LRrN{Xn$gv-D zXKTCnNrJUW>iay2NE1$p8>!nwcs-sxmz$AkTHzFjkO(2B1&im~ak}n& zFh$As!3sl`$BG}5r26>gEZX8Q&ql;u$3`tyjL~6<6?<{|^ojzuKH;Vh8vK=t$|nW1 z^q3s4@0!KSaWrMZg$FYaJm3xA6J~6BzOulnmgV5K54vWG8#3S9Fcn^8mHeY5$J$r2 zeD@*oK8AlO7pGV)GSHQK@JrNf!QuL8?*(VFFK7^15W>ef$Al~R++-n%z9xk*PREPp ze*a@!tk?{)J8w$_cvQ&ANt;$&|)XU@X??~V=o^=1|RDWi-Zb8P`^f^rzx?`u2vv!!8GPe^Q(^t9CMQ6 zP!@f-fqM?Sg$@rxfbk(oW|@)_8NKJ?vsiy7i27Gf;GVho!GwgxNgv{wK2+?Gc=yMs zosa)n`pj_I5BvxCE(H8PHO2hKvF071Gu|9*K^{RYXyEy@9%D$ z9mXjCed=n#JvH*D#KJhd{vBN@W5<#DL801Z7keAS2LZhnh6?^C2Uq-0a9|5rS84Gx zLhE2(GbfY7ggAc2fANhE_P@NldetW9R|}@I|KW%WUwN=sd-1~u2K`BDckJ6W7F36x z*ZLQlwdnD7@$;I3>n1W+aXK7W$l*|5FM9C)-@9HH=16!fXyE;jc95a|*N(pFi#=?a zRZnQ_eo)mkm#4tK>;C^{;|B{FF4)D^#o7IDl3HNSaH=@rAVUog<3f%-rJ+Z|U7{j# z1LXBC$}>)yBO7tYou`+`ssGb*a*k&xt-KJ=GxbfrU=6Rfl zO<4|h+cC~z*|0&FPhE}OU$U)b%NIMfcK$HYIaRG8FF09yk1k{5viYEB}tWd$aZd9riYdHIluP*_aYc4}Nx5 zT%nK=;9k$OV}Y`0Ycp$aTiOkeC-WBuBs}t#DiT+cOXAS3xN)=jQw8@VM~951JVy_0 zc=fy~Awikvbnk`2$tlbS!VMChbL?K3n6Z#Sa={ zcd8Ki~MLFK1~;;Ai-#AmMSrS%2C=;lul{N!c+TXy9l37h%KxbHUMv%&9fbG-5zicn2el35Ho}JP1Z@$oxiQgL?pUMcn5!YsJz1H~af}z2`mLpuu2OQE= zn-A1y@jl?+e&B$N3TN^kR?Ye)-!;Vk?raROVc}ln%ii#xMIhnB4(1x(r$z@7FDU-{ zYBhh4gck?H2Lbs%%v1T<4~0)vR}E8Pt_%@;d(EFk!AZXVV8h*&W{0M8CSP?ukd+m@ z_=ifu0uwnV)_{CwEr#0-AM8Igi?%u6E^T^3)*~oU=w$yvM%Dni;fogh8^=SK4BHu8D8@9;FUGAD(ojVacxMjQSIom zyRW|B0&`=NRHI6*OVh{y2Olor58sleYLv74A%jE}m!jCL#s4c5k8)Xwrmb4i{y|NE z2YjCd+h4XH?1}X(6SW!sPoHp7!s&z23V|m6CJBd`_DKu%?`C?<{&;0}@tMgDl@(Ke z?hmmJIqSDoH6+$S{kW~30aiV#IR-^7h z(L{}h(_a{=oH%*N>u}PAm4_B6E$p1Ko;6*Lld zxP+bOo>7#%Tivu=#3mWeaLHqzX3Qz`;m}b%#e7MQ4o3^+J<@%gA3__I?{K*C7CPwg zO`gzr=-$MpgFJyTA9@xV_c#k5Hgq{~p!6Nbg2l2G7t#*>m1O@Q(^4=&qK1d@!9gDB zN3KE*7SgB6KbPtq@Y9zs`da+Rv0|EC!>NPL!ETl-(IZ9d?zjQw5X!wFM(86Vg$ZDd=qspNtU`^SV+jSd3t zr)pwf`fCfZH1II|WcYCS)sc-lH9R@>vQCWi84e_BNbC^M3wmGwYjfiR`;8oo9J`)B zEL!i{&wQYM9zQd~`ArLGIFj$P zXkYbI@0_X;rh4t!q~;$o3l7M|aoC3`^Su@P|846uw}ks_EC&3c2VX5~+W4{H|K|rw zm%52+huPi?n5oaoZR}CQQz3ttNy4yV5|6+?l|Lf&Y-aXh)`AHZQ=|_+bvS&Xg~uw4 zJ!#>kQxTUOKNzrSeQ*|XY;QQ^;rv0tgXe5;r$@`e7t@yIT-B}nq@ujlMX-ne345Q= z{G#=0EeaQyy&GBfc!sf0t(7t3S+PUXgPr-{|7)@Tt2UL?vTVE|wMlq2n+^Zs^(X#@ z$jYsL&+EAGK^5z+O1HT@ea$}#Pk&vx12kS5#UtRvVOYRce~>pqo+EVai+A~K^R~P& zaAMPAb&>8$lPgY9J zd6hdd{9L|IX}E0mAizm!!35UCXN(QcD=ru@g;p#P;rh?f);Q$^pBn3n1?lIT64rh2 z(q=Wf_9e$f!a`S__2G9GhY!AyUW+}RYpkn2cGS=MU{s<(&1a9>NBM=kf~KA~QP}W9 zQ*;;l+ha{_42OmQTwPzV9rG9Zw2YIoq}5rM0zQIM;O0hCgVnVny16e=Gs3 zHa#^l=8)I>e*D#C?Vr&{Ch*-_e~!hTN&ITFYM9~wTbxtOKK@xymEat*`qYwpCLIs! z8~4SjiuX5s(0sPU&Q6algN@TEj9D{e{!_is*9W+Su1;$H#qmH+z>(d-g1N!^EWd5$ zgI4whNt2izuOGiBe}1ct0b78|Rq^UT6F1fBFUG%ml-NITb&R=aYPjc}?J?)T&%Id@}R=|a=rm?bJKsO z2q%X1hZO2%^gm_rERc5DvHp^yO2wkES+`$Y>v*icXaD_uf7bn4*S9+Kb&x_m*Mb8w zb{ww%*o3?vOlNfGKAstJsI)}lfx#rkEgl>S2l*d)Ol;o8Wplt>EfA+Zl3Y`9G z;e&4uNrkuOENOJ$c(Cxu0Ry40_c$C(n3-D|nbaq8G$g6=h8VI59MyPIeZnC|yy5_N z-y*>oJpOhPZ3%l=D|lExh1gtB-0_f;X}u()V9XvXpIk2KgH@7yCOH1cb-LVT!}Huy z+-dWH6LQ?QnB5%=9T&f3USaXzfO60C>FG*_QnrdSs#VU(GIu?i6!3?&DdS1;+6NDA z%sg4b$L>&YL?WZc{YiGoA#tWNTf#(~_BFRP&M;!q_u@R?tf05Q^1zCD-Ja(c~GHC0K>3E*ilP~mAhc=KV#3qx@!>2{Z6?4DVn9sP|b z-`|m9Zc{z*=8`};Gxv&LDLYIZYo>_R_s*0Pb8_Xg%&|}r{NCSuvf<&}2QAzTU#%ya z@yPY@urnNy5^jFv@FHtx1eavP#SJk@1%(R|WMbrsn-v~}2QOfk6XOg0+^pblr)ywf ze>iEv8q2uP50tZ|IGq$DKNvKMe9+Idu*l*+Jb|6fVV+UJhG14d?qa8a$1))g_E#JT zFK2zxq|wyACquSRJ4I0PAxBtw#RRL+$5kyB-uyDfN4}mcp7WuDgX7}{UJWhD<9AfJ zUWIcl2swUX&dGy+3LPGZ_y26n(9pd9YIDZZ(VIRd;EmNL)Vnr*P^P z_aAJZnjY-Zl)K;2STX%vD0|lWX4$C+{;?jIbH9B-i~aW_djqTl@}`Ow2(-4VYUYVQ9#_`v==8;76+ z`>JoNRypint5X5GH%fv>l_A0D`<_^ll-KD8_Xyb8hs3RZ)&8G(#^NPM4|3G4DfPY* zHRIF9pCzxlQ&ibMB*?P}RPcX1xWK5Pg8%dJSAUc_>sd^u?75YssKdXSZRtOKq1%(> zf^z*sS8rVZZ{OMn1`j#d86;Q~9v{+h4`^8VlG$N_3*(#zj?63-uFMB(L~O3^k#$|i zb5w(m&FsUBgoKC>KjvIz7oFVnsQqxk4kfmP*p`L0JaSS(T`b2h-ut-vjtoPG@u3Tw zSPmw1M0}VRaH}TcIcr1J{#_4Q}E$ z#ymqM!rD*QVvd7ki{pbwjSVYAPl-!@iP2;F5i;lEk&QgfF;^IWa=2M=l}Wr0Zd3f| z5T6mgwxIQS%ZnJXJth+CMA;5CpRo8KSCX}3xw2!xJ+bco6$$GZl^E`H^#%6c*`Y1- z`B6OUQ-S8-y<7)RbGJ3~JQNFO=he{OkQF1)@rzrE&rHNi?t5RmXvhzK70-@>6xoHg zpBWGI$W0NN=6LbLfr1$)oVesU_LQ(VE!wg0oWg?gjs=yC6`9xD6m+fch%~b(erIxW zIHSrZUOe@9fGgh-R<|8|X5XbI+Ppsgsf)eA{^JK}CdV0nYOen}!5jYKmVb{(%>mX2 zh7u&B&(69f<0=7i4aTI z`g`FY+8N&evzqAVpU?K}_&$B1tyMM?Br7jol!!)byI?( zeEkK1uXzFo0#;AwT(r0A$|ijwJL?}&w^u%>*E}Tf`|xdl|6eAj+Zzguc5b@-*=mRQM(^>if-rM`{0lL`LGR_>?|MuNNT#U{i^sM5vHhy)TvW#pg9(`NYe z>EjQ{t)G}{6d4j6I1(1F68W`lFHhqG1zWwJ1=Cj<9XO!C9AINVFSP39gC>C~tE~7R z6mT+E)Tr_=nXvn&m<{8UouPjomt1gQz8|71#In@O`{ZAnnMWTSKln$4LrYIj?kU&) z&q)yzRywW!E4=>O{#PQFo*Na|LF*rPC^GUaKhw0QBZi~EMWRSd-pGzk;KPICu8RJ` zU7Uq7g&%$xG%NUV-I<^#E822EWbr{0**1s7jT{!OngJ0H1!N2!ceX89w9@g=`JIms zJU;P!zNvFf!1umIS1e=<9-2oeRxC33wDX~kPQ-UM!K?3u9a}ThEuS7(XcH2kZ)Bpz zU%|wpqIBlLfv|!YtEF5{L@J1mwzxf1oE z!{Inb!-sk2c&3K>i3!H-OwbK7Nf12a+_bQ1;ld-083%%QthZUP)Pq>0UqBEJ)M zRGRLaZS-YLsf(mv$qENH<+mxq=Xl%sl!Ko+T9y~oh?xGbuk*OYBiX-Vg-mbx-fE5) z1`p5kuyF-?#3(Wpzc`^X^M&3#Q6{?%ZR;66b^;cb$1XTAH5V^C;NW35*JsNTy$WSv zRdzv}8~@+MytY-(J?_&a{=MXZH6PodWlO|(PaAIG?dg+eI@R2>_vr$K3DTD z0~cy>9TezL=CRO^u~w|eWj7LIDzI4ayZNKjV<9O%sUUSWhoz!f4?7ar*@RWj1PR(c zIk4^j4331!mIoWS7#kjIaWGCi$iwGuBhcJ#BY#R!SBPcZg*89e8q&Y*j7WL-M@CAD zafh8eQj)I&$n0xLT`WA#y+@`PT&z@f41OC8F^>>~q_$&Z)3(O5S93DWQUc&v9xeQ@jg}Gj1;_3Zo7d0d}a4<5IapX?ybg1B2a^z&eQ|1f& zNoxXUcbC8ITX?@N%6hF^tNi!JKCKD=65KvaP+9eJ(bKH05@|dFjm-PLU*chZdQa}l zjLQ8|<#PN_3YFSetlhu*o)*utVto~!ABG&tGaoagl@f?nN~7 z%1LlEI|^)=5bYGw;+T11_DRPxEJvA}n^G$dCN-|oW{1c@|4&#)_Vt2NEA97_l@Oq^#g{ zZk%YyA-p3jMUwgGdhV5n9v$%a>EiBhdeO+pvY`1f`;JU@j-~Z({9LTXNl7wKFT`9t zdEiPor^ecc7OOrwH%&bCoh_ODVxo2Pgg&m%Wox*Xvo!X66p%{csc_RgnrAUfn48&< zrFe??9uXGpmP00dj8#usn_jXiE=fCR`uOJ=8Rq!*q7~uVSC98M*grn_X;NIXS?)l2^9 zd{H3B{Hq|<;UI$|Xi!bSCMNd964yPqKQ~4E@cQvL;(hBqU32cM2ep`m`jfjD8zdPH zI4~S~kk1*QAYSO0eO3JXt@J~>$`2neT*2@m_C?O`qX(K=9UckI|8na?I3LG>Q;jYA zr%z|$Qte+f%kK6cwn*0?y>%Cox5==7h&k{CY`bAtQDbl;%0NAfYek!;xHy0Dc@d8GfJPQZ#}DOyH=fwk63;Hl%gn)N zd_z~yomJ!qKkG4hu6q?qGI|LUF4bO6I3dV*%%O5)N9KXvhZ_p69<{NIkzjPOlVX!R zRCHkWJrBeA!b}392TdO>(6I<`kh`dPiPtH>pT}3_A7_5yL8dTKyBT&)m%9@rm^Q54 zeBe<+qQixRBYd2}FEtHv#Mkk)@i1NyPi;BqV9$C`p(06)F>(O}+iqEYP`Qcs4 zoVMcZ!K)4>JWdCVn>-TR&KKwjRDFJQV1+`{)xO>j=w3t`4OI zG9MpIXgSMy@SM)}Ma}DlSvlGlE3+#ZST-L|Z0xuoUJz0ElC?*ZPmbe}Y()#Ntj{N5 zo)13+xc}4!?RV7Kv1iw2{%Y1p5ihrLHr6_JCIRC(_oK=I75bkJZaQ0Fz|O=mVcAQL zAKq7)7qdP+-u^*?F|*-_7l){S|MXcLjvRHd@1^y+4)#xH{3`d^{*Y>x$o2k5j0G+N zyLkdm?7r}@)#3Q*0}B3(6-QWw-z03<_2tC-YnR;TA2`i(W&eFy8^w&^SN7IF9{-S* zzh=HKLRFqwKG1(UqR=Gzf|F`^Ki? zWL2QT*!}sSg76$3)F~2n;+oUh9Bhyv6TZ>$!8*PQi{t}^5j$=eyyrRc_~AKmnac+f7Rd2^ zU};m~WNp<_ZFrcmLyAeNna82PZV}Vr2!#bRpH4b_PM)Kq^wq04ivym_S|<*Dn2|J3 zwAI0Lg@N0H3DbB^_vn84D>a9$(ctAqwSZo^8x|ijSQCt+*o8ZJ3`}GmZYblkym=_0 z;7-fMne0*tdo@@b9TK9~E3&GqIy|V*Hi*$Eo*H84l+f|3#H`(a4{K|`3d^yC3ko{A zjQk!E3WAIcdk;Er-+AD{*tKVa)&6=Nvk&!bBF1bXJZt#-HCVK!y|as`t0{Yx@r>cX z0;9$&@3z%2ha5?FKYaM;gX8BDGI-~2az6EsN0LSP=&y%=xE)R=MW?g>e`2zL>A(+z z^p^!jJ4*gBA8b(ctk|%lW_{muwpFt~7#=uN&Tt`tiJ4{Bni!rRw&E5KPcR+6&ft;8 zci@u7&Wnpr&Pl%WeS+7AB@71&^lcvTeQ09+zC$Oam8n2oMXYI3LEzr^w#*xn_o_(R zsIage?{P@>+mXX6aG~Hx8lOb#!3#NxEDf{x4EWf2mZUmHv=n?eR#CuuX9Ej!YsZv= z6{5fRBw86YTFpL8;7jjkZeyE}xKQK8iZnegndKJ>*2tK!b2ByQNPSkyXK9!au-C>& zX2tUiix&wY2X0KeB9o!Q`d~-6MJYQUFLP&KA8XqRRpHL|IT~qmxLCPm#n`84e<(QL zu!~>uO3eS}t{w|P#`T95&e*`dqw;9KG-IGsuj|x;H4_Z@!WTWB%a$*-SHsA;v0zas z4{LwLj;W!>4k|aZnI1l9aoc^%-S>4#iylvq!U^$42NfR;!E;W<4~{z?QF!R@c!XgZ zKeMHx^zlQhdn+v1l>agJB|7+)u*pm9mttSd>ck@<%gN4Lc;Mh=)l|u>GtyQvOfnbr zn;IIQ`3df8^5iscd)RW^#_vIk7*Sn|E+ z^kK%s!VhP8EmU}}$lmbgd(#s$CWdwM8jhb|B*D$k^isv@Lm^{>?2P&L{(TJ0hn=1V za3(zFXq(vZ!GwE3gu+R02R~-+`!NCzd!!^+=*aN83pj2FQ$8Y~Kjl1!f)>;BPNgZ_ z42yW=93{#pG?YG8coWVUA<-gid`ahE&uveBeq}bJ@;1h1xmlpo>RMvtO8xwd)Rne8 zZ{Fb4+m_n8XyfW*3mgvheSY8Ru;WwnypIQUeV98Mc?8RCY{k4dmoD++a-UbQhkeo> zM#Z@*1@>a?ZZbX-`Wv=4>?wF4%U5@G(V^}0CwcMl&-uRh@I!a8k{7D1r(PY=R(RXW zUyx!f$S`?B@$z5#EXVs8vgX*n7h-(0>q5aE9ahl?4`=1c@HAEN+0``9VHda%8{F(A zl*RBsgZ1_C!!05OacTw)*#YJP^88DjKgeXa{keMVl-!3L_JS~u#$HZ$$G{2fO&WPG z#CVp<3gqoeb zbod!6B4kYa1R50%xNtsn@K~wd<>-9OSzn@g$3k_BEf@U6ciiOSWov5hP^;+IV@g=T zXV2gAsD;g0z3GI4wBwP7+FeT=z2_B}e2AYsp&@~0jv@;1c{Rq)hV`A7K(zv94s^h{69wz=>8kT1olMgNslz2Re&7nrh zO)_?OLqHr`l0(h?f9E9`ExbN1kkRPM5soloWzcQ7(7}3?<--rQl^#3vE6xi1@YHx< z`S3tN!z!jP3N3sEE^ITzTc6B#U4F-g$xm2-U7-E2zyel3b&iIh0-1y)ZkFbWO>E5! z46@Z0LO2uyF&Qz}Y=3 z3=b46jfk`3w>|K1?YRXkyX3gfH)aUQuWfFNxKW|T%jm_YD%yH@E6apJ4tlIXTG1Hct>4TF=NDJG=3r%9* zSkBoPhPF+K_Mb1&?U+`Ovc9v!IWbNk$VHdwjl#^iY%IYiW_0qe2sp5?#o-A5o>YT| zHRZMs+MItdWj?sT?6z>ubPq|!$rlvZ+xJOY7_%8j@>#QPzQ_MC?r;1t=KtES{kFV3 zw@2b(1NXV+2U1oq8e10@y=dM0Ac@1lMg2U7gPVYi@(Cq#4uu8lD+&arL>`D{5&Ph1 zZK)8>%5<;5?biW))?@`Cg+)v+U$zLQi8ZWb=VS_8&c+y{o3O-*>EeUEhZkuvH5C*p zSVXMnW@&L+5TayOII*wkhAkI=&Kt(Ym9K>MKE4@v&P$U~zaos4g7z3H)ri{c*NiI z_PsRMi}RHm&sd+5?ctpBQE~N-6XFYBB{L;0@^n0w!7VO$&qZyq^C2-d5%IkOZHf;< z*(D29TMutOZCr5nY#m!G07w@ywVN_n|9I_#e>7Lb$HwJ5b4yfAX zupZXp{;YnKLD#B_`#=f%92xB&Elk`_mmkS4RuJG5KP5h&sj1~*CFg`1@vQ}Sf}OO~ z)cHByi}W@bU*`EfjZb*up1lTd7j8Is;8A)@f`+({g&O1W;wA%&z5*?+s+I#^rhSm{ z;*+pF?DWLNVVfk|WXT763vvR5`sqt__=>f62*S$*w7&?U5*!E~LhsQi{aw*;e;12scS`T3CF@iCa^_Zq61{o)TyA zeXZwI4Yu!DpuEs9A*o@PiF#ka!^0b*xnw@7ES{tHeR7MqKXc1F_2vz+&AmGxZV+T$ zdCcK(Lt?|02Un#+9yKm_nql$7^3mZ5KPS-8a^?7YB_kJRP-{3Yr+D- zZUzrqw!{hg8Ch-*b_Cwz>{d|ZYhwH2S0lTJ`($H=_`{ct50>*OXEw$Z9(b7WL&Vgb zU80~xVTKtub6?HRPw^?@4-W0pIJ9GeYqPvxRW^}{CMQ86I}79U2lMQk?AUU0gE{FKA*3FN_c~oOs+I(L%z4$yTJfO{0BfLh~+3m&Pvc zYMeE4b614EgW{{Ar*9g zWMxd(>4Oaq>m7~?#vPy1%l=3~jghN1u=aSx?vScyn${107%pyH!Ojrl=l7lUL_&#J z^$p1;1u6Cgd$nX#*)4??6#B|dCRr^KQqX5~=A6y0Eafyo;=v0pcBYIgDK+buJYv2z z*4Ubgyg2zzJo5hH!T^he3mcz5Hi&C?lPNrQps=}Zy@e4+Snv`@kGm^b*RfCVJj%FW z#)gasG0d_BakA{o|9_dXjGO7f-s)o$)Vi7#;%wGsHFvP}RTN7o>2k(==&`6cdSC(T zIzBNb#nXXIKZRup>q@Dg?&Iq3F)BFltn1*B=Z+JeB>mzz zvg}}22j@L6bqk4xf`F*phrjPkTG68{qN7$Rs1Vu8IO9QubK4o`N-i6k z8(jmwUo=QGaC&g{L=QL1W2P^BVhqn&Sy>%B_`>%nF)p~SG~oz~f*Z?)6H*RNTMSvQ zHyyA&-M6QnAxDqnfsG1_WyWO2kO{wEOj{#SCK=uk_>Ead&4op)ru6mKzUH5dhaalO zA3qed=|4xSn`8UY!w<3;7k_nF&|OoqBJ`n>YaN?x-@7k0B@znF2mUYOXJ+J>!rs!* z+Pv_p>`Ijv6PAdS#!Cg1HC_~So7Db6hshwHSzP>Q#Do=)_-~$`V(a0HPlAo+$#uLpUM zmdytGj85%L4dU&4G#Rrk&o&)6#KqR!c~6XC=8DWkH#CKqX4tIfK9D_`>C5kSMbSGF zZ^U*8^cLK6x?d3V-15-_9dSPHxt#n$jK`$f*cq%uzA@HFFtIvhyb{ooThx^vtWte& zLbB}>M-G{sjtOfOS4mB3`YEBh!^PvBv3>8}2M-%85}vmNEU!L%;L-6NKLQlKLn zcRG0SO3cAPQD!aSJvXF&eJD8aqC-aSVE9FzOK%KBo){i%_!3ZXM1+-BKvjaRSuw)$ z@q`_+eAb5|JzEc!9GcGUFQ;K#8{xp!+{nzRy0Kw`U~=a%$Fo&_AAGF3=FQ@5-gu*c znaM!Tj;po&Lcs~4%PcQTCAi)dgtaCtV3&N{pwPs@eIRZs__dmGR_fEEzij^Y zu6QV6!@{ooAR(atN;6Yy_!UEy#T>TD=5GpqAOG->frr_#N#Kj(^cMcwn3J>H8(S7V z`uTFff?yBORjM3ZjqLY77|5Ub$2Y}>nf+_T1eG%%zUM7O zHZ1(0v9r>#lZiv2`QZWnkJ>sPzTa54r;bD6*s6JEwTmCJ94Pyc#CSk~^A0yVZ}l88 zA$Ezz_i5Y)G2$%^hngaslq?nYg%n0I84D>DIeb~TK)jGajh*v~YOw^v4datX{Hz{S zv56EJRL>LdS;4ftnM0{uPMGzF#p{y}2Sc(xq%od6H?JZ?yGyWno*u)CO+5z>7tU^X z^m$cqVa8JfS;i=>f=7{VC-@Y8S~oQ~9GD`-n8xkeV>q$t=JF*v7GWIcs}DDF`mf_? zP0>n{d48<1icdHweXiz$!iEI-27?1Pzc{t=w6QU_euz+E3}Wrl5NBARCCZ&((SOX7 zzemHE@yG*{4N@k$7s9(+5B4ZCce>@X_dZtqri!O z0kgwt&3E3Vuh##4_LAkkKHKtxe+&*q)*tv6^fl|Vd(xthe;JN49J2WD*fF)jTVDI& z|9JnItNiD%e~@Es>~0c2VB+~_QB=tDBMogUsyU|qTT@hX-MH=Dd@}}x>Yx2#amrT? zPoM80!Fa-jN$GN9fQ&$eMHXj+5!0mru^EpN_#LxZwrB{qGMlaAGvj1D7?2PkRS~Hf z$0xPNkeRWeC-q759)VVOmd3-!+|*w_pUNzu&sZkV_`L9mk4%ng^}&X~MwtK|9^L{(@(N|my-vNJ68B8Sco&XIw@?ps_Wqt z!e3Spr7rR8-~qQ8x`kg?aeZ*NQRHlU^r1L~kGs8G00 zk)THp9`tFmY~0}@%g`o&_4)+S$3X`YH#7L~^mKD@Pe|?WY&39k6Z=r+IQ2cdWJMky zx8`@5$_dYUyOh~?SUzVwQGL+%QHE25Be&-~9mzZWtPflT-c_?cad_~s%8{pCVTanz zLz>P99)un!KHAiD@z9YeGep?ACAk+`fgLn;3CH4p!f3nX~wb-UhJ)B_BI}P z$>`v~(crQArPj?LF^-7sAIN9=T?7#3@=z7tDF1X zJ^kPxDGM9^-w)YX1T11=*!LZa(q%Z%$THP=p<2oDh4oW*$T9!f;PA1)@zASmQU2=J zQ_lXZXHR!5kP3|#oVRd!Xx*Go=Isq?OxF3OmeaXT&EPNe7Pss;C}5ybc*@`Elfyyx zRR+qZgl)Lk91?t4kNNQx9tjg+LtME)_?{Htn&Y`3xJCFL8NsG%wH(k!G}Pa@fPi zVA!x`vA~1!$`3AlTq`-1k_rP7VnU>qMCP(IF(#;W9TR!(Gxdq6UMk#u zj=x=QX<|f-)Se|ba$?`Ji(U#m@U&n8zc4E!lZCbnYq<l-lih0gbv1p6}(DJ3Eba%A9xf9 zu=Ah3Bj8}}-Lh+C!jfGL^?Th@Z?UpgANwW{#^3h9C7mHbfyE%;2jA~Uq4yfUGORlF zyD2ToisOJji>lH2qO9ZlRrj>Je^@2R=-4~C_pR6ETv;~x&JvFhE4^s#`U>*YfNLb4AYxh+3f^&uf? z!5+s<;X~n5m<86zvR8S1?^rDKpv&n)8k>PO>w-BS0+hKA3S3N>ka&|Rz{kZ*sK;UL z9P#rk3o805oS2RlmTGW1dQ=@;KC@vR^DZZD_hzP|f;;R_S&s-GT-|PP*oZ0k-bWLs z#XLvO^J_J|c;NPk?-PfIeB~B_<^xikiXWdZ>QduzD~RL$5>k`nV8Q&$kmcb=D|0r6 zIUi@#1ju}zk~3xQGxr7W+8hdtH}SO}QrIBD{7q|4&K%~t zb^E{HTRV5v3Kst7jU5KwGh$!9G-5cY>&qpYX<1?1AAI1CoNBXtu$zA9{{vCM4F78L zdKyea`h?nd=!HJ~H6b#A_0I=;#)W|j9zr&Dea1OlO%hH*?fWmKGET5tOQ1#zF%puJkzq2ahoxNl`PO#u%_+=>oYp#~&Mln3xYp zJQUb?j?bz>;NamX?p5M#N;})-4C0yF8XivCv0+7mtVgRc-+~@KHJ*7>Sy~ehZ>o4g?Jgsv3>y#tvOkE(dLPo+gC|*?S*81b$IrY)Wow7Q7(DdBn}lVNG>M zCv)qW8CjMZo?BXvDoi+6s4UXUur%`RRIc;P2@ee{eqQ)xA`@n`hqcA(d6PmR(}Ev@ z+ZxU_ckmUcrHEv8sC)5Mw>i(#ytq0fC+*;|1id&3HrW$R4=%*AI(_-EFuqxxoq?C> zCa=XmMupr6g|qWLblDpkrwBMPe0%bOgCpxmYx4hJY+hHJD|RU6Uu}N)|Cw^yh^34n$6F)iXA8Y@h$lPcl-OP|+SfJpj z7{X?m+_KW;=x3%<*L(BYMB5VnSvT?j6Riu_f1j;l>T3C4(=FuBb0i3R|I-m#S=p#n zbx}r7_T}LR|72_8fB$ZrSky32p|vD7ef`yb+q*V(QtTJ_T3jYxU9dr(iTD34=725X zkDh9oM)X&^PK=(%y+D({{rS1+a=#lL3LIG<7&PqAd)}tNe6UT1kHz{rYo~%7pOnO8 z*6u632@fS)dUD^hZje@dKDWq;>#Q6{Uk8hVjWFYzM+r_`{cH|3f5k)?1?F8SUMyj; z=A0Z7@@+{!un!{?2R_= zD3-&@+_CR@S_%qv**W`r9OgGEX>o05cYBk6@Qjq4qQcu!AK`$)2?w||&aAi^A-sAq z!wIp1HFk1L2TE8L6e|Yo5Lu+Gbdf=3NL6R8t}05oN3JF;@@+i=|II5Rt1k^ni7@|dCIEKF3aPY z^Ql3y;lVP_jo)osnO<=?r13~7bnsRgT=>KI=(uazZ-p?w2cW~{B5c?%CLECAiCH7U zwPKP9d&7?}HL*4t>GhAS5KJfpXDrb^c(}Q$|6846MJ3AB|-yhF9yzt%Ld(zaDbE<=lNaJ%yzIiZWKC{%a#*lNpVcw)!NbM_)}l;~0gome2#}rG zXd&3BCi#rgYbS9wnyjJ5o603S9PxZxf!` zSkUk?&BJexhTypt$3Cx8F2n9$O!K&yr#?!&va4=>Xt<(b$M4f@_xL2ZnOVrq=;l{-en%bsrQI6Os;ie(a zbA`3~SWCZ|LVD*sGcJe2TpQoArZqfya8P-|&xFTc@(%2g@pV*rAkrA&r!LR+yxWB_ z$DkzGAw0y~HD*DM)3eGaW7$&5Vwp~)Ks?+HCHNEKaa>a6@j zhtV)R%6MA!xbcpVbeyWAMzzP02@Y&|7TyfYnFAOf>%C|<3GmVC=d~p^SGm77tcvHe>sK}2WFA5XML;PK1pn>`o)>Y;~4Y%NP|JbqkugL8eIowg%~zv%n|1^oN?i()sv(mXxz)hCTz1~MiaL{@qvN^5{KsaShXlrwFQLeS8i|E-v7bp zLkUxhop_5w3+uZF2j&R!v$+H$?p`tHhA6wFXkdZ4DvRscJw6XV6uvNLeAyAW&4|(`VGNi`GZ1o$a%o@Fj^F1Vn_ z(Ns{drFA9`OR}M}zHBeIh@AER?ST{c3+4zk%?Z52Cb{E@YIEB`qjIO?(kcx_4o)AQ zsHD}Nm~%v+S=d2xYniiu2tOn@3ILuK4VhBtzY>pr-# z&XGwy&|=_uN`jMvqs<{g;>MiTJ%$WDLEkXoKb;Gz?h|>_K|>{Me&uzEHc*Y z331Y_k2_f#c5C{G9*;BPani6@5GST|xYL!(;!*lU<~iIgu06pE6;6pUDIR`sQNl!n zOSr>iakdElHH2))Per6&K$d%qU)O&@2)6iSL_;h<$?vgM(-{XM+uM`{Da98~7O> z@GayqW^eehA-`QY&h?_AQodXLn0oz9LQhz#5_H;?q~OF+NamX5&!! zApf9~;nZG7uQfB|n0P;A@iYFtVZhcLT7SM-L!Rd#gJQF`o{)v|C5I+EhNoG-E=t%p zq_BWG3qmea!~e@3T)}p)&r6PZjF0?ys)jc60q0d0vYnq0M^3S2@PV zjenRF9C#QV8oxJ-Gt0AuzNj%`*znIr!pn@uj*X$gAtOcA^1fX?C(8i~&*x&!OBUSV zZ)b=s_#5!$t=^2-hS?8JMx^mK@H2FJ|uHtZjl9yrkW#)O~o&yGKm0dmZaGYqD4ci&-bzQD!$Kuj=#MW%7V zf)___F!dL+N+>ey;F_bz=pn-(BUC+evK?PlOr(PZkA(pbH=AlJo0SJIgS*J#E{4tA zOadl?_ab~Bdh%|!=_@ESo)>wp&7Z@e*hY&h(PNDs6T_60njfZIGD16ySrw0R$8jB1kRiD9 z$fmF(gCp@ApV6m9+>50+9Xd2QxLahDwapoiO?k6UkYVS;mL`W4J`$F%+5VZC2%PYa zUZUx7XyQ3>ixp#i~;)xMh3R#1NBurj1S~pHZ*@SNO0uv>TlK-s$h9N~z|Y?BuLU$;mcVzx znM3uy{11^XXGIlnj;!u&)BjZotI;6RM#KY+}f)B9_9kM&GnF^?@L!@lX6 zjG)U_hogrA9OW_J0{1_9{lhRV}+BDcf*J23F_kFCLa>oco-Kl zl-ZU(kb4mO|M1=G>{o<@Iu#BnpKebOQaw;(!Q|Kcg7tuif{@dPG{%l+FXkw4Djc#f zNR8=OP|@LGD4@+O5W>W0ZL{6?XN(0u!-D5F>N}(cr<%_W}XY+1-PKg;N zj1^(Bl^o)G4{wN2HBaL?aB_p5;)^4)UmquW9`8SJVTX>x1Z%#|=7wD?c|6Qp6||b$ z#hIroRJyV-B_CeNTA|+b_lfXc`+mBZ_5+Ic%0Glnae&!t~2t2L0Q_YZ#_7dIkX=Tke#8guW6yr6yCa6#8%0T z)1Q6vh6N9$8yzmhH6`fWVVV4*HAaF(L7(ZOGs~gRJ!+f`lbAA0nwGM@W!-)9Ov0mN zf6XR?82+vC&gShOF6;$aFW;l zVfaz4IpObWHiv5UI_uh%DusWz8!{9?-An^^X7K{%?x~s&-u@F}X?5~&X5Ki-A)&#J z;n7F!{g>n`BNVl|ZrTVeEbI8!wZPEe-^%z*i+{`sEX~f24-|}9<$tVwaG+#|mymLl z2R|d@8;-20f44VR29~$X^Qx(dDcG~8L+*f+2wRA1g~0F31DPNALhSYLFgH$NQLt57 zuJvhA)sh1SOb!Cy_u3w3|G;|S$qr`6J#hk88CQ4DlW*p4zp{J!vBn4X>K|-a*p-|X zD!*l1Wx(F>xBS5cX2v-@90n4*R>{6NA;rx2Rh{w20oE5&A1k!kZOUd7ZHU?$&#Hc0 zzrem>n!ui~UN1Bj7)nh1^d>`v;n4rSy#^9z5`WyD$iZ~QDPgOCHnT`U4HM&(gXg;E zC*JEk%)peuYU9ZGk$L8ehXF;B>U>UfeyCZ@I3(QJ$<`>yrDx`IG~blz!R$Go93(G0 zDm-f}m|*K+#@#91deAw<^ibmFCW(XQYzZ?GHXl+_?L5uG;riHMj*63Ahl9w@g9R=L zdz3g7=7=yXJy_$zu_wvNsHkZxcUw|7Q zZTb`Qp^2AmuVRpj8uz7hf(%uC7B1Wu6C#*4%`5WZZd{-d)y1aL#AdWSn2Gb&X{QPu zn-4$S7HVI;;2<;Gvq$^57lo@d6d*w)~1oY}zZ1zL5}9+*W&H zGcz-PYmP`FhgA56$r=*MCIQR|4`%f&=qVBtwsAAiw!Tof;f#G_WX1_&>n#$qKRvVe zYhO^I8M1ioJXWc#zHEgzW?g4j-r>05zEJ(LtG~qi|C@Lp+5VPSYkIq3E8B+&yhh9= ziqmhg&Tx8=-=fg|ppoHWk^R?CRTWq5CWLSbifGB7o6mgv`E+p$z859hEQ~6XY#;t% zQ;6NYyr8Va_GurSQ>4M?=6^P$kWpzHczOhS$&d=gXKdOu4cId9y*Ew2|?o3J}Qa}9w#L{ z^{|+uqvV+0w%~AcPt(^!4GW93k1@CMF4{IDK;W=IpN>lPQK1<+E&3b{t1Q+k+HlX~ zbWE2MXngZYpkVqG1`~lj0kT(rl&EvH%X}2zyn10n!;?fA*8Tmq0s&mCOia(yH4dsY z9cX0m7Uox<*myXoqV{p7S82tH4fZx44k&1`%kr{G@pi}=Ownfv%s$yHq0hA7giK&X z1Wzlk#6^!ihDZ2Co2m-dK3|s49$1tl-r2~)pT1LJDl>zqg&s@76(uM3?l$WTrGR8X z2~Kuy#tZL^S2O%-m~vLV&5ye==#mCs!h{!!T>Y#DwhDUvb2!wM4+ik?iFF@MWDzMS zoR#?COu3P6g`voTNA8mq59&Sq9JU8ZIn?TTc<_A5w_rYvJ7hzSeObgeA>1C zsIsS;)W1Tnw}NsU4HFDsG%TFRn8c)T=5p&p0fC0iUJbRZH_{l>KZJ<_x16^ zANV<(-R}bYnu9h`z|L( zhsljB9OoYK%;8Yjk=@90c#oRwybouXjyEe-Hy#jle(Au=9!RqeG2?Jj}h#f)Z&TTr8VD9k|PAS`ek7(t7w@W3qDf;R9L)KFiw}4H9A; zIWBWgcDP|-HB&~|Mq>ge%Xu~jeU9A?k3yS!gk`#tw4PC5Xba@jm>%E)`K-p65dCRcgH<% z;(TwR{m+E&V8HJ-K91vwr}+vLJI)spmXG2MVt24UHna%!17a98cd+>DRQd zVPRMJARx0UK()f6z=nlA;nItLlbFR@43Zt*FdYl2c)&W3zrmQ{=AGrv3Ma0zojQKI z+->;{T^Ft^C)m%vlWv%BpsW7=N(Wt@oeQgvG}s>WD43zdvGU9!rzKJk9fW5KIP`J( zxi8{nb#l-+(cV}f#>e<*LqQma*WRX`0<7(o0piT-tW=Z?=M^{}JjThxAzr!k{N4wj z+!smcaWF*p7)&VKKCe;Og8M?OjYu00<9VLW{+)t++>2MNk?~V2YChcNuz*wfL{L?$ zD{HF_Pft)5Gh>4Y&w?j>!Msh5eIIr?JgQ|ci1GQdz)^}r$?)(zgSpqOJU&iz+T0kW z!(#BP_?Una$BXZi6`dy}6~u9OF5?t1(o>V|bh_bEGWXHM(;_MrDeTSj_#~K51y1D> zo+`9M{)p5SMTN6R`YJk-+1fY^^mv#Zs&t$uBwoI18IknifK~gE10CV&EQJ$zWC3*&6S!Uw+u*NX8VMiY!Gr&hz{XA)I^%r@v$K zF%a=kVNuv2dswi3dhUa!u8%Ga4}@64_t-b2a4Im#>v$%!TR6?8y0SbqYsWA zI8es_cgB(zKO}Y~{Jwp-;ZOh@f5TUvgDjrE=Ce8cXxsb6#HL1-(SXtYPJNpNPr*&? z*NqBXJU(ZHxI5+rSl>83x8`>H!sAjW3@_EMjx+K3u!H&H!iEV`T=?YJ6!sow5O12G z&$_@uiHkd~Muq$EdzK3!Y)r;YK?U;61>){<2hN;fzslp-n$MzOBN*qwtY#v@upzlg zAcmu9hnf_}7NLVC2PQ=5@JSt%5@)J#6UkDq%sNzZ!1m#fQ$07-Ctc_;=HYl?5Tfg} zM_5I&$&lx}NXwm1Z9HPE2P}%){3i;F@-#1Sxe)azK$T~n%aMa84A~qyo33junjp%P ze0-8(i{rVX)VhPp{%g3M=CWnc9aO!qz7x^qHC@ zjICGU{EL;hP9Dc}i|DV7gpvUka!%kLS z=*X@TdnT2IljgOmDNb&hz@F%EeaDTS2Np#S9V{AtTwMH#NBiyuKWpa3Gg_NJD6KLJ zQlHqEykN?Q8O%)Yd7Asg_&oR&xLGA+9;Z0<98?hI5@1oDdQ#zJ!oo@ki=(X9&)Hb8 zau#Sws^|nYG|y#GW|gz#cx7Yse6~bTfUgG20=cOg8j^D)c=|l_x3y2!(3s237^P8h zNiA^#MoOJ}8=i7L6qFF>E}o&!<7I#e~lqX?&H} zTLK&uBy4mfSLof-5;)`9*x}`EXJM!I zl@pBz8#LCLv-IRS_%ALDJ|sBv;R1z%Ju-S~xoyhA7k^(4VPWpKkmxwL;I>5!|)F60p;^PBCOb;%s_di^A@Cr|pf|O8!4RcRT9`g?u z$MOz^1&g$g3TQQ6nq5)P6u{NQp&dhJnA7)4%*t6vQYE~vkg-n4^ufsaIp^zi@KucOdM`4y* znsep#76k{Dug>jlo$N&mKglcK6KJ0JbW);+h1W5t=_v}%CE|%1Br?k968*XnYMfkU~P`#$+D3@(2(>{yK(xxSU&B8 zg@>OjurRg%sbFeu2(#cRkYZ?QzsKRi>aWoB^1%&-jczw)yjuAod41vuNuhPW5*L^W za=1_M5w20uG1W-tkys}?|Bt?R0@di zY2Bm9#PPs|wY}2dMD9Wh%Lgq5Hiex6sunIRj1qbeD^!@d3Z46wD)P)(cucEFz<^RBn#A-uc)diI`0u? zOlE1E&0*lg)NCWjnq<($nsD5v>Gq)p0bfUr7mWuiI1gqs1iKt%Kk74oEt{X~-Bwoi z0|6TDf3?IPzx)#D=pZbR$)cbx`ceI+t(H7~f>uKP>=T71w% zka^v~#OtjW^d0=!tV$mVp5yF$Fo*Sr;Nf@t3vBe)*sa)IVHdNbO`J^!T*_w|IXgzI;eK%PxJN?4)%QFM@s&J+&9)C4xE%vMb|}h7Jc)Uj5X$<% zA}8};f)hu0lfa7)D<-fucb*L4Gy60-f#8dI-BwJl z{zBnP*%)!}6y!ljhX z{6b^)>y@3E6Mr~!7)Ts#GSoCUz~v!Q(Zp=b^kDW8VHQW%cN~I_hZAfB9X>6v?Ag(O zF=|%j6j3IYJ^Y>j@0kgAIJGc4T3_UrU9e;`7f(wum&6es9+p+5PZab-zOiUBCHN#T z8?R_**PNii&1BG1dqze=pz->Ih4VTB9wvmwXjVBLOmTE{bl^{4BGNXoaPmQp&x|~L z?(zjOLOdc?7mXC0EG)lxDR?N^NDAKJlUNk6(@98dnZ*JLkwtov{aw*Z`xy`HIuJ2o zp?{*oA;p<8!v3F}Oe-vsjH^2jaa33=e8*;_J?DcXoAsp!AKcjeEVVe6EE3Samtna< zOwo+LxN(x$Ck0V;0VjRV0}Dc~7=8R8aq)$F=!eI1Itl{B869F63q7AYKTW>;aE*v- zV}csbJfVgQ7vgLc(!{x%R^Jn8W??++-s05qU}fVCdnL^<2ivfXm)_s^Ht}1-%<%o& zC5@DNb`kEN#_u)!KlVsmn)EW^K>~Zr!pH0?_I~UO#5=z4`N$z6e2yVO(Dua+lRpXP z6I!3&<6&g@;m5_6G1cNgjUw~J$X8Xjgyyp{99%BJBw(tMllEZ-51)lc@4<(?Zp#}R zxE}{OsK_yQFbY(k7x%ZBYVm+W;b{f8her{In!qQH*=Lw-6&2noG>FV`QDS}I$~2Mj zNIxelM|1B)K{a+s7t@0RODeewIe6Nu+ckVr4H6!%?2?P@gwN=!L}%i7;~|B2rhFI;W&}7^}J!ybFPL39tuIJ z1rHKrw5%pC3*=TXZ}g~IKSSvB)ug2%+*52m_cb$!wgxf15MkJ7;V|FF)3Tr;{=bt!gAMaT9!d4qS64YDk2APd)HAt-f0(kzEi}MF zK}%my-o|>zp>>U>9gWQj+-wKfJijgO{1z09!^kIk`gsBSWw(Q-C;%fyy_+mZL0?@+=2%` z99$R2^3dtwjtx=*85Rc?2pnAS-B#e44SUjYhL0VOjhj3V__B5QyZZC7Xi>J=r`e3}IUFWxJ`y~~dcZdBab}rf>+(6SjY)coIN6eI zWDmp%e)(o2QT)=s768@JZ{L z3t9&p3OP)8nEF{33N?4|buq*x#8|9RWo9vuY-NZlG2%$yp~UVW*P+m{FjY&S$$8I& zrh^4p_YA6MHi+v-Uj=$q9#@S&V1saqkq^eu=HnWI{*soDWWU?jEW^ zJ@+J=g)A%U%V=vkRYD0Qzenh;L!5r z3QbSG=khpd3A|V2WlIsTo7Yh-#3;4kVTGg89!1f6JWmtNc;=>8YG|he7&(qAz=sd^Fjp@Rn9de8r7yJx44#drwx&EbH2cRb&l#Rg=2SSvVAjkr-_MHY z^zlbdTZ4)fzTXn-_;5HzcA1%dqk$Ilhq%?RnijN*KH9ObDOJ8dM2f?qK{Yh_=aPS2 zEC0`D|DemtAjK1B+x2nUj@-ZrO#%<(*cLQ!2}*U=t$L|2N#MX&A@BDsS@u8V0yh5r zs3*hn`2R8CX338ktNY~}Eu@&PD7@!(i$B2@pvfkt$|lpyZRyPThjqj6gjqM#Zr3{; zFwEGrA~t@3kznfax$*};-&V0Sv{`I_Hb(YiLWn8rfy=vpZG7`5PPO6}ON8}>E7=$P z!@D>$(tYROGJYu0%(CCGR7O1WR{it#2eJ#~>b3J0X&NqL7-ilvco8EM!%kdv?RnKUvF)o-Ct)aR{v~6zn!H<_8ua&rH^ql>o zLieM9J1=yj{e-s|TW}uxs=*OdH&5P|`?T}q$I8=P``I4_Ogosl;GB_mGoA@_onormMdS_Hi*@Ek4!QaI&0X_f#gv`j!c8vHE}C`|h_| z#eBeF8jp%**!l+_+(Ep&o^MA$a0EPdIKX#mvKl$}f zQ2GnOIUFStH9V@vjx;14IJ5tOj6g#FtHv+oEDq=5j~ovC!!Dq$z+R!)sqkR~=R=Nv zoXR)YnstM?vP@VQ|8f-Yx^M8W{OD27H(TW0q2m>mPZ!+DSi|3#AgA)fR zZawgiIsesem-?9(rGJ-73QXf-`rkBR&xdJiYJb`-3pRP(|Dd+{fJ2%9Ba32Z@*nyB ztN+w1%#ZZVV{d4<;-wd$^1IhYLa{}G>&MhwGxkqX{11369NGS#zViRo!H@rcfBg7^ z?R)U7@6D=ZbJ=VTxC%ZJV*>$FaB{U*dE!%`}Fh!JOBR)#s9KaD(bOv{C=cAix6tw^Ii?jw|Jve@ zw||gRtdI*YdGlk6YO`MTgVIU`L#eH19J?m`T*=>D!8=Rbi+yT_#D~K#_BDim$r8HB z`r7R6)p^|QNgTEX@AReB**}%~uM?Z`;s3mqi+N|ynq#E5=B;kw_vWO7lXg$#Y)4#R;*frhZI+_vB`rdBI z??Y8#V*8(;f3{BNLs77lrl`#eJyAKaJtf*~h6lFIllM8fd?L?}&&z%HXPRnCU4Ad` z)8eq=sz5+bg$P^19?umm_qKRFCRYGQ+n^xNuQtlNjZ5gh;ejCGn-{4ZB$@v z-xMbomet^z()0Ly!v$_jPo2ss(?41-3gNThP;;NibVB0AEoH9rj}xuu$+69eJ(9fh z_WFE2o_@A;t*~W{35u?ZznX|LIE3ALFWb|ynElrOH>J<6T7s|t zC*|Z1hD7dm2-fgiyFtdZpQqX2kBN-up>Sa~#}8>bQm#DnRV?fpcvu$9-N)fLRjy+C zvj*MAzZ5DAB>0&7rXTv66ks@^M*rWRo7?xiV+e4x_5O3QUiiww)wjXk{6>lS_3@_GeJvy6S?gUqF;ZZka8 zUT|OqPy2#H?(L6^7HS_j;K8(inPbC?|9cN5iCq_O{vqIKFfESPWuXo)f4Af31)P86 zJ5>)HGFq>)>fq-Eyn3zQ%wk`$oPKb?Q;$XRp^Ren1D`tGaJ$`q6FL4dbUYMr3W(uQ zD~UP)9-_<6m>Zu2t68{zZ!I=GlUX@D!2Id08 zifQZr>xV6kkaJig5&g$u)@nAfS*!>2B8!ZkmjB~kV0fUGd(v;0@;c`?8`*R4p_0LZ%A=a27ff#6yW~)1zW$aRn{qhw#dk)v2Of!iR(IUFqxHG- z170V!3>Mj48*&`v-SV0WkLG@TE7ayF;#S?ySao6L8zbq7bKK$;a>UgIt=X=M2sI^~ zeY7yN%7gntfOVX-+^O@+H4mJ9C(G0P;_G=AzKRU(3Kv**#E7ydF5H})VCQ|TnenB=rofdKSD$D%lVV&a)Y*10uQ~Z)DdXb8yV1>3 z!gA}_o3+osKep(?nGd@Y8PZh6LfKi~XK``M=^9mT-^?e(mm$o_W@GtC(K$jwjEmu0 zxRqePvWba=g_{*;(}EzG2YV&k4-1H|Y-(J3;YY{Y3mhh1p9M3Iw=;9PDm$-IR+u7W zBj4eiD6vB3d-KoRExE#b9HjO>Sht0t(IV~BL*e`WvW!N{f7NWc=wPVN+r*jADs-kH zO6y^3fj7@#&UlW)2B}s}9)`!8GT$$F%+If^c)azzso3RZhYhX?o;#ydeQ4o@7lsE5 zS2@35SouQG@K&OS;pKk5bcgs}xsL%U#&Rlrtb0;88az~4Z&)zgcqz*_g~^G@ppGkj zE}I2U;o${35Ayc2*_X_iAj@!alkkHXd@2VI96We|bsf{L3N0JPUVEp!9g++aPpoTK zNqCTXaH0c8yPXl!3;Bft7fxt9y*rec(qocgQemON!Ze8?#@I}M`Mg?AcfUD|?}hxj z9V#C@iqx3;Uc-9^5(=_U5vda7wAZL9r@noY~I$Ww}d@Px_gI#xQ+D8 z`E%5HP90n(_qifO_VA1IVyx?zw=10$v3+o=L|DL9G}XmuqQZt0L-w2RITjT5?eNeM zd-zSEAVu5uj9~L3sVMXtA3M4Z z&k(7Zpr@pl6JWyb;Ckjm7mK4qnNxy1yN#wKXWOHqtG~p$8NO(2WlnQ*KgND};^jGl zA7-B7cQ0|UNQhyaTXu(ey|jx-f(~z!vY+^ThaVbK6XdJ*O%+sA65jJjsMRTbj^l+m z?(4mbf{oe7QdP8kJ~;85V|Dcv7HxKQkE?Q2R_~gZkg!9$mv>oG8(?iX-q zTG+6~n8l$$ze-_FBg=u7FEcbW7%L(k8m@T4ZqzkH*-Uc60TI>r_Mc`KFMQ6H%)!m5 z)#`66lCYrV97{t;yLW>|Ctv5m3Fnx1naS9MsEEp>l$5eNb>$}eFF*K2OKKJ44foP@ z-Ek#?jAr*F<(OxxSoB0M7WCj~5uEp71LupaPabgQT=I7FV{MK3;34Z+!N+{$K!+2L zqw(JA!w(8pcyJ$4KgpP3d`Z~fki|~GCPXCA=}*(sTMs{!Sh^g4nCo+HP>Sd%W8B)6pU=d*`?-N@uhU6Xtg}sE!~uSJNZU&Vc*Y!)>?oo#d9i#bM~t1U_Cmtha|n9=$4K*8B-{(?nJR|@@$ z&h@(Sb1}DBNU@7-(c))X62KeC`as35F+peF2Q3ZmWkF8m%`Y^5etz35Z^P!6Z^y%K zWURhNVx5yL8z0BKn~5I|C?q_Hv14>n4lLM{rN!Q$mE4?sbnQIWCIh~O0xm{Eea#k; zH#{>`<%>48Mrd(4Cv-Vkh`b2zI_yxqd#N8s%K;g2<^?ly8b3Z(Sf!wvzp&kBBAb}# z(t`m3Y{oqd5#o{(J+1HA1Uu9!0$7ilI0{!x;^Yaa;I8yhQ9WN_!|*^aqvVCI3e%Gu z5r#ct3|}0Bg&9sL2EU)*?zzB3VCAK}qj&vy7lg5O&1el9QVo8s8Q8KHzW(^vTd# z=l6Y@z|o}51__%OH{X*Nbc*o#^5ozOi?ANn^DGYUT^%-v*cu*R@uJ|PK@hXk3s+rv ze&)7q`rIqd+;EnX{VDK6B!o{<l}h+dU+KKv>2TPuPk9vXlUOu!$HN7 zS$u-u=f$k7jvEpKxDN-2YV2#%cV)~7@H}$3|2q;pm>q1qr^s`dEEix5O^2}Ocb`uvQbVzjy@Ec8WVq@rF zZ(oq#@nTEa;+ZRBVK9v+j;(QO zGe7%+Wy~*pn^_bZ7_WGIxW&zVx@CURX^dnth|pDaj8!90dXn4;(`{9Qp5bJ?Q=H_0Mj>IX3;p5BTI)J&@6F zGHhsJd=%mM<&NiY<~?U;1zyjMA;}aTT~Ap{vf)5IfI`N%1@<%ag~A zF{W$}rf`4wFk`}!6f^O5=Q%0GJ2q^&#Ut)4rO9|+WvjbtWAgDUW)qZHo;-I_Z*LNh zz9Y(gO7i7F1I-H_A=>UPN+Jn6&GlHf?|tx#yQy*GTbA~nj~{xy=Zf&tG2)fx zHHC>6yfPCPA4(Kn>L=3XJR`*1rY0vYh3RbHQcFJOOFME79DQ)XGG0;eV()|X;(Ky* zPqQ8|38^VLb7^5L%bG`p{!9yMjK#Xx-pt}Y56x~CWQo4itmh)ZpOC_{bWQ-1frfxZ*2HGslU#>4cC36Pp_*`guYiYy zCre`H^+!zMtqgkn74?i7>I}O-r0v(%=`H*(ba2+E_m680tZn44vMBxM6ss0)7HDRu zu;KrswO_rnwubrORQ`X9G7U6dE$e0KU~>NHwBVLNOXF*Y!#?xc7%UVx6>gtxKe$Cg z#3|rw#LK%EtP*$j@jr;taQ?v_^o&7)x%&{;4xXbY&Oe9|aAc8c5opdZtEvq87MNkQ zP^b25eM7DPfmwUlPyc@-qT9FY)k^E*AGl{2IAp1^7_@81ww{RNS>wr}Rk_1ORXqMc z+OPTXuOENY_Urs5$^RgV<#FfJEN6SI8S|T-x_)amyxve?@HKwt*RW*usmu@lzjvSd z_=k=#v)M z6m=2(_u@bHxb1SOJ>0MEb(4a7^*y;Dr4;tPVoetxK9Tyi%%`x3_0Gp9 z7CrA64`!cUnCiBD&WkoL<~uc}&RmX8RTjq$^+?u7X z{vbrcCeq^3%Ak`6OJz%WIc~Q_)wa$@r%LY310k-k3AH5E`DFwb1313Ggp1PoE7ucLtC4f)h{(3 zJlO4Q%qF>Kot z#HE8v`FS}HS`-VZ8$I}#r>|%|VO}N8Ce@bZQn}z@#+R!hIsZ5r9Hxsl%Y?;W4b#_dVwkc{ zyJ%LC`@h-p2ZA^fA8d@UVPRWvctQJrRW@&~P@wu)>US#R(T40mqi654n0*i>C=WYDO*1)wZz@KanAS@a?7*Y_iSLa&8;H zMwkkT9?wnerwH*2^_9RpRu&Y{cm@i(@~Va&$6jyMbB3ag+AjOk&m^Z$v*T}K+-Li$Gc-2g zhyAPvZ7Tg!n6(ypOj#qnPygGa`)mvo_4BIVZkEOep3HZB=Gb?|>EVVeF{1t#JT(sZEWF(O;BiaCtnXV+F>_Ve z@fG;2_#w9F;EbmaPFO5iwD`fncN|Wq)O0T$V)W<``Ea4cqVtt_RsVvhMSV;hZk@qK znNJT`Ma=h@BqQ2(@V;aQOB>s{o?iw(RKGD@sAcb4`s1m@qJ?h$mm_*bB=-C;C{a!G zX3VU(@7mDiA<6gD_vkL2=7|$_Xe=*b>}U3sxKPY_zU|u@Sfg$tCpuw1 z>u%12)rSP$SXXXzwqBiN)@si#Wy0Dt-`1bMElugEij6i)%CmOgHUAf62(vfFZPDYl z0LiK~1RQrLV5EfGgj-sLoTWU0&`JIEE6MELmx-(c*SnoV|TCYat!H*bu zKRw<6h)XW)i3<2WhoW7LFFQ+QjvX|9{ZvH-fWM#CQN+O&|D-c(8{`2p3j-R zzj@-_yJiqaO~8HC)D__ijy3M%SsTM}!N&H(+wkQXyTs#bYCk@l_~ws(`{5r#Ob;qJgb#ww zHu<60@BZ}v*~<;!jb(>FwD71_hib_^XDb_?u@0!Tq zw!`sj7R%OyZHs>}Kk$<|aAl7i^REvHyc{NcRY!em+-2smEedbqnEX}s`|qj}4>rB< zpFh{LH~gEzJXPygdW)cT=z+lL{h3-zD^|FLRMay~P+`81`oI0wGS=;%6W@l;-NV(y zFl}9Y(H7$+>)9Weh;j;u#0N%yc(K^OX=2PD;moqXLEYD)&3Mlr&SU@J!+E5E>z|OR z!iGH}_D>9J9zXtdK$vl(K5z2@hig144GHX>T#ftgU*%N35IUcYRpO@~f08(h;18z{ ze-yN3O?9WWwjTbdA!6Jn+TZ>~^1we0(DtJ~9>xQQU-7X2Kl3xY;Q7^E4dn}_@Vabu z_;LSF|G{P}_J&VOlJ2kmx3}?vkrS&^j0i&mn_`q37xMx>CzU;FX451Nu$!9miA-zB z=W0uk;W`+(WG>%{OP<4HYXkY{`)7aeiUyDA3=*klv^u z+F<(l;oV33F18+Ih~q2x5mD89R79}fh;K=+SZUd>j~_lAJ9b0)Wvb!}9oEBr=giG7 zcvSq*$ZUSYdO-E7LYQppgB{wPNAtEHZCu7K0^ewCoTGQzW(C#-$^lCQYo z$)N|6T^tu5J{0S5AnqYc&c_3l7m|czm~LE=@tMkc@F45b##r79Hj0c6Iu(Dcnidpz zIn-DP+Zb@keOM5fpm&L#jYGjWe5Mmmig9I-)2BHcCzA6jPVg^`bFyz{TChae`Lg4# zwT#*SB*l+L`(H{pW8Y`B@T)+yNQJko)|C^k^{B4wH?91Hvhr8jS7mr=Y z67NigOD(F-XaAhF;%8>K-@SLU#M1T#%c%YRIsG#aS+D1RaAC!tJyHx6&KL4NnjcMA zz`~j}>-^jhfvKyz8e8gnGc?@)Wf-6GyWRf5hOMbpXljjT?`rV`g`2*IK0Q8q_|eO) zo;KEg%s-;mUf6wwX;oieuZ+cq5YY()SvYPAfaWKEe0VEpM1 zd=8xK4UIl^ypD}L`yc<}>0Xi)SXuGOpJU5`X{!%kwO`i$ae*7x!3PSlYN91QXsgH?Taj-P65*+Jn|0LlSLDlf6$Blm( z9n~L2$g#=yzpDPn{P_R3c=wVt4zBjc7uwdp?25gV-yiZ)BF)LTs)>`~iufW%5f{#t z%nwvmIBia7pHpGGQOJHEWP*5RgmQ%id*Y_Y3SYu_86IpZ>^fBVBT-#!zTd5+gfEAW zG?*-!`Z%G4dqz%)PsqVfDaz01iSfxg7B2k2E8y68h|NY>vejS0jcak&J)>!-j0Kp| z=S#e2%$lnxeME8M!A%NZ7hU$`Z#$5+ZjP?UWkt)cEDP2=49H-z$XM09tHO?jlj)7U zDDSZ-KAlQ~gj!ApZQ)7sEn-}krrWh26%A<{j z2^?c6}a9iXJ{%9jS>H zH_!7g_$occ$WWrGGE4cq8Rx|lhhA9A7-Y_3YrK-6r=$2mQ|C^Mk3~CwI7^XM2(yeC zJ1^Ii73_0a8#m}!CG+&`+a0UoVI#c6)LFqHicd|n<>0NZMv;yq7j`}p&}!kW2w`R_ z%}Nv)r#$)Wr(^Vfra;X;iq>zOqc)J7OP9CKOFv}Ol?zxQqi z9ZCPjDW5|);{-1^=AC+w>ikjrAG4Do`=SIBN$qpDza2Kd!n0EUmr>!P4QG`P8~k8p zI#K@WxuojhuIj~sf4CY8wAedcpMHxM{O{lCApb`Gr+Y-qd4unJcYnF^RgC$=!uPjI zyx6V=80+1{+9Mtg~QⓈ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
    (avS+4kR1 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%0AD9~( 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
    pyIZ3%+v0dft9E zwW8Jj;@YPb7o3T=;N!VC_ppPg>GD1K?1si}lRrF@>g%>K7C$j}Yqi0finJ4HlKpN= z&Pp1+l=)OqtPw2t;N-&-SzI1JBtHE9cb&~~MTFSV_Z&(78;pxWCM^9W(314`6vqPY zM=FdR2?z4HC!bv4qT=wZ#cA0&udtG(B@a?HPcm_SJ0_d!c-k^cQw;n#OKT3_Gm>z?vN!D-%! zgAPt#(!iVCc%%24F&cQxJ(sXmL%^bpyFDRA+(q@yvN?i`Cl1YE-=KSl;r#nr%|(|A zr*!<;qIcNb#+$vHc~!!^8S*DIT2J}zFzVykmmq%jaBJBto6iR|TB}cMb46F6-?)$!f` z@u8mUu*}D$Y$y9Q=CTzXoUzZ`Qo+JT@~~CHhi_gVg$`f%Qjj7!|A35$tt_+hg#&5& z%|De3Cd71nF*^9Xb+Kt)@tQZnOMZw5yl}V~)LXUuBCo&(MHa`CFO8QLtIWU1s=?9Z z;ydl)XSaZ~{d<9t?+Hx?d>%imS$b6$EW%=AK_W7WL&Ez?@p(=MMoQ4_k3JDh;p8K#en8n_}a4xUFq%%B*N1xn zZ+`yJEt688D9qsWM83_v@WD5G8%c(c@CwN~Nq%?6C7+j=zPP+b?I1_V{I&%re9R`? zJg`9BNVKIXjGsfTLq(F@Zqc?4aR<&i{OIev%w+WY zd_U^~O~-)8wgvx+_*oyG_&1ATuIXC49dYcpM68l5eomN_&}I8*Wv|u+&i-{AYPt8K z*!I5nIN&u+pT$@paCKsP^UfxPlkew!J-jMTapEP3jFbw?nX4xr|5WMJ-j@79fj8pL zKUq5^=Z1fFX8X;)U;jJ#on(jHI*aPB2hSX}eEucwdsJ7>}TXg4-W~j__UG z;!nkd4JU)J8^gwR7f|v)Kq+Y!2{5%HdH;kEl zi4L-yw#jtJZL0u7Z1=5J2;vT^Arh7}49-DW94iERZ|!I` zUv!a4D`3%s11YSE!YRwO*>5cW!=jn)FnvkNP(46@rP2hxHMUb-BJ01~>=EE#X z0-DSfU#olAWZ&?daFAk?Q)YgU?Kbz|tZj;68G@bCmWO^kkiVtMbH1vraK*e?%g#Sg zVE^*gj?sOJteu^pqRYYem-G3baPt3LaKiYq&pin%``Kb{bv%o&Hn`gGw=(#jpWML3 z7CNKWpu?^6;x-rc^GrMPM70#>?|6JjVCLpSf|K1>$UTsMyU<~2gFd5$eZu!Wp#F!> z1P5q z1Wa6$T70AzwKi%9+6@3>e_+*?rX5IMulwTLz4 zZZ%7wbSq=Cdn?nEcA=SqySz-fD`KRgc!swziR0{vjV*3pW*T^XNoX;x zd*CFrzQ`g@diT{Vwvfm3I>HtvN;kGl)pQZPx~Sp6NzKKb3O<_eIh+ZycB45PODUfq@G9!dZN0ngj#{SRY?J)ZlmVk-)OAlP?Aw5a^g;qc{U} zke<-u>}+Ac?q3jfgHe{eYA$5aaslYplyp>kf|3YBhu{ }-`ZbF{Tp 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 A*8l(j literal 0 HcmV?d00001 diff --git a/mpeg4/src/COPYING b/mpeg4/src/COPYING new file mode 100644 index 00000000..1e099144 --- /dev/null +++ b/mpeg4/src/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/mpeg4/src/CREDITS b/mpeg4/src/CREDITS new file mode 100644 index 00000000..b937f7a3 --- /dev/null +++ b/mpeg4/src/CREDITS @@ -0,0 +1,45 @@ +This file contains the name of the people who have contributed to +FFmpeg. The names are sorted alphabetically by last name. + +Michel Bardiaux +Fabrice Bellard +Patrice Bensoussan +Alex Beregszaszi +BERO +Mario Brito +Ronald Bultje +Maarten Daniels +Reimar Doeffinger +Tim Ferguson +Brian Foley +Arpad Gereoffy +Philip Gladstone +Vladimir Gneushev +Roine Gustafsson +David Hammerton +Wolfgang Hesseler +Falk Hueffner +Steven Johnson +Zdenek Kabelac +Robin Kay +Todd Kirby +Nick Kurshev +Benjamin Larsson +Loïc Le Loarer +Daniel Maas +Mike Melanson +Loren Merritt +Jeff Muizelaar +Michael Niedermayer +François Revol +Peter Ross +MÃ¥ns RullgÃ¥rd +Roman Shaposhnik +Dieter Shirley +Konstantin Shishkov +Juan J. Sierralta +Ewald Snel +Sascha Sommer +Leon van Stuivenberg +Roberto Togni +Lionel Ulmer diff --git a/mpeg4/src/Changelog b/mpeg4/src/Changelog new file mode 100644 index 00000000..b9ef5efc --- /dev/null +++ b/mpeg4/src/Changelog @@ -0,0 +1,368 @@ +version +- DV50 AKA DVCPRO50 encoder, decoder, muxer and demuxer +- TechSmith Camtasia (TSCC) video decoder +- IBM Ultimotion (ULTI) video decoder +- Sierra Online audio file demuxer and decoder +- Apple QuickDraw (qdrw) video decoder +- Creative ADPCM audio decoder (16 bits as well as 8 bits schemes) +- Electronic Arts Multimedia (WVE/UV2/etc.) file demuxer +- Miro VideoXL (VIXL) video decoder +- H.261 video encoder +- QPEG video decoder +- Nullsoft Video (NSV) file demuxer +- Shorten audio decoder +- LOCO video decoder +- Apple Lossless Audio Codec (ALAC) decoder +- Winnov WNV1 video decoder +- Autodesk Animator Studio Codec (AASC) decoder +- Indeo 2 video decoder +- Fraps FPS1 video decoder +- Snow video encoder/decoder +- Sonic audio encoder/decoder +- Vorbis audio decoder +- Macromedia ADPCM decoder +- Duck TrueMotion 2 video decoder +- support for decoding FLX and DTA extensions in FLIC files +- H.264 custom quantization matrices support +- ffserver fixed, it should now be usable again +- QDM2 audio decoder +- Real Cooker audio decoder +- TrueSpeech audio decoder +- WMA2 audio decoder fixed, now all files should play correctly +- RealAudio 14.4 and 28.8 decoders fixed +- JPEG-LS encoder and decoder +- CamStudio video decoder +- build system improvements +- tabs and trailing whitespace removed from the codebase +- AIFF/AIFF-C audio format, encoding and decoding +- ADTS AAC file reading and writing +- Creative VOC file reading and writing +- American Laser Games multimedia (*.mm) playback system +- Zip Blocks Motion Video decoder +- Improved Theora/VP3 decoder +- True Audio (TTA) decoder +- AVS demuxer and video decoder +- Smacker demuxer and decoder +- NuppelVideo/MythTV demuxer and RTjpeg decoder +- KMVC decoder + +version 0.4.9-pre1: + +- DV encoder, DV muxer +- Microsoft RLE video decoder +- Microsoft Video-1 decoder +- Apple Animation (RLE) decoder +- Apple Graphics (SMC) decoder +- Apple Video (RPZA) decoder +- Cinepak decoder +- Sega FILM (CPK) file demuxer +- Westwood multimedia support (VQA & AUD files) +- Id Quake II CIN playback support +- 8BPS video decoder +- FLIC playback support +- RealVideo 2.0 (RV20) decoder +- Duck TrueMotion v1 (DUCK) video decoder +- Sierra VMD demuxer and video decoder +- MSZH and ZLIB decoder support +- SVQ1 video encoder +- AMR-WB support +- PPC optimizations +- rate distortion optimal cbp support +- rate distorted optimal ac prediction for MPEG-4 +- rate distorted optimal lambda->qp support +- AAC encoding with libfaac +- Sunplus JPEG codec (SP5X) support +- use Lagrange multipler instead of QP for ratecontrol +- Theora/VP3 decoding support +- XA and ADX ADPCM codecs +- export MPEG-2 active display area / pan scan +- Add support for configuring with IBM XLC +- floating point AAN DCT +- initial support for zygo video (not complete) +- RGB ffv1 support +- new audio/video parser API +- av_log() system +- av_read_frame() and av_seek_frame() support +- missing last frame fixes +- seek by mouse in ffplay +- noise reduction of DCT coefficients +- H.263 OBMC & 4MV support +- H.263 alternative inter vlc support +- H.263 loop filter +- H.263 slice structured mode +- interlaced DCT support for MPEG-2 encoding +- stuffing to stay above min_bitrate +- MB type & QP visualization +- frame stepping for ffplay +- interlaced motion estimation +- alternate scantable support +- SVCD scan offset support +- closed GOP support +- SSE2 FDCT +- quantizer noise shaping +- G.726 ADPCM audio codec +- MS ADPCM encoding +- multithreaded/SMP motion estimation +- multithreaded/SMP encoding for MPEG-1/MPEG-2/MPEG-4/H.263 +- multithreaded/SMP decoding for MPEG-2 +- FLAC decoder +- Metrowerks CodeWarrior suppport +- H.263+ custom pcf support +- nicer output for 'ffmpeg -formats' +- Matroska demuxer +- SGI image format, encoding and decoding +- H.264 loop filter support +- H.264 CABAC support +- nicer looking arrows for the motion vector vissualization +- improved VCD support +- audio timestamp drift compensation +- MPEG-2 YUV 422/444 support +- polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample +- better image scaling +- H.261 support +- correctly interleave packets during encoding +- VIS optimized motion compensation +- intra_dc_precision>0 encoding support +- support reuse of motion vectors/MB types/field select values of the source video +- more accurate deblock filter +- padding support +- many optimizations and bugfixes + +version 0.4.8: + +- MPEG-2 video encoding (Michael) +- Id RoQ playback subsystem (Mike Melanson and Tim Ferguson) +- Wing Commander III Movie (.mve) file playback subsystem (Mike Melanson + and Mario Brito) +- Xan DPCM audio decoder (Mario Brito) +- Interplay MVE playback subsystem (Mike Melanson) +- Duck DK3 and DK4 ADPCM audio decoders (Mike Melanson) + +version 0.4.7: + +- RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, code from mplayerhq + (originally from public domain player for Amiga at http://www.honeypot.net/audio) +- current version now also compiles with older GCC (Fabrice) +- 4X multimedia playback system including 4xm file demuxer (Mike + Melanson), and 4X video and audio codecs (Michael) +- Creative YUV (CYUV) decoder (Mike Melanson) +- FFV1 codec (our very simple lossless intra only codec, compresses much better + than HuffYUV) (Michael) +- ASV1 (Asus), H.264, Intel indeo3 codecs have been added (various) +- tiny PNG encoder and decoder, tiny GIF decoder, PAM decoder (PPM with + alpha support), JPEG YUV colorspace support. (Fabrice Bellard) +- ffplay has been replaced with a newer version which uses SDL (optionally) + for multiplatform support (Fabrice) +- Sorenson Version 3 codec (SVQ3) support has been added (decoding only) - donated + by anonymous +- AMR format has been added (Johannes Carlsson) +- 3GP support has been added (Johannes Carlsson) +- VP3 codec has been added (Mike Melanson) +- more MPEG-1/2 fixes +- better multiplatform support, MS Visual Studio fixes (various) +- AltiVec optimizations (Magnus Damn and others) +- SH4 processor support has been added (BERO) +- new public interfaces (avcodec_get_pix_fmt) (Roman Shaposhnick) +- VOB streaming support (Brian Foley) +- better MP3 autodetection (Andriy Rysin) +- qpel encoding (Michael) +- 4mv+b frames encoding finally fixed (Michael) +- chroma ME (Michael) +- 5 comparison functions for ME (Michael) +- B-frame encoding speedup (Michael) +- WMV2 codec (unfinished - Michael) +- user specified diamond size for EPZS (Michael) +- Playstation STR playback subsystem, still experimental (Mike and Michael) +- ASV2 codec (Michael) +- CLJR decoder (Alex) + +.. And lots more new enhancements and fixes. + +version 0.4.6: + +- completely new integer only MPEG audio layer 1/2/3 decoder rewritten + from scratch +- Recoded DCT and motion vector search with gcc (no longer depends on nasm) +- fix quantization bug in AC3 encoder +- added PCM codecs and format. Corrected WAV/AVI/ASF PCM issues +- added prototype ffplay program +- added GOB header parsing on H.263/H.263+ decoder (Juanjo) +- bug fix on MCBPC tables of H.263 (Juanjo) +- bug fix on DC coefficients of H.263 (Juanjo) +- added Advanced Prediction Mode on H.263/H.263+ decoder (Juanjo) +- now we can decode H.263 streams found in QuickTime files (Juanjo) +- now we can decode H.263 streams found in VIVO v1 files(Juanjo) +- preliminary RTP "friendly" mode for H.263/H.263+ coding. (Juanjo) +- added GOB header for H.263/H.263+ coding on RTP mode (Juanjo) +- now H.263 picture size is returned on the first decoded frame (Juanjo) +- added first regression tests +- added MPEG-2 TS demuxer +- new demux API for libav +- more accurate and faster IDCT (Michael) +- faster and entropy-controlled motion search (Michael) +- two pass video encoding (Michael) +- new video rate control (Michael) +- added MSMPEG4V1, MSMPEGV2 and WMV1 support (Michael) +- great performance improvement of video encoders and decoders (Michael) +- new and faster bit readers and vlc parsers (Michael) +- high quality encoding mode: tries all macroblock/VLC types (Michael) +- added DV video decoder +- preliminary RTP/RTSP support in ffserver and libavformat +- H.263+ AIC decoding/encoding support (Juanjo) +- VCD MPEG-PS mode (Juanjo) +- PSNR stuff (Juanjo) +- simple stats output (Juanjo) +- 16-bit and 15-bit RGB/BGR/GBR support (Bisqwit) + +version 0.4.5: + +- some header fixes (Zdenek Kabelac ) +- many MMX optimizations (Nick Kurshev ) +- added configure system (actually a small shell script) +- added MPEG audio layer 1/2/3 decoding using LGPL'ed mpglib by + Michael Hipp (temporary solution - waiting for integer only + decoder) +- fixed VIDIOCSYNC interrupt +- added Intel H.263 decoding support ('I263' AVI fourCC) +- added Real Video 1.0 decoding (needs further testing) +- simplified image formats again. Added PGM format (=grey + pgm). Renamed old PGM to PGMYUV. +- fixed msmpeg4 slice issues (tell me if you still find problems) +- fixed OpenDivX bugs with newer versions (added VOL header decoding) +- added support for MPlayer interface +- added macroblock skip optimization +- added MJPEG decoder +- added mmx/mmxext IDCT from libmpeg2 +- added pgmyuvpipe, ppm, and ppm_pipe formats (original patch by Celer + ) +- added pixel format conversion layer (e.g. for MJPEG or PPM) +- added deinterlacing option +- MPEG-1/2 fixes +- MPEG-4 vol header fixes (Jonathan Marsden ) +- ARM optimizations (Lionel Ulmer ). +- Windows porting of file converter +- added MJPEG raw format (input/ouput) +- added JPEG image format support (input/output) + +version 0.4.4: + +- fixed some std header definitions (Bjorn Lindgren + ). +- added MPEG demuxer (MPEG-1 and 2 compatible). +- added ASF demuxer +- added prototype RM demuxer +- added AC3 decoding (done with libac3 by Aaron Holtzman) +- added decoding codec parameter guessing (.e.g. for MPEG, because the + header does not include them) +- fixed header generation in MPEG-1, AVI and ASF muxer: wmplayer can now + play them (only tested video) +- fixed H.263 white bug +- fixed phase rounding in img resample filter +- add MMX code for polyphase img resample filter +- added CPU autodetection +- added generic title/author/copyright/comment string handling (ASF and RM + use them) +- added SWF demux to extract MP3 track (not usable yet because no MP3 + decoder) +- added fractional frame rate support +- codecs are no longer searched by read_header() (should fix ffserver + segfault) + +version 0.4.3: + +- BGR24 patch (initial patch by Jeroen Vreeken ) +- fixed raw yuv output +- added motion rounding support in MPEG-4 +- fixed motion bug rounding in MSMPEG4 +- added B-frame handling in video core +- added full MPEG-1 decoding support +- added partial (frame only) MPEG-2 support +- changed the FOURCC code for H.263 to "U263" to be able to see the + +AVI/H.263 file with the UB Video H.263+ decoder. MPlayer works with + this +codec ;) (JuanJo). +- Halfpel motion estimation after MB type selection (JuanJo) +- added pgm and .Y.U.V output format +- suppressed 'img:' protocol. Simply use: /tmp/test%d.[pgm|Y] as input or + output. +- added pgmpipe I/O format (original patch from Martin Aumueller + , but changed completely since we use a format + instead of a protocol) + +version 0.4.2: + +- added H.263/MPEG-4/MSMPEG4 decoding support. MPEG-4 decoding support + (for OpenDivX) is almost complete: 8x8 MVs and rounding are + missing. MSMPEG4 support is complete. +- added prototype MPEG-1 decoder. Only I- and P-frames handled yet (it + can decode ffmpeg MPEGs :-)). +- added libavcodec API documentation (see apiexample.c). +- fixed image polyphase bug (the bottom of some images could be + greenish) +- added support for non clipped motion vectors (decoding only) + and image sizes non-multiple of 16 +- added support for AC prediction (decoding only) +- added file overwrite confirmation (can be disabled with -y) +- added custom size picture to H.263 using H.263+ (Juanjo) + +version 0.4.1: + +- added MSMPEG4 (aka DivX) compatible encoder. Changed default codec + of AVI and ASF to DIV3. +- added -me option to set motion estimation method + (default=log). suppressed redundant -hq option. +- added options -acodec and -vcodec to force a given codec (useful for + AVI for example) +- fixed -an option +- improved dct_quantize speed +- factorized some motion estimation code + +version 0.4.0: + +- removing grab code from ffserver and moved it to ffmpeg. Added + multistream support to ffmpeg. +- added timeshifting support for live feeds (option ?date=xxx in the + URL) +- added high quality image resize code with polyphase filter (need + mmx/see optimisation). Enable multiple image size support in ffserver. +- added multi live feed support in ffserver +- suppressed master feature from ffserver (it should be done with an + external program which opens the .ffm url and writes it to another + ffserver) +- added preliminary support for video stream parsing (WAV and AVI half + done). Added proper support for audio/video file conversion in + ffmpeg. +- added preliminary support for video file sending from ffserver +- redesigning I/O subsystem: now using URL based input and output + (see avio.h) +- added WAV format support +- added "tty user interface" to ffmpeg to stop grabbing gracefully +- added MMX/SSE optimizations to SAD (Sums of Absolutes Differences) + (Juan J. Sierralta P. a.k.a. "Juanjo" ) +- added MMX DCT from mpeg2_movie 1.5 (Juanjo) +- added new motion estimation algorithms, log and phods (Juanjo) +- changed directories: libav for format handling, libavcodec for + codecs + +version 0.3.4: + +- added stereo in MPEG audio encoder + +version 0.3.3: + +- added 'high quality' mode which use motion vectors. It can be used in + real time at low resolution. +- fixed rounding problems which caused quality problems at high + bitrates and large GOP size + +version 0.3.2: small fixes + +- ASF fixes +- put_seek bug fix + +version 0.3.1: added avi/divx support + +- added AVI support +- added MPEG-4 codec compatible with OpenDivX. It is based on the H.263 codec +- added sound for flash format (not tested) + +version 0.3: initial public release diff --git a/mpeg4/src/Doxyfile b/mpeg4/src/Doxyfile new file mode 100644 index 00000000..73b4e992 --- /dev/null +++ b/mpeg4/src/Doxyfile @@ -0,0 +1,1038 @@ +# Doxyfile 1.3-rc1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = ffmpeg + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxy + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = . + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consist of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output dir. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non empty doxygen will try to run +# the html help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the Html help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, +# or Internet explorer 4.0+). Note that for large projects the tree generation +# can take a very long time. In such cases it is better to disable this feature. +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = __attribute__(x)="" "RENAME(x)=x ## _TMPL" "DEF(x)=x ## _TMPL" \ + HAVE_BUILTIN_VECTOR HAVE_AV_CONFIG_H HAVE_MMX HAVE_MMX2 HAVE_3DNOW \ + ATTR_ALIGN(x)="" + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +#EXPAND_AS_DEFINED = FF_COMMON_FRAME +EXPAND_AS_DEFINED = declare_idct(idct, table, idct_row_head, idct_row, idct_row_tail, idct_row_mid) + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yield more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermedate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/mpeg4/src/INSTALL b/mpeg4/src/INSTALL new file mode 100644 index 00000000..a636c536 --- /dev/null +++ b/mpeg4/src/INSTALL @@ -0,0 +1,14 @@ + +1) Type './configure' create the configuration (use './configure +--help' to have the configure options). + +'configure' can be launched from another directory than the ffmpeg +sources to put the objects at that place. In that case, use an +absolute path when launching 'configure', +e.g. /ffmpegdir/ffmpeg/configure. + +2) Then type 'make' to build ffmpeg. On BSD systems, type 'gmake' +instead of 'make'. You may need to install GNU make first. + +3) Type 'make install' to install ffmpeg and ffserver in +/usr/local/bin. diff --git a/mpeg4/src/MAINTAINERS b/mpeg4/src/MAINTAINERS new file mode 100644 index 00000000..373c65aa --- /dev/null +++ b/mpeg4/src/MAINTAINERS @@ -0,0 +1,220 @@ +FFmpeg maintainers +================== + +Below is a list of the people maintaining different parts of the +FFmpeg code. + + +Project Leader +============== + +Michael Niedermayer + final design decisions + + +Applications +============ + +ffmpeg: + ffmpeg.c Michael Niedermayer + + Video Hooks: + vhook + vhook/watermark.c Marcus Engene + vhook/ppm.c + vhook/drawtext.c + vhook/fish.c + vhook/null.c + vhook/imlib2.c + +ffplay: + ffplay.c + +ffserver: + ffserver.c, ffserver.h + +Commandline utility code: + cmdutils.c, cmdutils.h + +QuickTime faststart: + qt-faststart.c Mike Melanson + + +Miscellaneous Areas +=================== + +documentation Mike Melanson, Diego Biurrun +website Mike Melanson, Diego Biurrun +build system (configure,Makefiles) Diego Biurrun +project server Diego Biurrun, Mans Rullgard + + +libavutil +========= + +External Interfaces: + libavutil/avutil.h +Internal Interfaces: + libavutil/common.h + +Other: + intfloat* Michael Niedermayer + rational.c, rational.h Michael Niedermayer + mathematics.c, mathematics.h Michael Niedermayer + integer.c, integer.h Michael Niedermayer + bswap.h + + +libavcodec +========== + +Generic Parts: + External Interfaces: + avcodec.h Michael Niedermayer + utility code: + utils.c + mem.c + opt.c, opt.h + arithmetic expression evaluator: + eval.c Michael Niedermayer + audio and video frame extraction: + parser.c + bitsream reading: + bitstream.c, bitstream.h Michael Niedermayer + CABAC: + cabac.h, cabac.c Michael Niedermayer + DSP utilities: + dsputils.c, dsputils.h Michael Niedermayer + entropy coding: + rangecoder.c, rangecoder.h Michael Niedermayer + floating point AAN DCT: + faandct.c, faandct.h Michael Niedermayer + Golomb coding: + golomb.c, golomb.h Michael Niedermayer + motion estimation: + motion* Michael Niedermayer + rate control: + ratecontrol.c + xvid_rc.c Michael Niedermayer + simple IDCT: + simple_idct.c, simple_idct.h Michael Niedermayer + postprocessing: + libpostproc/* Michael Niedermayer + +Codecs: + 4xm.c Michael Niedermayer + 8bps.c Roberto Togni + aasc.c Kostya Shishkov + asv* Michael Niedermayer + bmp.c Mans Rullgard + cinepak.c Roberto Togni + cljr Alex Beregszaszi + cook.c, cookdata.h Benjamin Larsson + cscd.c Reimar Doeffinger + dpcm.c Mike Melanson + dv.c Roman Shaposhnik + ffv1.c Michael Niedermayer + flac.c Alex Beregszaszi + flicvideo.c Mike Melanson + g726.c Roman Shaposhnik + h264* Loren Merritt, Michael Niedermayer + h261* Michael Niedermayer + h263* Michael Niedermayer + huffyuv.c Michael Niedermayer + idcinvideo.c Mike Melanson + indeo2* Kostya Shishkov + interplayvideo.c Mike Melanson + jpeg_ls.c Kostya Shishkov + kmvc.c Kostya Shishkov + lcl.c Roberto Togni + loco.c Kostya Shishkov + lzo.h, lzo.c Reimar Doeffinger + mdec.c Michael Niedermayer + mjpeg.c Michael Niedermayer + mpeg12.c, mpeg12data.h Michael Niedermayer + mpegvideo.c, mpegvideo.h Michael Niedermayer + msmpeg4.c, msmpeg4data.h Michael Niedermayer + msrle.c Mike Melanson + msvideo1.c Mike Melanson + nuv.c Reimar Doeffinger + oggtheora.c Mans Rullgard + qdm2.c, qdm2data.h Roberto Togni + qdrw.c Kostya Shishkov + qpeg.c Kostya Shishkov + qtrle.c Mike Melanson + ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni + resample2.c Michael Niedermayer + rpza.c Roberto Togni + rtjpeg.c, rtjpeg.h Reimar Doeffinger + rv10.c Michael Niedermayer + smc.c Mike Melanson + snow.c Michael Niedermayer, Loren Merritt + sonic.c Alex Beregszaszi + svq3.c Michael Niedermayer + truemotion1* Mike Melanson + truemotion2* Kostya Shishkov + truespeech.c Kostya Shishkov + tscc.c Kostya Shishkov + ulti* Kostya Shishkov + vcr1.c Michael Niedermayer + vp3* Mike Melanson + vqavideo.c Mike Melanson + wmv2.c Michael Niedermayer + wnv1.c Kostya Shishkov + x264.c Mans Rullgard + xan.c Mike Melanson + xl.c Kostya Shishkov + xvmcvideo.c Ivan Kalvachev + zmbv.c Kostya Shishkov + + +libavformat +=========== + +Generic parts: + External Interface: + libavcodec/avcodec.h + Utility Code: + libavcodec/utils.c + + +Muxers/Demuxers: + 4xm.c Mike Melanson + adtsenc.c Mans Rullgard + avi* Michael Niedermayer + crc.c Michael Niedermayer + daud.c Reimar Doeffinger + dc1394.c, dv.c Roman Shaposhnik + flic.c Mike Melanson + flvdec.c, flvenc.c Michael Niedermayer + idcin.c Mike Melanson + idroq.c Mike Melanson + ipmovie.c Mike Melanson + img2.c Michael Niedermayer + mov.c Francois Revol, Michael Niedermayer + mpegts* Mans Rullgard + nsvdec.c Francois Revol + nut.c Alex Beregszaszi + nuv.c Reimar Doeffinger + ogg2.c, ogg2.h Mans Rullgard + oggparsevorbis.c Mans Rullgard + psxstr.c Mike Melanson + raw.c Michael Niedermayer + rm.c Roberto Togni + segafilm.c Mike Melanson + v4l2.c Luca Abeni + voc.c Aurelien Jacobs + wav.c Michael Niedermayer + wc3movie.c Mike Melanson + westwood.c Mike Melanson + + +Operating systems / CPU architectures +===================================== + +Alpha Mans Rullgard, Falk Hueffner +BeOS Francois Revol +i386 Michael Niedermayer +Mac OS X / PowerPC Romain Dolbeau +Amiga / PowerPC Colin Ward +Linux / PowerPC Luca Barbato diff --git a/mpeg4/src/Makefile b/mpeg4/src/Makefile new file mode 100644 index 00000000..4e91630c --- /dev/null +++ b/mpeg4/src/Makefile @@ -0,0 +1,217 @@ +# +# Main ffmpeg Makefile +# (c) 2000-2004 Fabrice Bellard +# +include config.mak + +VPATH=$(SRC_PATH) + +CFLAGS=$(OPTFLAGS) -I. -I$(SRC_PATH) -I$(SRC_PATH)/libavutil -I$(SRC_PATH)/libavcodec -I$(SRC_PATH)/libavformat -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE +LDFLAGS+= -g + +ifeq ($(TARGET_GPROF),yes) +CFLAGS+=-p +LDFLAGS+=-p +endif + +MANPAGE=doc/ffmpeg.1 +PROG_G+=ffmpeg_g$(EXESUF) +PROG+=ffmpeg$(EXESUF) +PROGTEST=output_example$(EXESUF) +QTFASTSTART=qt-faststart$(EXESUF) + +ifeq ($(CONFIG_FFSERVER),yes) +MANPAGE+=doc/ffserver.1 +PROG+=ffserver$(EXESUF) +endif + +ifeq ($(CONFIG_FFPLAY),yes) +MANPAGE+=doc/ffplay.1 +PROG_G+=ffplay_g$(EXESUF) +PROG+=ffplay$(EXESUF) +FFPLAY_O=ffplay.o +endif + +ifeq ($(CONFIG_AUDIO_BEOS),yes) +EXTRALIBS+=-lmedia -lbe +endif + +ifeq ($(BUILD_SHARED),yes) +DEP_LIBS=libavcodec/$(SLIBPREF)avcodec$(SLIBSUF) libavformat/$(SLIBPREF)avformat$(SLIBSUF) +else +DEP_LIBS=libavcodec/$(LIBPREF)avcodec$(LIBSUF) libavformat/$(LIBPREF)avformat$(LIBSUF) +endif + +ifeq ($(BUILD_VHOOK),yes) +VHOOK=videohook +INSTALLVHOOK=install-vhook +endif + +ifeq ($(TARGET_OS), SunOS) +TEST=/usr/bin/test +else +TEST=test +endif + +ifeq ($(BUILD_DOC),yes) +DOC=documentation +endif + +OBJS = ffmpeg.o ffserver.o cmdutils.o $(FFPLAY_O) +SRCS = $(OBJS:.o=.c) $(ASM_OBJS:.o=.s) +FFLIBS = -L./libavformat -lavformat$(BUILDSUF) -L./libavcodec -lavcodec$(BUILDSUF) -L./libavutil -lavutil$(BUILDSUF) + +all: lib $(PROG_G) $(PROG) $(PROGTEST) $(VHOOK) $(QTFASTSTART) $(DOC) + +lib: + $(MAKE) -C libavutil all + $(MAKE) -C libavcodec all + $(MAKE) -C libavformat all +ifeq ($(CONFIG_PP),yes) + $(MAKE) -C libavcodec/libpostproc all +endif + +ffmpeg_g$(EXESUF): ffmpeg.o cmdutils.o .libs + $(CC) $(LDFLAGS) -o $@ ffmpeg.o cmdutils.o $(FFLIBS) $(EXTRALIBS) + +ffmpeg$(EXESUF): ffmpeg_g$(EXESUF) + cp -p $< $@ + $(STRIP) $@ + +ffserver$(EXESUF): ffserver.o .libs + $(CC) $(LDFLAGS) $(FFSLDFLAGS) -o $@ ffserver.o $(FFLIBS) $(EXTRALIBS) + +ffplay_g$(EXESUF): ffplay.o cmdutils.o .libs + $(CC) $(LDFLAGS) -o $@ ffplay.o cmdutils.o $(FFLIBS) $(EXTRALIBS) $(SDL_LIBS) + +ffplay$(EXESUF): ffplay_g$(EXESUF) + cp -p $< $@ + $(STRIP) $@ + +output_example$(EXESUF): output_example.o .libs + $(CC) $(LDFLAGS) -o $@ output_example.o $(FFLIBS) $(EXTRALIBS) + +qt-faststart$(EXESUF): qt-faststart.c + $(CC) $(CFLAGS) $(SRC_PATH)/qt-faststart.c -o qt-faststart$(EXESUF) + +cws2fws$(EXESUF): cws2fws.c + $(CC) $(SRC_PATH)/cws2fws.c -o cws2fws$(EXESUF) -lz + +ffplay.o: ffplay.c + $(CC) $(CFLAGS) $(SDL_CFLAGS) -c -o $@ $< + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +videohook: .libs + $(MAKE) -C vhook all + +documentation: + $(MAKE) -C doc all + +.PHONY: install + +install: install-progs install-libs install-headers install-man $(INSTALLVHOOK) + +ifeq ($(BUILD_SHARED),yes) +install-progs: $(PROG) install-libs +else +install-progs: $(PROG) +endif + install -d "$(bindir)" + install -c $(INSTALLSTRIP) -m 755 $(PROG) "$(bindir)" + +# create the window installer +wininstaller: all install + makensis ffinstall.nsi + +# install man from source dir if available +install-man: +ifneq ($(CONFIG_WIN32),yes) + if [ -f doc/ffmpeg.1 ] ; then \ + install -d "$(mandir)/man1" ; \ + install -m 644 $(MANPAGE) "$(mandir)/man1" ; \ + fi +endif + +install-vhook: + $(MAKE) -C vhook install + +install-libs: + $(MAKE) -C libavutil install-libs + $(MAKE) -C libavcodec install-libs + $(MAKE) -C libavformat install-libs +ifeq ($(CONFIG_PP),yes) + $(MAKE) -C libavcodec/libpostproc install-libs +endif +ifeq ($(BUILD_SHARED),yes) + -$(LDCONFIG) +endif + +install-headers: + $(MAKE) -C libavutil install-headers + $(MAKE) -C libavcodec install-headers + $(MAKE) -C libavformat install-headers +ifeq ($(CONFIG_PP),yes) + $(MAKE) -C libavcodec/libpostproc install-headers +endif + +dep: depend + +depend: .depend + $(MAKE) -C libavcodec depend + $(MAKE) -C libavformat depend +ifeq ($(BUILD_VHOOK),yes) + $(MAKE) -C vhook depend +endif + +.depend: $(SRCS) + $(CC) -MM $(CFLAGS) $(SDL_CFLAGS) $^ 1>.depend + +.libs: lib + @test -f .libs || touch .libs + @for i in $(DEP_LIBS) ; do if $(TEST) $$i -nt .libs ; then touch .libs; fi ; done + +clean: + $(MAKE) -C libavutil clean + $(MAKE) -C libavcodec clean + $(MAKE) -C libavformat clean + $(MAKE) -C libavcodec/libpostproc clean + $(MAKE) -C tests clean + $(MAKE) -C vhook clean + rm -f *.o *.d *~ .libs gmon.out TAGS \ + $(PROG) $(PROG_G) $(PROGTEST) $(QTFASTSTART) + +# Note well: config.log is NOT removed. +distclean: clean + $(MAKE) -C libavutil distclean + $(MAKE) -C libavcodec distclean + $(MAKE) -C libavformat distclean + $(MAKE) -C libavcodec/libpostproc distclean + $(MAKE) -C tests distclean + $(MAKE) -C vhook distclean + rm -f .depend config.mak config.h *.pc + +TAGS: + etags *.[ch] libavformat/*.[ch] libavcodec/*.[ch] + +# regression tests + +libavtest test mpeg4 mpeg test-server fulltest: $(PROG) + $(MAKE) -C tests $@ + +# tar release (use 'make -k tar' on a checkouted tree) +FILE=ffmpeg-$(shell grep "\#define FFMPEG_VERSION " libavcodec/avcodec.h | \ + cut -d "\"" -f 2 ) + +tar: + rm -rf /tmp/$(FILE) + cp -r . /tmp/$(FILE) + ( cd /tmp ; tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS ) + rm -rf /tmp/$(FILE) + +.PHONY: lib + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/mpeg4/src/README b/mpeg4/src/README new file mode 100644 index 00000000..ce3e0d69 --- /dev/null +++ b/mpeg4/src/README @@ -0,0 +1,19 @@ +FFmpeg README +------------- + +1) Documentation +---------------- + +* Read the documentation in the doc/ directory. + +2) Licensing +------------ + +* Read the file COPYING. ffmpeg and the associated libraries EXCEPT + liba52 and libpostproc are licensed under the Lesser GNU General + Public License. + +* liba52 and libpostproc are distributed under the GNU General Public + License and their compilation and use is optional in ffmpeg. + +Fabrice Bellard. \ No newline at end of file diff --git a/mpeg4/src/berrno.h b/mpeg4/src/berrno.h new file mode 100644 index 00000000..eb3bd0cd --- /dev/null +++ b/mpeg4/src/berrno.h @@ -0,0 +1,44 @@ +#ifndef BERRNO_H +#define BERRNO_H + +#include + +// mmu_man: this is needed for http.c (defined errno) +#include + +#ifdef ENOENT +#undef ENOENT +#endif +#define ENOENT 2 + +#ifdef EINTR +#undef EINTR +#endif +#define EINTR 4 + +#ifdef EIO +#undef EIO +#endif +#define EIO 5 + +#ifdef EAGAIN +#undef EAGAIN +#endif +#define EAGAIN 11 + +#ifdef ENOMEM +#undef ENOMEM +#endif +#define ENOMEM 12 + +#ifdef EINVAL +#undef EINVAL +#endif +#define EINVAL 22 + +#ifdef EPIPE +#undef EPIPE +#endif +#define EPIPE 32 + +#endif /* BERRNO_H */ diff --git a/mpeg4/src/build_avopt b/mpeg4/src/build_avopt new file mode 100755 index 00000000..fcf16576 --- /dev/null +++ b/mpeg4/src/build_avopt @@ -0,0 +1,9 @@ +#!/bin/sh +sed 's/unsigned//g' |\ + sed 's/enum//g' |\ + egrep '^ *(int|float|double|AVRational|char *\*) *[a-zA-Z_0-9]* *;' |\ + sed 's/^ *\([^ ]*\)[ *]*\([^;]*\);.*$/{"\2", NULL, OFFSET(\2), FF_OPT_TYPE_\U\1, DEFAULT, \1_MIN, \1_MAX},/' |\ + sed 's/AVRATIONAL_M/INT_M/g'|\ + sed 's/TYPE_AVRATIONAL/TYPE_RATIONAL/g'|\ + sed 's/FLOAT_M/FLT_M/g'|\ + sed 's/FF_OPT_TYPE_CHAR/FF_OPT_TYPE_STRING/g' diff --git a/mpeg4/src/clean-diff b/mpeg4/src/clean-diff new file mode 100755 index 00000000..3a6d19ee --- /dev/null +++ b/mpeg4/src/clean-diff @@ -0,0 +1,11 @@ +#!/bin/sh +sed '/^+[^+]/!s/ /TaBBaT/g' |\ + expand -t `seq -s , 9 8 200` |\ + sed 's/TaBBaT/ /g' |\ + sed '/^+[^+]/s/ * $//' |\ + tr -d '\015' |\ + tr '\n' '°' |\ + sed 's/\(@@[^@]*@@°[^@]*\)/\n\1/g' |\ + egrep -v '@@[^@]*@@°(( [^°]*°)|([+-][[:space:]]*°)|(-[[:space:]]*([^°]*)°\+[[:space:]]*\5°))*$' |\ + tr -d '\n' |\ + tr '°' '\n' \ No newline at end of file diff --git a/mpeg4/src/cmdutils.c b/mpeg4/src/cmdutils.c new file mode 100644 index 00000000..32f38083 --- /dev/null +++ b/mpeg4/src/cmdutils.c @@ -0,0 +1,135 @@ +/* + * Various utilities for command line tools + * Copyright (c) 2000-2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#define HAVE_AV_CONFIG_H +#include "avformat.h" +#include "common.h" + +#include "cmdutils.h" + +void show_help_options(const OptionDef *options, const char *msg, int mask, int value) +{ + const OptionDef *po; + int first; + + first = 1; + for(po = options; po->name != NULL; po++) { + char buf[64]; + if ((po->flags & mask) == value) { + if (first) { + printf("%s", msg); + first = 0; + } + pstrcpy(buf, sizeof(buf), po->name); + if (po->flags & HAS_ARG) { + pstrcat(buf, sizeof(buf), " "); + pstrcat(buf, sizeof(buf), po->argname); + } + printf("-%-17s %s\n", buf, po->help); + } + } +} + +static const OptionDef* find_option(const OptionDef *po, const char *name){ + while (po->name != NULL) { + if (!strcmp(name, po->name)) + break; + po++; + } + return po; +} + +void parse_options(int argc, char **argv, const OptionDef *options) +{ + const char *opt, *arg; + int optindex; + const OptionDef *po; + + /* parse options */ + optindex = 1; + while (optindex < argc) { + opt = argv[optindex++]; + + if (opt[0] == '-' && opt[1] != '\0') { + po= find_option(options, opt + 1); + if (!po->name) + po= find_option(options, "default"); + if (!po->name) { +unknown_opt: + fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt); + exit(1); + } + arg = NULL; + if (po->flags & HAS_ARG) { + arg = argv[optindex++]; + if (!arg) { + fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt); + exit(1); + } + } + if (po->flags & OPT_STRING) { + char *str; + str = av_strdup(arg); + *po->u.str_arg = str; + } else if (po->flags & OPT_BOOL) { + *po->u.int_arg = 1; + } else if (po->flags & OPT_INT) { + *po->u.int_arg = atoi(arg); + } else if (po->flags & OPT_FLOAT) { + *po->u.float_arg = atof(arg); + } else if (po->flags & OPT_FUNC2) { + if(po->u.func2_arg(opt+1, arg)<0) + goto unknown_opt; + } else { + po->u.func_arg(arg); + } + } else { + parse_arg_file(opt); + } + } +} + +void print_error(const char *filename, int err) +{ + switch(err) { + case AVERROR_NUMEXPECTED: + fprintf(stderr, "%s: Incorrect image filename syntax.\n" + "Use '%%d' to specify the image number:\n" + " for img1.jpg, img2.jpg, ..., use 'img%%d.jpg';\n" + " for img001.jpg, img002.jpg, ..., use 'img%%03d.jpg'.\n", + filename); + break; + case AVERROR_INVALIDDATA: + fprintf(stderr, "%s: Error while parsing header\n", filename); + break; + case AVERROR_NOFMT: + fprintf(stderr, "%s: Unknown format\n", filename); + break; + case AVERROR_IO: + fprintf(stderr, "%s: I/O error occured\n" + "Usually that means that input file is truncated and/or corrupted.\n", + filename); + break; + case AVERROR_NOMEM: + fprintf(stderr, "%s: memory allocation error occured\n", filename); + break; + default: + fprintf(stderr, "%s: Error while opening file\n", filename); + break; + } +} diff --git a/mpeg4/src/cmdutils.h b/mpeg4/src/cmdutils.h new file mode 100644 index 00000000..d9c66f01 --- /dev/null +++ b/mpeg4/src/cmdutils.h @@ -0,0 +1,34 @@ +#ifndef _CMD_UTILS_H +#define _CMD_UTILS_H + +typedef struct { + const char *name; + int flags; +#define HAS_ARG 0x0001 +#define OPT_BOOL 0x0002 +#define OPT_EXPERT 0x0004 +#define OPT_STRING 0x0008 +#define OPT_VIDEO 0x0010 +#define OPT_AUDIO 0x0020 +#define OPT_GRAB 0x0040 +#define OPT_INT 0x0080 +#define OPT_FLOAT 0x0100 +#define OPT_SUBTITLE 0x0200 +#define OPT_FUNC2 0x0400 + union { + void (*func_arg)(const char *); //FIXME passing error code as int return would be nicer then exit() in the func + int *int_arg; + char **str_arg; + float *float_arg; + int (*func2_arg)(const char *, const char *); + } u; + const char *help; + const char *argname; +} OptionDef; + +void show_help_options(const OptionDef *options, const char *msg, int mask, int value); +void parse_options(int argc, char **argv, const OptionDef *options); +void parse_arg_file(const char *filename); +void print_error(const char *filename, int err); + +#endif /* _CMD_UTILS_H */ diff --git a/mpeg4/src/common.mak b/mpeg4/src/common.mak new file mode 100644 index 00000000..3bcf1e96 --- /dev/null +++ b/mpeg4/src/common.mak @@ -0,0 +1,101 @@ +# +# common bits used by all libraries +# + +SRC_DIR = $(SRC_PATH)/$(SUBDIR) +VPATH = $(SRC_DIR) + +#FIXME: This should be in configure/config.mak +ifeq ($(CONFIG_WIN32),yes) +LDFLAGS = -Wl,--output-def,$(@:.dll=.def),--out-implib,lib$(SLIBNAME:$(SLIBSUF)=.dll.a) +endif + +ifeq ($(TARGET_GPROF),yes) +CFLAGS+=-p +LDFLAGS+=-p +endif + +ifeq ($(TARGET_ARCH_SPARC64),yes) +CFLAGS+= -mcpu=ultrasparc -mtune=ultrasparc +endif + +SRCS := $(OBJS:.o=.c) $(ASM_OBJS:.o=.S) $(CPPOBJS:.o=.cpp) +OBJS := $(OBJS) $(ASM_OBJS) $(CPPOBJS) +STATIC_OBJS := $(OBJS) $(STATIC_OBJS) +SHARED_OBJS := $(OBJS) $(SHARED_OBJS) + +all: $(LIB) $(SLIBNAME) + +$(LIB): $(STATIC_OBJS) + rm -f $@ + $(AR) rc $@ $^ $(EXTRAOBJS) + $(RANLIB) $@ + +$(SLIBNAME): $(SHARED_OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o $@ $^ $(EXTRALIBS) $(EXTRAOBJS) +ifeq ($(CONFIG_WIN32),yes) + -lib /machine:i386 /def:$(@:.dll=.def) +endif + +%.o: %.c + $(CC) $(CFLAGS) $(LIBOBJFLAGS) -c -o $@ $< + +%.o: %.S + $(CC) $(CFLAGS) $(LIBOBJFLAGS) -c -o $@ $< + +# BeOS: remove -Wall to get rid of all the "multibyte constant" warnings +%.o: %.cpp + g++ $(subst -Wall,,$(CFLAGS)) -c -o $@ $< + +depend: $(SRCS) + $(CC) -MM $(CFLAGS) $^ 1>.depend + +dep: depend + +clean:: + rm -f *.o *.d *~ *.a *.lib *.so *.dylib *.dll \ + *.lib *.def *.dll.a *.exp + +distclean: clean + rm -f .depend + +ifeq ($(BUILD_SHARED),yes) +INSTLIBTARGETS += install-lib-shared +endif +ifeq ($(BUILD_STATIC),yes) +INSTLIBTARGETS += install-lib-static +endif + +install: install-libs install-headers + +install-libs: $(INSTLIBTARGETS) + +install-lib-shared: $(SLIBNAME) + install -d "$(libdir)" +ifeq ($(CONFIG_WIN32),yes) + install $(INSTALLSTRIP) -m 755 $(SLIBNAME) "$(prefix)" +else + install $(INSTALLSTRIP) -m 755 $(SLIBNAME) \ + $(libdir)/$(SLIBNAME_WITH_VERSION) + ln -sf $(SLIBNAME_WITH_VERSION) \ + $(libdir)/$(SLIBNAME_WITH_MAJOR) + ln -sf $(SLIBNAME_WITH_VERSION) \ + $(libdir)/$(SLIBNAME) +endif + +install-lib-static: $(LIB) + install -d "$(libdir)" + install -m 644 $(LIB) "$(libdir)" + +install-headers: + install -d "$(incdir)" + install -d "$(libdir)/pkgconfig" + install -m 644 $(addprefix "$(SRC_DIR)"/,$(HEADERS)) "$(incdir)" + install -m 644 $(BUILD_ROOT)/lib$(NAME).pc "$(libdir)/pkgconfig" + +# +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/mpeg4/src/config.h b/mpeg4/src/config.h new file mode 100644 index 00000000..2c5be02d --- /dev/null +++ b/mpeg4/src/config.h @@ -0,0 +1,190 @@ +/* Automatically generated by configure - do not modify! */ +#define FFMPEG_CONFIGURATION " --disable-mmx --disable-ffserver --disable-ffplay --disable-strip " +//#define ARCH_X86_64 1 -- removed +#define TUNECPU generic +#define HAVE_BUILTIN_VECTOR 1 +#define HAVE_LOCALTIME_R 1 +#define HAVE_LRINTF 1 +#define HAVE_VHOOK 1 +#define CONFIG_ENCODERS 1 +#define CONFIG_DECODERS 1 +#define CONFIG_MUXERS 1 +#define CONFIG_DEMUXERS 1 +#define CONFIG_MPEGAUDIO_HP 1 +#define CONFIG_VIDEO4LINUX 1 +#define CONFIG_VIDEO4LINUX2 1 +#define CONFIG_DV1394 1 +#define CONFIG_HAVE_DLOPEN 1 +#define CONFIG_HAVE_DLFCN 1 +#define CONFIG_AUDIO_OSS 1 +#define CONFIG_NETWORK 1 +#define CONFIG_IPV6 1 +#define CONFIG_ZLIB 1 +//#define HAVE_MALLOC_H 1 -- defined in Android headers +#define HAVE_MEMALIGN 1 +#define SIMPLE_IDCT 1 +#define CONFIG_PROTOCOLS 1 +#define restrict __restrict__ +#define CONFIG_AC3_ENCODER 1 +#define CONFIG_MP2_ENCODER 1 +#define CONFIG_MP3LAME_ENCODER 1 +#define CONFIG_OGGVORBIS_ENCODER 1 +#define CONFIG_OGGVORBIS_DECODER 1 +#define CONFIG_OGGTHEORA_ENCODER 1 +#define CONFIG_OGGTHEORA_DECODER 1 +#define CONFIG_FAAC_ENCODER 1 +#define CONFIG_XVID_ENCODER 1 +#define CONFIG_MPEG1VIDEO_ENCODER 1 +#define CONFIG_H264_ENCODER 1 +#define CONFIG_MPEG2VIDEO_ENCODER 1 +#define CONFIG_H261_ENCODER 1 +#define CONFIG_H263_ENCODER 1 +#define CONFIG_H263P_ENCODER 1 +#define CONFIG_FLV_ENCODER 1 +#define CONFIG_RV10_ENCODER 1 +#define CONFIG_RV20_ENCODER 1 +#define CONFIG_MPEG4_ENCODER 1 +#define CONFIG_MSMPEG4V1_ENCODER 1 +#define CONFIG_MSMPEG4V2_ENCODER 1 +#define CONFIG_MSMPEG4V3_ENCODER 1 +#define CONFIG_WMV1_ENCODER 1 +#define CONFIG_WMV2_ENCODER 1 +#define CONFIG_SVQ1_ENCODER 1 +#define CONFIG_MJPEG_ENCODER 1 +#define CONFIG_LJPEG_ENCODER 1 +#define CONFIG_JPEGLS_ENCODER 1 +#define CONFIG_PNG_ENCODER 1 +#define CONFIG_PPM_ENCODER 1 +#define CONFIG_PGM_ENCODER 1 +#define CONFIG_PGMYUV_ENCODER 1 +#define CONFIG_PBM_ENCODER 1 +#define CONFIG_PAM_ENCODER 1 +#define CONFIG_HUFFYUV_ENCODER 1 +#define CONFIG_FFVHUFF_ENCODER 1 +#define CONFIG_ASV1_ENCODER 1 +#define CONFIG_ASV2_ENCODER 1 +#define CONFIG_FFV1_ENCODER 1 +#define CONFIG_SNOW_ENCODER 1 +#define CONFIG_ZLIB_ENCODER 1 +#define CONFIG_DVVIDEO_ENCODER 1 +#define CONFIG_SONIC_ENCODER 1 +#define CONFIG_SONIC_LS_ENCODER 1 +#define CONFIG_X264_ENCODER 1 +#define CONFIG_LIBGSM_ENCODER 1 +#define CONFIG_RAWVIDEO_ENCODER 1 +#define CONFIG_H263_DECODER 1 +#define CONFIG_H261_DECODER 1 +#define CONFIG_MPEG4_DECODER 1 +#define CONFIG_MSMPEG4V1_DECODER 1 +#define CONFIG_MSMPEG4V2_DECODER 1 +#define CONFIG_MSMPEG4V3_DECODER 1 +#define CONFIG_WMV1_DECODER 1 +#define CONFIG_WMV2_DECODER 1 +#define CONFIG_VC9_DECODER 1 +#define CONFIG_WMV3_DECODER 1 +#define CONFIG_H263I_DECODER 1 +#define CONFIG_FLV_DECODER 1 +#define CONFIG_RV10_DECODER 1 +#define CONFIG_RV20_DECODER 1 +#define CONFIG_SVQ1_DECODER 1 +#define CONFIG_SVQ3_DECODER 1 +#define CONFIG_WMAV1_DECODER 1 +#define CONFIG_WMAV2_DECODER 1 +#define CONFIG_INDEO2_DECODER 1 +#define CONFIG_INDEO3_DECODER 1 +#define CONFIG_TSCC_DECODER 1 +#define CONFIG_CSCD_DECODER 1 +#define CONFIG_NUV_DECODER 1 +#define CONFIG_ULTI_DECODER 1 +#define CONFIG_QDRAW_DECODER 1 +#define CONFIG_XL_DECODER 1 +#define CONFIG_QPEG_DECODER 1 +#define CONFIG_LOCO_DECODER 1 +#define CONFIG_KMVC_DECODER 1 +#define CONFIG_WNV1_DECODER 1 +#define CONFIG_AASC_DECODER 1 +#define CONFIG_FRAPS_DECODER 1 +#define CONFIG_AAC_DECODER 1 +#define CONFIG_MPEG4AAC_DECODER 1 +#define CONFIG_MPEG1VIDEO_DECODER 1 +#define CONFIG_MPEG2VIDEO_DECODER 1 +#define CONFIG_MPEGVIDEO_DECODER 1 +#define CONFIG_MPEG_XVMC_DECODER 1 +#define CONFIG_DVVIDEO_DECODER 1 +#define CONFIG_MJPEG_DECODER 1 +#define CONFIG_MJPEGB_DECODER 1 +#define CONFIG_SP5X_DECODER 1 +#define CONFIG_PNG_DECODER 1 +#define CONFIG_MP2_DECODER 1 +#define CONFIG_MP3_DECODER 1 +#define CONFIG_MP3ADU_DECODER 1 +#define CONFIG_MP3ON4_DECODER 1 +#define CONFIG_MACE3_DECODER 1 +#define CONFIG_MACE6_DECODER 1 +#define CONFIG_HUFFYUV_DECODER 1 +#define CONFIG_FFVHUFF_DECODER 1 +#define CONFIG_FFV1_DECODER 1 +#define CONFIG_SNOW_DECODER 1 +#define CONFIG_CYUV_DECODER 1 +#define CONFIG_H264_DECODER 1 +#define CONFIG_VP3_DECODER 1 +#define CONFIG_THEORA_DECODER 1 +#define CONFIG_ASV1_DECODER 1 +#define CONFIG_ASV2_DECODER 1 +#define CONFIG_VCR1_DECODER 1 +#define CONFIG_CLJR_DECODER 1 +#define CONFIG_FOURXM_DECODER 1 +#define CONFIG_MDEC_DECODER 1 +#define CONFIG_ROQ_DECODER 1 +#define CONFIG_INTERPLAY_VIDEO_DECODER 1 +#define CONFIG_XAN_WC3_DECODER 1 +#define CONFIG_RPZA_DECODER 1 +#define CONFIG_CINEPAK_DECODER 1 +#define CONFIG_MSRLE_DECODER 1 +#define CONFIG_MSVIDEO1_DECODER 1 +#define CONFIG_VQA_DECODER 1 +#define CONFIG_IDCIN_DECODER 1 +#define CONFIG_EIGHTBPS_DECODER 1 +#define CONFIG_SMC_DECODER 1 +#define CONFIG_FLIC_DECODER 1 +#define CONFIG_TRUEMOTION1_DECODER 1 +#define CONFIG_TRUEMOTION2_DECODER 1 +#define CONFIG_VMDVIDEO_DECODER 1 +#define CONFIG_VMDAUDIO_DECODER 1 +#define CONFIG_MSZH_DECODER 1 +#define CONFIG_ZLIB_DECODER 1 +#define CONFIG_ZMBV_DECODER 1 +#define CONFIG_SMACKER_DECODER 1 +#define CONFIG_SMACKAUD_DECODER 1 +#define CONFIG_SONIC_DECODER 1 +#define CONFIG_AC3_DECODER 1 +#define CONFIG_DTS_DECODER 1 +#define CONFIG_RA_144_DECODER 1 +#define CONFIG_RA_288_DECODER 1 +#define CONFIG_ROQ_DPCM_DECODER 1 +#define CONFIG_INTERPLAY_DPCM_DECODER 1 +#define CONFIG_XAN_DPCM_DECODER 1 +#define CONFIG_SOL_DPCM_DECODER 1 +#define CONFIG_QTRLE_DECODER 1 +#define CONFIG_FLAC_DECODER 1 +#define CONFIG_SHORTEN_DECODER 1 +#define CONFIG_ALAC_DECODER 1 +#define CONFIG_WS_SND1_DECODER 1 +#define CONFIG_VORBIS_DECODER 1 +#define CONFIG_LIBGSM_DECODER 1 +#define CONFIG_QDM2_DECODER 1 +#define CONFIG_COOK_DECODER 1 +#define CONFIG_TRUESPEECH_DECODER 1 +#define CONFIG_TTA_DECODER 1 +#define CONFIG_AVS_DECODER 1 +#define CONFIG_RAWVIDEO_DECODER 1 +#define CONFIG_AMR_NB_DECODER 1 +#define CONFIG_AMR_NB_ENCODER 1 +#define CONFIG_AMR_WB_DECODER 1 +#define CONFIG_AMR_WB_ENCODER 1 +#define CONFIG_BMP_DECODER 1 +#define CONFIG_MMVIDEO_DECODER 1 +#define CONFIG_DVDSUB_DECODER 1 +#define CONFIG_DVDSUB_ENCODER 1 +#define CONFIG_DVBSUB_DECODER 1 +#define CONFIG_DVBSUB_ENCODER 1 diff --git a/mpeg4/src/config.mak b/mpeg4/src/config.mak new file mode 100644 index 00000000..c4d672f2 --- /dev/null +++ b/mpeg4/src/config.mak @@ -0,0 +1,213 @@ +# Automatically generated by configure - do not modify! +prefix=$(DESTDIR)/usr/local +libdir=$(DESTDIR)/usr/local/lib +incdir=$(DESTDIR)/usr/local/include/ffmpeg +bindir=$(DESTDIR)/usr/local/bin +mandir=$(DESTDIR)/usr/local/man +MAKE=make +CC=gcc +AR=ar +RANLIB=ranlib +STRIP=echo ignoring strip +INSTALLSTRIP= +OPTFLAGS=-O3 -g -Wall -Wno-switch -Wdeclaration-after-statement +SHCFLAGS=-O3 -g -Wall -Wno-switch -Wdeclaration-after-statement +LDFLAGS=-Wl,--warn-common -rdynamic +LDCONFIG=ldconfig +FFSLDFLAGS=-Wl,-E +SHFLAGS=-shared -Wl,-soname,$@.$(LIBMAJOR) +LIBOBJFLAGS= +BUILD_STATIC=yes +BUILDSUF= +LIBPREF=lib +LIBSUF=${BUILDSUF}.a +LIB=$(LIBPREF)$(NAME)$(LIBSUF) +SLIBPREF=lib +SLIBSUF=${BUILDSUF}.so +EXESUF=${BUILDSUF} +TARGET_OS=Linux +TARGET_ARCH_X86_64=yes +TARGET_BUILTIN_VECTOR=yes +HAVE_FREETYPE2=yes +CONFIG_SDL=yes +SDL_LIBS=-L/usr/lib -lSDL +SDL_CFLAGS=-I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT +BUILD_VHOOK=yes +EXTRALIBS=-lm -lz -ldl +VERSION=CVS +CONFIG_ENCODERS=yes +CONFIG_DECODERS=yes +CONFIG_MUXERS=yes +CONFIG_DEMUXERS=yes +CONFIG_VIDEO4LINUX=yes +CONFIG_VIDEO4LINUX2=yes +CONFIG_DV1394=yes +CONFIG_AUDIO_OSS=yes +CONFIG_NETWORK=yes +CONFIG_ZLIB=yes +CONFIG_PROTOCOLS=yes +SRC_PATH=/usr/local/google/home/projects/bench/outofbox/mpeg/ffmpeg/ffmpeg +BUILD_ROOT=/usr/local/google/home/projects/bench/outofbox/mpeg/ffmpeg/obj +CONFIG_AC3_ENCODER=yes +CONFIG_MP2_ENCODER=yes +CONFIG_MP3LAME_ENCODER=yes +CONFIG_OGGVORBIS_ENCODER=yes +CONFIG_OGGVORBIS_DECODER=yes +CONFIG_OGGTHEORA_ENCODER=yes +CONFIG_OGGTHEORA_DECODER=yes +CONFIG_FAAC_ENCODER=yes +CONFIG_XVID_ENCODER=yes +CONFIG_MPEG1VIDEO_ENCODER=yes +CONFIG_H264_ENCODER=yes +CONFIG_MPEG2VIDEO_ENCODER=yes +CONFIG_H261_ENCODER=yes +CONFIG_H263_ENCODER=yes +CONFIG_H263P_ENCODER=yes +CONFIG_FLV_ENCODER=yes +CONFIG_RV10_ENCODER=yes +CONFIG_RV20_ENCODER=yes +CONFIG_MPEG4_ENCODER=yes +CONFIG_MSMPEG4V1_ENCODER=yes +CONFIG_MSMPEG4V2_ENCODER=yes +CONFIG_MSMPEG4V3_ENCODER=yes +CONFIG_WMV1_ENCODER=yes +CONFIG_WMV2_ENCODER=yes +CONFIG_SVQ1_ENCODER=yes +CONFIG_MJPEG_ENCODER=yes +CONFIG_LJPEG_ENCODER=yes +CONFIG_JPEGLS_ENCODER=yes +CONFIG_PNG_ENCODER=yes +CONFIG_PPM_ENCODER=yes +CONFIG_PGM_ENCODER=yes +CONFIG_PGMYUV_ENCODER=yes +CONFIG_PBM_ENCODER=yes +CONFIG_PAM_ENCODER=yes +CONFIG_HUFFYUV_ENCODER=yes +CONFIG_FFVHUFF_ENCODER=yes +CONFIG_ASV1_ENCODER=yes +CONFIG_ASV2_ENCODER=yes +CONFIG_FFV1_ENCODER=yes +CONFIG_SNOW_ENCODER=yes +CONFIG_ZLIB_ENCODER=yes +CONFIG_DVVIDEO_ENCODER=yes +CONFIG_SONIC_ENCODER=yes +CONFIG_SONIC_LS_ENCODER=yes +CONFIG_X264_ENCODER=yes +CONFIG_LIBGSM_ENCODER=yes +CONFIG_RAWVIDEO_ENCODER=yes +CONFIG_H263_DECODER=yes +CONFIG_H261_DECODER=yes +CONFIG_MPEG4_DECODER=yes +CONFIG_MSMPEG4V1_DECODER=yes +CONFIG_MSMPEG4V2_DECODER=yes +CONFIG_MSMPEG4V3_DECODER=yes +CONFIG_WMV1_DECODER=yes +CONFIG_WMV2_DECODER=yes +CONFIG_VC9_DECODER=yes +CONFIG_WMV3_DECODER=yes +CONFIG_H263I_DECODER=yes +CONFIG_FLV_DECODER=yes +CONFIG_RV10_DECODER=yes +CONFIG_RV20_DECODER=yes +CONFIG_SVQ1_DECODER=yes +CONFIG_SVQ3_DECODER=yes +CONFIG_WMAV1_DECODER=yes +CONFIG_WMAV2_DECODER=yes +CONFIG_INDEO2_DECODER=yes +CONFIG_INDEO3_DECODER=yes +CONFIG_TSCC_DECODER=yes +CONFIG_CSCD_DECODER=yes +CONFIG_NUV_DECODER=yes +CONFIG_ULTI_DECODER=yes +CONFIG_QDRAW_DECODER=yes +CONFIG_XL_DECODER=yes +CONFIG_QPEG_DECODER=yes +CONFIG_LOCO_DECODER=yes +CONFIG_KMVC_DECODER=yes +CONFIG_WNV1_DECODER=yes +CONFIG_AASC_DECODER=yes +CONFIG_FRAPS_DECODER=yes +CONFIG_AAC_DECODER=yes +CONFIG_MPEG4AAC_DECODER=yes +CONFIG_MPEG1VIDEO_DECODER=yes +CONFIG_MPEG2VIDEO_DECODER=yes +CONFIG_MPEGVIDEO_DECODER=yes +CONFIG_MPEG_XVMC_DECODER=yes +CONFIG_DVVIDEO_DECODER=yes +CONFIG_MJPEG_DECODER=yes +CONFIG_MJPEGB_DECODER=yes +CONFIG_SP5X_DECODER=yes +CONFIG_PNG_DECODER=yes +CONFIG_MP2_DECODER=yes +CONFIG_MP3_DECODER=yes +CONFIG_MP3ADU_DECODER=yes +CONFIG_MP3ON4_DECODER=yes +CONFIG_MACE3_DECODER=yes +CONFIG_MACE6_DECODER=yes +CONFIG_HUFFYUV_DECODER=yes +CONFIG_FFVHUFF_DECODER=yes +CONFIG_FFV1_DECODER=yes +CONFIG_SNOW_DECODER=yes +CONFIG_CYUV_DECODER=yes +CONFIG_H264_DECODER=yes +CONFIG_VP3_DECODER=yes +CONFIG_THEORA_DECODER=yes +CONFIG_ASV1_DECODER=yes +CONFIG_ASV2_DECODER=yes +CONFIG_VCR1_DECODER=yes +CONFIG_CLJR_DECODER=yes +CONFIG_FOURXM_DECODER=yes +CONFIG_MDEC_DECODER=yes +CONFIG_ROQ_DECODER=yes +CONFIG_INTERPLAY_VIDEO_DECODER=yes +CONFIG_XAN_WC3_DECODER=yes +CONFIG_RPZA_DECODER=yes +CONFIG_CINEPAK_DECODER=yes +CONFIG_MSRLE_DECODER=yes +CONFIG_MSVIDEO1_DECODER=yes +CONFIG_VQA_DECODER=yes +CONFIG_IDCIN_DECODER=yes +CONFIG_EIGHTBPS_DECODER=yes +CONFIG_SMC_DECODER=yes +CONFIG_FLIC_DECODER=yes +CONFIG_TRUEMOTION1_DECODER=yes +CONFIG_TRUEMOTION2_DECODER=yes +CONFIG_VMDVIDEO_DECODER=yes +CONFIG_VMDAUDIO_DECODER=yes +CONFIG_MSZH_DECODER=yes +CONFIG_ZLIB_DECODER=yes +CONFIG_ZMBV_DECODER=yes +CONFIG_SMACKER_DECODER=yes +CONFIG_SMACKAUD_DECODER=yes +CONFIG_SONIC_DECODER=yes +CONFIG_AC3_DECODER=yes +CONFIG_DTS_DECODER=yes +CONFIG_RA_144_DECODER=yes +CONFIG_RA_288_DECODER=yes +CONFIG_ROQ_DPCM_DECODER=yes +CONFIG_INTERPLAY_DPCM_DECODER=yes +CONFIG_XAN_DPCM_DECODER=yes +CONFIG_SOL_DPCM_DECODER=yes +CONFIG_QTRLE_DECODER=yes +CONFIG_FLAC_DECODER=yes +CONFIG_SHORTEN_DECODER=yes +CONFIG_ALAC_DECODER=yes +CONFIG_WS_SND1_DECODER=yes +CONFIG_VORBIS_DECODER=yes +CONFIG_LIBGSM_DECODER=yes +CONFIG_QDM2_DECODER=yes +CONFIG_COOK_DECODER=yes +CONFIG_TRUESPEECH_DECODER=yes +CONFIG_TTA_DECODER=yes +CONFIG_AVS_DECODER=yes +CONFIG_RAWVIDEO_DECODER=yes +CONFIG_AMR_NB_DECODER=yes +CONFIG_AMR_NB_ENCODER=yes +CONFIG_AMR_WB_DECODER=yes +CONFIG_AMR_WB_ENCODER=yes +CONFIG_BMP_DECODER=yes +CONFIG_MMVIDEO_DECODER=yes +CONFIG_DVDSUB_DECODER=yes +CONFIG_DVDSUB_ENCODER=yes +CONFIG_DVBSUB_DECODER=yes +CONFIG_DVBSUB_ENCODER=yes diff --git a/mpeg4/src/configure b/mpeg4/src/configure new file mode 100755 index 00000000..20b6e4bb --- /dev/null +++ b/mpeg4/src/configure @@ -0,0 +1,2097 @@ +#!/bin/sh +# +# ffmpeg configure script (c) 2000, 2001, 2002 Fabrice Bellard +# + +if test x"$1" = x"-h" -o x"$1" = x"--help" ; then +cat << EOF + +Usage: configure [options] +Options: [defaults in brackets after descriptions] + +EOF +echo "Standard options:" +echo " --help print this message" +echo " --prefix=PREFIX install in PREFIX [$prefix]" +echo " --libdir=DIR install libs in DIR [PREFIX/lib]" +echo " --incdir=DIR install includes in DIR [PREFIX/include/ffmpeg]" +echo " --mandir=DIR install man page in DIR [PREFIX/man]" +echo " --enable-mp3lame enable MP3 encoding via libmp3lame [default=no]" +echo " --enable-libogg enable Ogg support via libogg [default=no]" +echo " --enable-vorbis enable Vorbis support via libvorbis [default=no]" +echo " --enable-theora enable Theora support via libtheora [default=no]" +echo " --enable-faad enable FAAD support via libfaad [default=no]" +echo " --enable-faadbin build FAAD support with runtime linking [default=no]" +echo " --enable-faac enable FAAC support via libfaac [default=no]" +echo " --enable-libgsm enable GSM support via libgsm [default=no]" +echo " --enable-xvid enable XviD support via xvidcore [default=no]" +echo " --enable-x264 enable H.264 encoding via x264 [default=no]" +echo " --enable-mingw32 enable MinGW native/cross Windows compile" +echo " --enable-mingwce enable MinGW native/cross WinCE compile" +echo " --enable-a52 enable GPLed A52 support [default=no]" +echo " --enable-a52bin open liba52.so.0 at runtime [default=no]" +echo " --enable-dts enable GPLed DTS support [default=no]" +echo " --enable-pp enable GPLed postprocessing support [default=no]" +echo " --enable-static build static libraries [default=yes]" +echo " --disable-static do not build static libraries [default=no]" +echo " --enable-shared build shared libraries [default=no]" +echo " --disable-shared do not build shared libraries [default=yes]" +echo " --enable-amr_nb enable amr_nb float audio codec" +echo " --enable-amr_nb-fixed use fixed point for amr-nb codec" +echo " --enable-amr_wb enable amr_wb float audio codec" +echo " --enable-amr_if2 enable amr_wb IF2 audio codec" +echo " --enable-sunmlib use Sun medialib [default=no]" +echo " --enable-pthreads use pthreads [default=no]" +echo " --enable-dc1394 enable IIDC-1394 grabbing using libdc1394" +echo " and libraw1394 [default=no]" +echo " --enable-gpl allow use of GPL code, the resulting libav*" +echo " and ffmpeg will be under GPL [default=no]" +echo "" +echo "Advanced options (experts only):" +echo " --source-path=PATH path to source code [$source_path]" +echo " --cross-prefix=PREFIX use PREFIX for compilation tools [$cross_prefix]" +echo " --cc=CC use C compiler CC [$cc]" +echo " --make=MAKE use specified make [$make]" +echo " --extra-cflags=ECFLAGS add ECFLAGS to CFLAGS [$CFLAGS]" +echo " --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS [$LDFLAGS]" +echo " --extra-libs=ELIBS add ELIBS [$ELIBS]" +echo " --build-suffix=SUFFIX suffix for application specific build []" +echo " --cpu=CPU force cpu to CPU [$cpu]" +echo " --tune=CPU tune code for a particular CPU" +echo " (may fail or perform badly on other CPUs)" +echo " --powerpc-perf-enable enable performance report on PPC" +echo " (requires enabling PMC)" +echo " --disable-mmx disable MMX usage" +echo " --disable-iwmmxt disable iwmmxt usage" +echo " --disable-altivec disable AltiVec usage" +echo " --disable-audio-oss disable OSS audio support [default=no]" +echo " --disable-audio-beos disable BeOS audio support [default=no]" +echo " --disable-v4l disable video4linux grabbing [default=no]" +echo " --disable-v4l2 disable video4linux2 grabbing [default=no]" +echo " --disable-bktr disable bktr video grabbing [default=no]" +echo " --disable-dv1394 disable DV1394 grabbing [default=no]" +echo " --disable-network disable network support [default=no]" +echo " --disable-zlib disable zlib [default=no]" +echo " --disable-lzo disable lzo [default=no]" +echo " --disable-simple_idct disable simple IDCT routines [default=no]" +echo " --disable-vhook disable video hooking support" +echo " --enable-gprof enable profiling with gprof [$gprof]" +echo " --disable-debug disable debugging symbols" +echo " --disable-opts disable compiler optimizations" +echo " --disable-mpegaudio-hp faster (but less accurate)" +echo " MPEG audio decoding [default=no]" +echo " --disable-protocols disable I/O protocols support [default=no]" +echo " --disable-ffserver disable ffserver build" +echo " --disable-ffplay disable ffplay build" +echo " --enable-small optimize for size instead of speed" +echo " --enable-memalign-hack emulate memalign, interferes with memory debuggers" +echo " --disable-strip disable stripping of executables and shared libraries" +echo " --disable-encoder=NAME disables encoder NAME" +echo " --enable-encoder=NAME enables encoder NAME" +echo " --disable-decoder=NAME disables decoder NAME" +echo " --enable-decoder=NAME enables decoder NAME" +echo " --disable-encoders disables all encoders" +echo " --disable-decoders disables all decoders" +echo " --disable-muxers disables all muxers" +echo " --disable-demuxers disables all demuxers" +echo "" +echo "NOTE: Object files are built at the place where configure is launched." +exit 1 +fi + +# set temporary file name +if test ! -z "$TMPDIR" ; then + TMPDIR1="${TMPDIR}" +elif test ! -z "$TEMPDIR" ; then + TMPDIR1="${TEMPDIR}" +else + TMPDIR1="/tmp" +fi + +TMPC="${TMPDIR1}/ffmpeg-conf-${RANDOM}-$$-${RANDOM}.c" +TMPO="${TMPDIR1}/ffmpeg-conf-${RANDOM}-$$-${RANDOM}.o" +TMPE="${TMPDIR1}/ffmpeg-conf-${RANDOM}-$$-${RANDOM}" +TMPS="${TMPDIR1}/ffmpeg-conf-${RANDOM}-$$-${RANDOM}.S" +TMPH="${TMPDIR1}/ffmpeg-conf-${RANDOM}-$$-${RANDOM}.h" + +# default parameters +prefix="/usr/local" +libdir="" +incdir="" +mandir="" +bindir="" +cross_prefix="" +cc="gcc" +ar="ar" +ranlib="ranlib" +make="make" +strip="strip" +cpu=`uname -m` +tune="generic" +powerpc_perf="no" +mmx="default" +iwmmxt="default" +altivec="default" +mmi="default" +case "$cpu" in + i386|i486|i586|i686|i86pc|BePC) + cpu="x86" + ;; + x86_64|amd64) + cpu="x86" + canon_arch="`cc -dumpmachine | sed -e 's,\([^-]*\)-.*,\1,'`" + if [ x"$canon_arch" = x"x86_64" -o x"$canon_arch" = x"amd64" ]; then + if [ -z "`echo $CFLAGS | grep -- -m32`" ]; then + cpu="x86_64" + fi + fi + ;; + # armv4l is a subset of armv5tel + armv4l|armv5tel) + cpu="armv4l" + ;; + alpha) + cpu="alpha" + ;; + "Power Macintosh"|ppc|powerpc) + cpu="powerpc" + ;; + mips|mipsel) + cpu="mips" + ;; + sun4u|sparc64) + cpu="sparc64" + ;; + sparc) + cpu="sparc" + ;; + sh4) + cpu="sh4" + ;; + parisc|parisc64) + cpu="parisc" + ;; + s390|s390x) + cpu="s390" + ;; + m68k) + cpu="m68k" + ;; + ia64) + cpu="ia64" + ;; + *) + cpu="unknown" + ;; +esac +gprof="no" +v4l="yes" +v4l2="yes" +bktr="no" +audio_oss="yes" +audio_beos="no" +dv1394="yes" +dc1394="no" +network="yes" +zlib="yes" +lzo="yes" +libgsm="no" +mp3lame="no" +libogg="no" +vorbis="no" +theora="no" +faad="no" +faadbin="no" +faac="no" +xvid="no" +x264="no" +a52="no" +a52bin="no" +dts="no" +pp="no" +mingw32="no" +mingwce="no" +cygwin="no" +os2="no" +lstatic="yes" +lshared="no" +optimize="yes" +debug="yes" +dostrip="yes" +installstrip="-s" +extralibs="-lm" +simpleidct="yes" +bigendian="no" +inttypes="yes" +emu_fast_int="no" +vhook="default" +dlfcn="no" +dlopen="no" +mpegaudio_hp="yes" +SHFLAGS='-shared -Wl,-soname,$@.$(LIBMAJOR)' +netserver="no" +need_inet_aton="no" +protocols="yes" +ffserver="yes" +ffplay="yes" +LIBOBJFLAGS="" +LDFLAGS=-Wl,--warn-common +FFSLDFLAGS=-Wl,-E +LDCONFIG="ldconfig" +LIBPREF="lib" +LIBSUF=".a" +LIB='$(LIBPREF)$(NAME)$(LIBSUF)' +SLIBPREF="lib" +SLIBSUF=".so" +SLIBNAME='$(SLIBPREF)$(NAME)$(SLIBSUF)' +SLIBNAME_WITH_VERSION='$(SLIBPREF)$(NAME)$(SLIBSUF).$(LIBVERSION)' +SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(NAME)$(SLIBSUF).$(LIBMAJOR)' +EXESUF="" +BUILDSUF="" +amr_nb="no" +amr_wb="no" +amr_nb_fixed="no" +amr_if2="no" +sunmlib="no" +pthreads="no" +gpl="no" +memalignhack="no" +muxers="yes" +demuxers="yes" + +# OS specific +targetos=`uname -s` +case $targetos in +BeOS) +prefix="/boot/home/config" +# helps building libavcodec +CFLAGS="$CFLAGS -DPIC -fomit-frame-pointer" +# 3 gcc releases known for BeOS, each with ugly bugs +gcc_version="`$cc -v 2>&1 | grep version | cut -d ' ' -f3-`" +case "$gcc_version" in +2.9-beos-991026*|2.9-beos-000224*) echo "R5/GG gcc" +mmx="no" +;; +*20010315*) echo "BeBits gcc" +CFLAGS="$CFLAGS -fno-expensive-optimizations" +;; +esac +SHFLAGS=-nostart +# disable Linux things +audio_oss="no" +v4l="no" +v4l2="no" +dv1394="no" +# enable BeOS things +audio_beos="yes" +# no need for libm, but the inet stuff +# Check for BONE +if (echo $BEINCLUDES|grep 'headers/be/bone' >/dev/null); then +extralibs="-lbind -lsocket" +else +netserver="yes" +need_inet_aton="yes" +extralibs="-lnet" +fi ;; +SunOS) +v4l="no" +v4l2="no" +audio_oss="no" +dv1394="no" +make="gmake" +LDFLAGS="" +FFSLDFLAGS="" +need_inet_aton="yes" +extralibs="$extralibs -lsocket -lnsl" +;; +NetBSD) +v4l="no" +v4l2="no" +bktr="yes" +audio_oss="yes" +dv1394="no" +make="gmake" +LDFLAGS="$LDFLAGS -export-dynamic" +case `uname -r` in +2.*) extralibs="$extralibs -lossaudio" +;; +esac +;; +OpenBSD) +v4l="no" +v4l2="no" +bktr="yes" +audio_oss="yes" +dv1394="no" +make="gmake" +LIBOBJFLAGS="\$(PIC)" +LDFLAGS="$LDFLAGS -export-dynamic -pthread" +LDCONFIG="ldconfig -m \$(libdir)" +extralibs="$extralibs -lossaudio" +;; +FreeBSD) +v4l="no" +v4l2="no" +bktr="yes" +audio_oss="yes" +dv1394="no" +make="gmake" +CFLAGS="$CFLAGS -pthread" +LDFLAGS="$LDFLAGS -export-dynamic -pthread" +;; +BSD/OS) +v4l="no" +v4l2="no" +bktr="yes" +audio_oss="yes" +dv1394="no" +extralibs="-lpoll -lgnugetopt -lm" +make="gmake" +strip="strip -d" +installstrip="" +;; +Darwin) +cc="cc" +v4l="no" +v4l2="no" +audio_oss="no" +dv1394="no" +SHFLAGS="-dynamiclib -Wl,-single_module -Wl,-install_name,\$(libdir)/\$(SLIBNAME),-current_version,\$(SPPVERSION),-compatibility_version,\$(SPPVERSION)" +extralibs="" +darwin="yes" +strip="strip -x" +installstrip="" +LDFLAGS="-Wl,-dynamic,-search_paths_first" +SLIBSUF=".dylib" +SLIBNAME_WITH_FULLVERSION='$(SLIBPREF)$(NAME).$(LIBVERSION)$(SLIBSUF)' +SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(NAME).$(LIBMAJOR)$(SLIBSUF)' +FFSLDFLAGS=-Wl,-bind_at_load +;; +MINGW32*) +# Note: the rest of the mingw32 config is done afterwards as mingw32 +# can be forced on the command line for Linux cross compilation. +mingw32="yes" +;; +CYGWIN*) +v4l="no" +v4l2="no" +audio_oss="yes" +dv1394="no" +vhook="no" +extralibs="" +cygwin="yes" +EXESUF=".exe" +;; +Linux) +LDFLAGS="$LDFLAGS -rdynamic" +;; +IRIX*) +ranlib="echo ignoring ranlib" +v4l="no" +v4l2="no" +audio_oss="no" +make="gmake" +;; +OS/2) +TMPE=$TMPE".exe" +ar="emxomfar -p128" +ranlib="echo ignoring ranlib" +strip="echo ignoring strip" +CFLAGS="$CFLAGS -Zomf" +LDFLAGS="-Zomf -Zstack 16384 -s" +SHFLAGS="-Zdll -Zomf" +FFSLDFLAGS="" +LIBPREF="" +LIBSUF=".lib" +SLIBPREF="" +SLIBSUF=".dll" +EXESUF=".exe" +extralibs="" +pkg_requires="" +v4l="no" +v4l2="no" +audio_oss="no" +dv1394="no" +ffserver="no" +vhook="no" +os2="yes" + +;; +*) ;; +esac + +# From MPlayer configure. We need TARGET_OS available +# to the Makefile, so it can distinguish between flavors +# of AltiVec on PowerPC. +TARGET_OS=`( uname -s ) 2>&1` + case "$TARGET_OS" in + Linux|FreeBSD|NetBSD|BSD/OS|OpenBSD|SunOS|QNX|Darwin|GNU|BeOS|MorphOS) + ;; + IRIX*) + TARGET_OS=IRIX + ;; + HP-UX*) + TARGET_OS=HP-UX + ;; + [cC][yY][gG][wW][iI][nN]*) + TARGET_OS=CYGWIN + ;; + *) + TARGET_OS="$TARGET_OS-UNKNOWN" + ;; + esac + +# find source path +source_path="`dirname $0`" +source_path_used="yes" +if test -z "$source_path" -o "$source_path" = "." ; then + source_path=`pwd` + source_path_used="no" +else + source_path="`cd \"$source_path\"; pwd`" +fi + +FFMPEG_CONFIGURATION=" " +for opt do + FFMPEG_CONFIGURATION="$FFMPEG_CONFIGURATION""$opt " +done + +CODEC_LIST=`grep 'register_avcodec(&[a-z]' $source_path/libavcodec/allcodecs.c | sed 's/.*&\(.*\)).*/\1/'` + +for opt do + case "$opt" in + --prefix=*) prefix=`echo $opt | cut -d '=' -f 2`; force_prefix=yes + ;; + --libdir=*) libdir=`echo $opt | cut -d '=' -f 2`; force_libdir=yes + ;; + --incdir=*) incdir=`echo $opt | cut -d '=' -f 2`; + ;; + --mandir=*) mandir=`echo $opt | cut -d '=' -f 2` + ;; + --source-path=*) source_path=`echo $opt | cut -d '=' -f 2` + ;; + --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2` + ;; + --cc=*) cc=`echo $opt | cut -d '=' -f 2-` + ;; + --make=*) make=`echo $opt | cut -d '=' -f 2` + ;; + --extra-cflags=*) CFLAGS="$CFLAGS ${opt#--extra-cflags=}" + ;; + --extra-ldflags=*) LDFLAGS="$LDFLAGS ${opt#--extra-ldflags=}" + ;; + --extra-libs=*) extralibs=${opt#--extra-libs=} + ;; + --build-suffix=*) BUILDSUF=${opt#--build-suffix=} + ;; + --cpu=*) cpu=`echo $opt | cut -d '=' -f 2` + ;; + --tune=*) tune=`echo $opt | cut -d '=' -f 2` + ;; + --powerpc-perf-enable) powerpc_perf="yes" + ;; + --disable-mmx) mmx="no" + ;; + --disable-iwmmxt) iwmmxt="no" + ;; + --disable-altivec) altivec="no" + ;; + --enable-gprof) gprof="yes" + ;; + --disable-v4l) v4l="no" + ;; + --disable-v4l2) v4l2="no" + ;; + --disable-bktr) bktr="no" + ;; + --disable-audio-oss) audio_oss="no" + ;; + --disable-audio-beos) audio_beos="no" + ;; + --disable-dv1394) dv1394="no" + ;; + --disable-network) network="no"; ffserver="no" + ;; + --disable-zlib) zlib="no" + ;; + --disable-lzo) lzo="no" + ;; + --enable-a52) a52="yes" + ;; + --enable-a52bin) a52bin="yes" + ;; + --enable-dts) dts="yes" + extralibs="$extralibs -ldts" + ;; + --enable-pp) pp="yes" + ;; + --enable-libgsm) libgsm="yes" + extralibs="$extralibs -lgsm" + ;; + --enable-mp3lame) mp3lame="yes" + extralibs="$extralibs -lmp3lame" + ;; + --enable-libogg) libogg="yes" + extralibs="$extralibs -logg" + pkg_requires="$pkg_requires ogg >= 1.1" + ;; + --enable-vorbis) vorbis="yes" + extralibs="$extralibs -lvorbis -lvorbisenc" + pkg_requires="$pkg_requires vorbis vorbisenc" + ;; + --enable-theora) theora="yes" + extralibs="$extralibs -ltheora" + pkg_requires="$pkg_requires theora" + ;; + --enable-faad) faad="yes" + extralibs="$extralibs -lfaad" + ;; + --enable-faadbin) faadbin="yes" + ;; + --enable-faac) faac="yes" + extralibs="$extralibs -lfaac" + ;; + --enable-xvid) xvid="yes" + extralibs="$extralibs -lxvidcore" + ;; + --enable-x264) x264="yes" + extralibs="$extralibs -lx264" + ;; + --enable-dc1394) dc1394="yes" + extralibs="$extralibs -ldc1394_control -lraw1394" + pkg_requires="$pkg_requires libraw1394" + ;; + --disable-vhook) vhook="no" + ;; + --disable-simple_idct) simpleidct="no" + ;; + --enable-mingw32) mingw32="yes" + ;; + --enable-mingwce) mingwce="yes" + ;; + --enable-static) lstatic="yes" + ;; + --disable-static) lstatic="no" + ;; + --enable-shared) lshared="yes" + ;; + --disable-shared) lshared="no" + ;; + --disable-debug) debug="no" + ;; + --disable-opts) optimize="no" + ;; + --disable-mpegaudio-hp) mpegaudio_hp="no" + ;; + --disable-protocols) protocols="no"; network="no"; ffserver="no" + ;; + --disable-ffserver) ffserver="no" + ;; + --disable-ffplay) ffplay="no" + ;; + --enable-small) optimize="small" + ;; + --enable-amr_nb) amr_nb="yes" + ;; + --enable-amr_nb-fixed) amr_nb_fixed="yes" + ;; + --enable-amr_wb) amr_wb="yes" + ;; + --enable-amr_if2) amr_if2="yes" + ;; + --enable-sunmlib) sunmlib="yes" + ;; + --enable-pthreads) pthreads="yes" + ;; + --enable-gpl) gpl="yes" + ;; + --enable-memalign-hack) memalignhack="yes" + ;; + --disable-strip) dostrip="no" + ;; + --enable-encoder=*) CODEC_LIST="$CODEC_LIST ${opt#--enable-encoder=}_encoder" + ;; + --enable-decoder=*) CODEC_LIST="$CODEC_LIST ${opt#--enable-decoder=}_decoder" + ;; + --disable-encoder=*) CODEC_LIST="`echo $CODEC_LIST | sed -e \"s#${opt#--disable-encoder=}_encoder##\"`" + ;; + --disable-decoder=*) CODEC_LIST="`echo $CODEC_LIST | sed -e \"s#${opt#--disable-decoder=}_decoder##\"`" + ;; + --disable-encoders) CODEC_LIST="`echo $CODEC_LIST | sed 's/[-_a-zA-Z0-9]*encoder//g'`" + ;; + --disable-decoders) CODEC_LIST="`echo $CODEC_LIST | sed 's/[-_a-zA-Z0-9]*decoder//g'`" + ;; + --disable-muxers) muxers="no"; ffserver="no" + ;; + --disable-demuxers) demuxers="no" + ;; + *) + echo "Unknown option \"$opt\"." + echo "See $0 --help for available options." + exit 1 + ;; + esac +done + +# we need to build at least one lib type +if test "$lstatic" = "no" && test "$lshared" = "no" ; then + cat < $TMPC << EOF + #include + int main( void ) { return 0; } +EOF + + if $cc $CFLAGS -o $TMPE $TMPC 2> /dev/null ; then + cat > $TMPC << EOF + #include + #ifndef FAAD2_VERSION + ok faad1 + #endif + int main( void ) { return 0; } +EOF + if $cc $CFLAGS -o $TMPE $TMPC 2> /dev/null ; then + echo "FAAD2 is under GPL and --enable-gpl is not specified." + fail="yes" + fi + else + faad="no" + faadbin="no" + echo "FAAD test failed." + fi + fi + + + if test "$fail" = "yes"; then + exit 1 + fi +fi + +# compute MMX state +if test $mmx = "default"; then + if test $cpu = "x86" -o $cpu = "x86_64"; then + mmx="yes" + else + mmx="no" + fi +fi + +# check iwmmxt support +if test $iwmmxt = "default" -a $cpu = "armv4l"; then + cat > $TMPC << EOF + int main(void) { + __asm__ __volatile__ ("wunpckelub wr6, wr4"); + } +EOF + + iwmmxt=no + if ${cross_prefix}${cc} -o $TMPO $TMPC 2> /dev/null ; then + iwmmxt=yes + fi +fi + +#Darwin CC versions +needmdynamicnopic="no" +if test $targetos = Darwin; then + if test -n "`$cc -v 2>&1 | grep xlc`"; then + CFLAGS="$CFLAGS -qpdf2 -qlanglvl=extc99 -qmaxmem=-1 -qarch=auto -qtune=auto" + else + gcc_version="`$cc -v 2>&1 | grep version | cut -d ' ' -f3-`" + case "$gcc_version" in + *2.95*) + CFLAGS="$CFLAGS -no-cpp-precomp -pipe -fomit-frame-pointer" + ;; + *[34].*) + CFLAGS="$CFLAGS -no-cpp-precomp -pipe -fomit-frame-pointer -force_cpusubtype_ALL -Wno-sign-compare" + if test "$lshared" = no; then + needmdynamicnopic="yes" + fi + ;; + *) + CFLAGS="$CFLAGS -no-cpp-precomp -pipe -fomit-frame-pointer" + if test "$lshared" = no; then + needmdynamicnopic="yes" + fi + ;; + esac + fi +fi + +# Can only do AltiVec on PowerPC +if test $altivec = "default"; then + if test $cpu = "powerpc"; then + altivec="yes" + else + altivec="no" + fi +fi + +# Add processor-specific flags +TUNECPU="generic" +POWERPCMODE="32bits" +if test $tune != "generic"; then + case $tune in + 601|ppc601|PowerPC601) + CFLAGS="$CFLAGS -mcpu=601" + if test $altivec = "yes"; then + echo "WARNING: Tuning for PPC601 but AltiVec enabled!"; + fi + TUNECPU=ppc601 + ;; + 603*|ppc603*|PowerPC603*) + CFLAGS="$CFLAGS -mcpu=603" + if test $altivec = "yes"; then + echo "WARNING: Tuning for PPC603 but AltiVec enabled!"; + fi + TUNECPU=ppc603 + ;; + 604*|ppc604*|PowerPC604*) + CFLAGS="$CFLAGS -mcpu=604" + if test $altivec = "yes"; then + echo "WARNING: Tuning for PPC604 but AltiVec enabled!"; + fi + TUNECPU=ppc604 + ;; + G3|g3|75*|ppc75*|PowerPC75*) + CFLAGS="$CFLAGS -mcpu=750 -mtune=750 -mpowerpc-gfxopt" + if test $altivec = "yes"; then + echo "WARNING: Tuning for PPC75x but AltiVec enabled!"; + fi + TUNECPU=ppc750 + ;; + G4|g4|745*|ppc745*|PowerPC745*) + CFLAGS="$CFLAGS -mcpu=7450 -mtune=7450 -mpowerpc-gfxopt" + if test $altivec = "no"; then + echo "WARNING: Tuning for PPC745x but AltiVec disabled!"; + fi + TUNECPU=ppc7450 + ;; + 74*|ppc74*|PowerPC74*) + CFLAGS="$CFLAGS -mcpu=7400 -mtune=7400 -mpowerpc-gfxopt" + if test $altivec = "no"; then + echo "WARNING: Tuning for PPC74xx but AltiVec disabled!"; + fi + TUNECPU=ppc7400 + ;; + G5|g5|970|ppc970|PowerPC970|power4*|Power4*) + CFLAGS="$CFLAGS -mcpu=970 -mtune=970 -mpowerpc-gfxopt -mpowerpc64" + if test $altivec = "no"; then + echo "WARNING: Tuning for PPC970 but AltiVec disabled!"; + fi + TUNECPU=ppc970 + POWERPCMODE="64bits" + ;; + i[3456]86|pentium|pentiumpro|pentium-mmx|pentium[234]|prescott|k6|k6-[23]|athlon|athlon-tbird|athlon-4|athlon-[mx]p|winchip-c6|winchip2|c3|nocona|athlon64|k8|opteron|athlon-fx) + CFLAGS="$CFLAGS -march=$tune" + ;; + *) + echo "WARNING: Unknown CPU \"$tune\", ignored." + ;; + esac +fi + +# AltiVec flags: The FSF version of GCC differs from the Apple version +if test $cpu = "powerpc"; then + if test $altivec = "yes"; then + if test -n "`$cc -v 2>&1 | grep version | grep Apple`"; then + CFLAGS="$CFLAGS -faltivec" + else + CFLAGS="$CFLAGS -maltivec -mabi=altivec" + fi + fi +fi + +# check if we have +cat > $TMPC << EOF +#include +int main( void ) { return 0; } +EOF + +_altivec_h="no" +if $cc $CFLAGS -o $TMPE $TMPC 2> /dev/null ; then +_altivec_h="yes" +fi + +# check if our compiler supports Motorola AltiVec C API +if test $altivec = "yes"; then +if test $_altivec_h = "yes"; then +cat > $TMPC << EOF +#include +int main(void) { + vector signed int v1, v2, v3; + v1 = vec_add(v2,v3); + return 0; +} +EOF +else +cat > $TMPC << EOF +int main(void) { + vector signed int v1, v2, v3; + v1 = vec_add(v2,v3); + return 0; +} +EOF +fi +$cc $CFLAGS -o $TMPE $TMPC 2> /dev/null || altivec="no" +fi + +# mmi only available on mips +if test $mmi = "default"; then + if test $cpu = "mips"; then + mmi="yes" + else + mmi="no" + fi +fi + +# check if our compiler supports mmi +if test $mmi = "yes"; then +cat > $TMPC << EOF +int main(void) { + __asm__ ("lq \$2, 0(\$2)"); + return 0; +} +EOF +$cc -o $TMPE $TMPC 2> /dev/null || mmi="no" +fi + +if test "$mingw32" = "yes" -o "$mingwce" = "yes"; then + if test "$lshared" = "yes" && test "$lstatic" = "yes" ; then + cat < $TMPC << EOF +#include +int main(int argc, char ** argv){ + volatile uint32_t i=0x01234567; + return (*((uint8_t*)(&i))) == 0x67; +} +EOF + +if $cc -o $TMPE $TMPC 2>/dev/null ; then +$TMPE && bigendian="yes" +else +echo big/little test failed +fi + +else + +# programs cannot be launched if cross compiling, so make a static guess +if test "$cpu" = "powerpc" -o "$cpu" = "mips" ; then + bigendian="yes" +fi + +fi + +# --- +# *inttypes.h* test +cat > $TMPC << EOF +#include +int main(int argc, char ** argv){ + return 0; +} +EOF + +$cc -o $TMPE $TMPC 2>/dev/null || inttypes="no" + +# --- +# *int_fast* test +cat > $TMPC << EOF +#include +int main(int argc, char ** argv){ + volatile uint_fast64_t i=0x01234567; + return 0; +} +EOF + +$cc -o $TMPE $TMPC 2>/dev/null || emu_fast_int="yes" + +# --- +# check availability of some header files + +cat > $TMPC << EOF +#include +int main( void ) { return 0; } +EOF + +_memalign=no +_malloc_h=no +if $cc -o $TMPE $TMPC 2> /dev/null ; then +_malloc_h=yes +_memalign=yes +# check for memalign - atmos +cat > $TMPC << EOF +#include +#include +int main ( void ) { +char *string = NULL; +string = memalign(64, sizeof(char)); +return 0; +} +EOF +$cc -o $TMPE $TMPC 2> /dev/null || _memalign=no +fi + +if test "$_memalign" = "no" -a "$mmx" = "yes" -a "$memalignhack" != "yes"; then + echo "Error, no memalign() but SSE enabled, disable it or use --enable-memalign-hack." + exit 1 +fi + +cat > $TMPC << EOF +#include +int main( void ) { localtime_r(NULL, NULL); } +EOF + +localtime_r=no +if $cc -o $TMPE $TMPC 2> /dev/null ; then + localtime_r=yes +fi + +if test "$zlib" = "yes"; then +# check for zlib - mmu_man +cat > $TMPC << EOF +#include +int main ( void ) { +if (zlibVersion() != ZLIB_VERSION) + puts("zlib version differs !!!"); + return 1; +return 0; +} +EOF +$cc $CFLAGS $LDFLAGS -o $TMPE $TMPC -lz 2> /dev/null || zlib="no" +# $TMPE 2> /dev/null > /dev/null || zlib="no" +# XXX: more tests needed - runtime test +fi +if test "$zlib" = "yes"; then +extralibs="$extralibs -lz" +fi + +if test "$lzo" = "yes" -a "$gpl" = "yes"; then +# check for liblzo +cat > $TMPC << EOF +#include +int main ( void ) { +lzo_init(); +return 0; +} +EOF +$cc $CFLAGS $LDFLAGS -o $TMPE $TMPC -llzo 2> /dev/null || lzo="no" +else +lzo="no" +fi +if test "$lzo" = "yes"; then +extralibs="$extralibs -llzo" +fi + +# test for lrintf in math.h +cat > $TMPC << EOF +#define _ISOC9X_SOURCE 1 +#include +int main( void ) { return (lrintf(3.999f) > 0)?0:1; } +EOF + +have_lrintf="no" +if $cc $CFLAGS $LDFLAGS -o $TMPE $TMPC $extralibs 2> /dev/null ; then + have_lrintf="yes" + # allanc@chickenandporn.com: cannot execute cross-compiled + # code on the host. Only execute if not cross-compiling. + if test -z "$cross_prefix" ; then + $TMPE 2> /dev/null > /dev/null || have_lrintf="no" + fi +fi + +_restrict= +for restrict_keyword in restrict __restrict__ __restrict; do + echo "void foo(char * $restrict_keyword p);" > $TMPC + if $cc -c -o $TMPO $TMPC 2> /dev/null; then + _restrict=$restrict_keyword + break; + fi +done + +# test gcc version to see if vector builtins can be used +# currently only used on i386 for MMX builtins +cat > $TMPC << EOF +#include +int main(void) { +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2) +return 0; +#else +#error no vector builtins +#endif +} +EOF + +builtin_vector=no +if $cc -msse -o $TMPO $TMPC 2> /dev/null ; then + builtin_vector=yes +fi + +# test for mm3dnow.h +cat > $TMPC << EOF +#include +int main(void) { +return 0; +} +EOF + +mm3dnow=no +if $cc -march=athlon -o $TMPO $TMPC 2> /dev/null ; then + mm3dnow=yes +fi + +# Probe for -Wdeclaration-after-statement +if test "$cc" = "gcc"; then + cat > $TMPC << EOF + int main( void ) { return 0; } +EOF + + if $cc -Wdeclaration-after-statement -Werror -o $TMPE $TMPC 2> /dev/null ; then + CFLAGS="$CFLAGS -Wdeclaration-after-statement" + fi +fi + +# dlopen/dlfcn.h probing + +cat > $TMPC << EOF +#include +int main( void ) { return (int) dlopen("foo", 0); } +EOF + +ldl=-ldl + +if $cc $CFLAGS $LDFLAGS -o $TMPE $TMPC -ldl > /dev/null 2>&1 ; then +dlfcn=yes +dlopen=yes +fi + +if $cc $CFLAGS $LDFLAGS -o $TMPE $TMPC > /dev/null 2>&1 ; then +dlfcn=yes +dlopen=yes +ldl="" +fi + +cat > $TMPC << EOF +int main( void ) { return (int) dlopen("foo", 0); } +EOF + +if $cc $CFLAGS $LDFLAGS -o $TMPE $TMPC -ldl > /dev/null 2>&1 ; then +dlopen=yes +fi + +if $cc $CFLAGS $LDFLAGS -o $TMPE $TMPC > /dev/null 2>&1 ; then +dlopen=yes +ldl="" +fi + +if test "$vhook" = "default" ; then + vhook="$dlopen" +fi + +if test "$vhook" = "yes" -o "$a52bin" = "yes" -o "$faadbin" = "yes"; then + extralibs="$extralibs $ldl" +fi + + +########################################## +# imlib check + +cat > $TMPC << EOF +#include +#include +int main( void ) { return (int) imlib_load_font("foo"); } +EOF + +imlib2=no +if $cc $CFLAGS $LDFLAGS -o $TMPE $TMPC -lImlib2 -lm > /dev/null 2>&1 ; then +imlib2=yes +fi + +########################################## +# FreeType check + +cat > $TMPC << EOF +#include +int main( void ) { return (int) FT_Init_FreeType(0); } +EOF + +freetype2=no +if test "x$targetos" != "xBeOS"; then + if (freetype-config --version) >/dev/null 2>&1 ; then + if $cc -o $TMPE $TMPC `freetype-config --cflags` `freetype-config --libs` > /dev/null 2>&1 ; then + freetype2=yes + fi + fi +fi + +########################################## +# SDL check + +cat > $TMPC << EOF +#include +#undef main /* We don't want SDL to override our main() */ +int main( void ) { return SDL_Init (SDL_INIT_VIDEO); } +EOF + +sdl_too_old=no +sdl=no +SDL_CONFIG="${cross_prefix}sdl-config" +if ("${SDL_CONFIG}" --version) >/dev/null 2>&1 ; then +if $cc -o $TMPE `"${SDL_CONFIG}" --cflags` $TMPC `"${SDL_CONFIG}" --libs` > /dev/null 2>&1 ; then +_sdlversion=`"${SDL_CONFIG}" --version | sed 's/[^0-9]//g'` +if test "$_sdlversion" -lt 121 ; then +sdl_too_old=yes +else +sdl=yes +fi +fi +fi + +########################################## +# texi2html check + +texi2html=no +if (texi2html -version) >/dev/null 2>&1; then +texi2html=yes +fi + +if test "$network" = "yes" ; then +########################################## +# IPv6 check + +cat > $TMPC << EOF +#include +#include +#include +#include +int main( void ) { + struct sockaddr_storage saddr; + struct ipv6_mreq mreq6; + getaddrinfo(0,0,0,0); + getnameinfo(0,0,0,0,0,0,0); + IN6_IS_ADDR_MULTICAST((const struct in6_addr *)0); +} +EOF + +ipv6=no +if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then +ipv6=yes +fi +fi + +if test "$v4l2" = "yes"; then +# check for video4linux2 --- V4L2_PIX_FMT_YUV420 +cat > $TMPC << EOF +#include +#include +int dummy = V4L2_PIX_FMT_YUV420; +struct v4l2_buffer dummy1; +EOF +$cc -c -o $TMPE $TMPC 2> /dev/null || v4l2="no" +fi + +case "`$cc -v 2>&1 | grep version`" in + *gcc*) + CFLAGS="-Wall -Wno-switch $CFLAGS" + ;; + *) + ;; +esac + +if test "$sdl" = "no" ; then + ffplay=no +fi + +if test "$debug" = "yes"; then + CFLAGS="-g $CFLAGS" +fi + +if test "$optimize" = "small"; then +# CFLAGS=${CFLAGS//-O3/-Os} + CFLAGS="$CFLAGS -Os" +fi + +if test "$optimize" = "yes"; then + if test -n "`$cc -v 2>&1 | grep xlc`"; then + CFLAGS="$CFLAGS -O5" + LDFLAGS="$LDFLAGS -O5" + else + CFLAGS="-O3 $CFLAGS" + fi +fi + +# PIC flags for shared library objects where they are needed +if test "$lshared" = "yes" ; then + # LIBOBJFLAGS may have already been set in the OS configuration + if test -z "$LIBOBJFLAGS" ; then + if test "$cpu" = "x86_64" -o "$cpu" = "ia64" -o "$cpu" = "alpha" ; then + LIBOBJFLAGS="\$(PIC)" + fi + fi +fi + +if test x"$bindir" = x""; then +bindir="${prefix}/bin" +fi + +if test x"$libdir" = x""; then +libdir="${prefix}/lib" +fi + +if test x"$incdir" = x""; then +incdir="${prefix}/include/ffmpeg" +fi + +if test x"$mandir" = x""; then +mandir="${prefix}/man" +fi + +echo "install prefix $prefix" +echo "source path $source_path" +echo "C compiler $cc" +echo "make $make" +echo "CPU $cpu ($tune)" +if test "$BUILDSUF" != ""; then +echo "build suffix $BUILDSUF" +fi +echo "big-endian $bigendian" +echo "inttypes.h $inttypes" +echo "broken inttypes.h $emu_fast_int" +if test $cpu = "x86" -o $cpu = "x86_64"; then +echo "MMX enabled $mmx" +echo "Vector Builtins $builtin_vector" +echo "3DNow! Builtins $mm3dnow" +fi +if test $cpu = "armv4l"; then +echo "IWMMXT enabled $iwmmxt" +fi +if test $cpu = "mips"; then +echo "MMI enabled $mmi" +fi +if test $cpu = "powerpc"; then +echo "AltiVec enabled $altivec" +fi +echo "gprof enabled $gprof" +echo "zlib enabled $zlib" +echo "lzo enabled $lzo" +echo "libgsm enabled $libgsm" +echo "mp3lame enabled $mp3lame" +echo "libogg enabled $libogg" +echo "Vorbis enabled $vorbis" +echo "Theora enabled $theora" +echo "FAAD enabled $faad" +echo "faadbin enabled $faadbin" +echo "FAAC enabled $faac" +echo "XviD enabled $xvid" +echo "x264 enabled $x264" +echo "a52 support $a52" +echo "a52 dlopened $a52bin" +echo "DTS support $dts" +echo "pp support $pp" +echo "debug symbols $debug" +echo "strip symbols $dostrip" +echo "optimize $optimize" +echo "static $lstatic" +echo "shared $lshared" +echo "video hooking $vhook" +echo "SDL support $sdl" +if test $sdl_too_old = "yes"; then +echo "-> Your SDL version is too old - please upgrade to have FFplay/SDL support." +fi + +if test "$vhook" = "yes" ; then +echo "Imlib2 support $imlib2" +echo "FreeType support $freetype2" +fi +echo "Sun medialib support" $sunmlib +echo "pthreads support" $pthreads +echo "AMR-NB float support" $amr_nb +echo "AMR-NB fixed support" $amr_nb_fixed +echo "AMR-WB float support" $amr_wb +echo "AMR-WB IF2 support" $amr_if2 +echo "network support $network" +if test "$network" = "yes" ; then +echo "IPv6 support $ipv6" +fi +if test "$gpl" = "no" ; then +echo "License: LGPL" +else +echo "License: GPL" +fi + +echo "Creating config.mak and config.h..." + +date >> config.log +echo " $0 $FFMPEG_CONFIGURATION" >> config.log +echo "# Automatically generated by configure - do not modify!" > config.mak +echo "/* Automatically generated by configure - do not modify! */" > $TMPH +echo "#define FFMPEG_CONFIGURATION "'"'"$FFMPEG_CONFIGURATION"'"' >> $TMPH + +echo "prefix=\$(DESTDIR)$prefix" >> config.mak +echo "libdir=\$(DESTDIR)$libdir" >> config.mak +echo "incdir=\$(DESTDIR)$incdir" >> config.mak +echo "bindir=\$(DESTDIR)$bindir" >> config.mak +echo "mandir=\$(DESTDIR)$mandir" >> config.mak +echo "MAKE=$make" >> config.mak +echo "CC=$cc" >> config.mak +echo "AR=$ar" >> config.mak +echo "RANLIB=$ranlib" >> config.mak +if test "$dostrip" = "yes" ; then +echo "STRIP=$strip" >> config.mak +echo "INSTALLSTRIP=$installstrip" >> config.mak +else +echo "STRIP=echo ignoring strip" >> config.mak +echo "INSTALLSTRIP=" >> config.mak +fi + +# SHCFLAGS is a copy of CFLAGS without -mdynamic-no-pic, used when building +# shared modules on OS/X (vhook/Makefile). +SHCFLAGS=$CFLAGS +if test "$needmdynamicnopic" = yes; then + CFLAGS="$CFLAGS -mdynamic-no-pic" +fi + +echo "OPTFLAGS=$CFLAGS" >> config.mak +echo "SHCFLAGS=$SHCFLAGS">>config.mak +echo "LDFLAGS=$LDFLAGS" >> config.mak +echo "LDCONFIG=$LDCONFIG" >> config.mak +echo "FFSLDFLAGS=$FFSLDFLAGS" >> config.mak +echo "SHFLAGS=$SHFLAGS" >> config.mak +echo "LIBOBJFLAGS=$LIBOBJFLAGS" >> config.mak +echo "BUILD_STATIC=$lstatic" >> config.mak +echo "BUILDSUF=$BUILDSUF" >> config.mak +echo "LIBPREF=$LIBPREF" >> config.mak +echo "LIBSUF=\${BUILDSUF}$LIBSUF" >> config.mak +if test "$lstatic" = "yes" ; then + echo "LIB=$LIB" >> config.mak +else # Some Make complain if this variable does not exist. + echo "LIB=" >> config.mak +fi +echo "SLIBPREF=$SLIBPREF" >> config.mak +echo "SLIBSUF=\${BUILDSUF}$SLIBSUF" >> config.mak +echo "EXESUF=\${BUILDSUF}$EXESUF" >> config.mak +echo "TARGET_OS=$TARGET_OS" >> config.mak +if test "$cpu" = "x86" ; then + echo "TARGET_ARCH_X86=yes" >> config.mak + echo "#define ARCH_X86 1" >> $TMPH +elif test "$cpu" = "x86_64" ; then + echo "TARGET_ARCH_X86_64=yes" >> config.mak + echo "#define ARCH_X86_64 1" >> $TMPH +elif test "$cpu" = "armv4l" ; then + echo "TARGET_ARCH_ARMV4L=yes" >> config.mak + echo "#define ARCH_ARMV4L 1" >> $TMPH +elif test "$cpu" = "alpha" ; then + echo "TARGET_ARCH_ALPHA=yes" >> config.mak + echo "#define ARCH_ALPHA 1" >> $TMPH +elif test "$cpu" = "sparc64" ; then + echo "TARGET_ARCH_SPARC64=yes" >> config.mak + echo "#define ARCH_SPARC64 1" >> $TMPH + echo "TARGET_ARCH_SPARC=yes" >> config.mak + echo "#define ARCH_SPARC 1" >> $TMPH +elif test "$cpu" = "sparc" ; then + echo "TARGET_ARCH_SPARC=yes" >> config.mak + echo "#define ARCH_SPARC 1" >> $TMPH +elif test "$cpu" = "powerpc" ; then + echo "TARGET_ARCH_POWERPC=yes" >> config.mak + echo "#define ARCH_POWERPC 1" >> $TMPH + if test $POWERPCMODE = "32bits"; then + echo "#define POWERPC_MODE_32BITS 1" >> $TMPH + else + echo "#define POWERPC_MODE_64BITS 1" >> $TMPH + fi + if test "$powerpc_perf" = "yes"; then + echo "#define POWERPC_PERFORMANCE_REPORT 1" >> $TMPH + fi +elif test "$cpu" = "mips" ; then + echo "TARGET_ARCH_MIPS=yes" >> config.mak + echo "#define ARCH_MIPS 1" >> $TMPH +elif test "$cpu" = "sh4" ; then + echo "TARGET_ARCH_SH4=yes" >> config.mak + echo "#define ARCH_SH4 1" >> $TMPH +elif test "$cpu" = "parisc" ; then + echo "TARGET_ARCH_PARISC=yes" >> config.mak + echo "#define ARCH_PARISC 1" >> $TMPH +elif test "$cpu" = "s390" ; then + echo "TARGET_ARCH_S390=yes" >> config.mak + echo "#define ARCH_S390 1" >> $TMPH +elif test "$cpu" = "m68k" ; then + echo "TARGET_ARCH_M68K=yes" >> config.mak + echo "#define ARCH_M68K 1" >> $TMPH +elif test "$cpu" = "ia64" ; then + echo "TARGET_ARCH_IA64=yes" >> config.mak + echo "#define ARCH_IA64 1" >> $TMPH +fi +echo "#define TUNECPU $TUNECPU" >> $TMPH +if test "$bigendian" = "yes" ; then + echo "WORDS_BIGENDIAN=yes" >> config.mak + echo "#define WORDS_BIGENDIAN 1" >> $TMPH +fi +if test "$inttypes" != "yes" ; then + echo "#define EMULATE_INTTYPES 1" >> $TMPH +fi +if test "$emu_fast_int" = "yes" ; then + echo "#define EMULATE_FAST_INT 1" >> $TMPH +fi +if test "$mmx" = "yes" ; then + echo "TARGET_MMX=yes" >> config.mak + echo "#define HAVE_MMX 1" >> $TMPH + echo "#define __CPU__ 586" >> $TMPH +fi +if test "$builtin_vector" = "yes" ; then + echo "TARGET_BUILTIN_VECTOR=yes" >> config.mak + echo "#define HAVE_BUILTIN_VECTOR 1" >> $TMPH +fi +if test "$mm3dnow" = "yes" ; then + echo "TARGET_BUILTIN_3DNOW=yes" >> config.mak + echo "#define HAVE_MM3DNOW 1" >> $TMPH +fi +if test "$iwmmxt" = "yes" ; then + echo "TARGET_IWMMXT=yes" >> config.mak + echo "#define HAVE_IWMMXT 1" >> $TMPH +fi +if test "$mmi" = "yes" ; then + echo "TARGET_MMI=yes" >> config.mak + echo "#define HAVE_MMI 1" >> $TMPH +fi +if test "$altivec" = "yes" ; then + echo "TARGET_ALTIVEC=yes" >> config.mak + echo "#define HAVE_ALTIVEC 1" >> $TMPH + echo "// Enable the next line to use the reference C code instead of AltiVec" >> $TMPH + echo "// #define ALTIVEC_USE_REFERENCE_C_CODE 1" >> $TMPH + if test "$_altivec_h" = "yes" ; then + echo "#define HAVE_ALTIVEC_H 1" >> $TMPH + else + echo "#undef HAVE_ALTIVEC_H" >> $TMPH + fi +fi +if test "$gprof" = "yes" ; then + echo "TARGET_GPROF=yes" >> config.mak + echo "#define HAVE_GPROF 1" >> $TMPH +fi +if test "$localtime_r" = "yes" ; then + echo "#define HAVE_LOCALTIME_R 1" >> $TMPH +fi +if test "$imlib2" = "yes" ; then + echo "HAVE_IMLIB2=yes" >> config.mak +fi +if test "$freetype2" = "yes" ; then + echo "HAVE_FREETYPE2=yes" >> config.mak +fi +if test "$sunmlib" = "yes" ; then + echo "HAVE_MLIB=yes" >> config.mak + echo "#define HAVE_MLIB 1" >> $TMPH + extralibs="$extralibs -lmlib" +fi +if test "$pthreads" = "yes" ; then + echo "HAVE_PTHREADS=yes" >> config.mak + echo "#define HAVE_PTHREADS 1" >> $TMPH + echo "#define HAVE_THREADS 1" >> $TMPH + if test $targetos != FreeBSD -a $targetos != OpenBSD ; then + extralibs="$extralibs -lpthread" + fi +fi +if test "$sdl" = "yes" ; then + echo "CONFIG_SDL=yes" >> config.mak + echo "SDL_LIBS=`"${SDL_CONFIG}" --libs`" >> config.mak + echo "SDL_CFLAGS=`"${SDL_CONFIG}" --cflags`" >> config.mak +fi +if test "$texi2html" = "yes"; then + echo "BUILD_DOC=yes" >> config.mak +fi +if test "$have_lrintf" = "yes" ; then + echo "#define HAVE_LRINTF 1" >> $TMPH +fi +if test "$vhook" = "yes" ; then + echo "BUILD_VHOOK=yes" >> config.mak + echo "#define HAVE_VHOOK 1" >> $TMPH +fi + +pp_version=`grep '#define LIBPOSTPROC_VERSION ' "$source_path/libavcodec/libpostproc/postprocess.h" | sed 's/[^0-9\.]//g'` +lavc_version=`grep '#define LIBAVCODEC_VERSION ' "$source_path/libavcodec/avcodec.h" | sed 's/[^0-9\.]//g'` +lavf_version=`grep '#define LIBAVFORMAT_VERSION ' "$source_path/libavformat/avformat.h" | sed 's/[^0-9\.]//g'` +lavu_version=`grep '#define LIBAVUTIL_VERSION ' "$source_path/libavutil/avutil.h" | sed 's/[^0-9\.]//g'` + + + +if test "$lshared" = "yes" ; then + echo "#define BUILD_SHARED_AV 1" >> $TMPH + echo "BUILD_SHARED=yes" >> config.mak + echo "PIC=-fPIC -DPIC" >> config.mak + echo "SPPMAJOR=${lavc_version%%.*}" >> config.mak + echo "SPPVERSION=$lavc_version" >> config.mak + echo "LAVCMAJOR=${lavc_version%%.*}" >> config.mak + echo "LAVCVERSION=$lavc_version" >> config.mak + echo "LAVFMAJOR=${lavf_version%%.*}" >> config.mak + echo "LAVFVERSION=$lavf_version" >> config.mak + echo "LAVUMAJOR=${lavu_version%%.*}" >> config.mak + echo "LAVUVERSION=$lavu_version" >> config.mak + echo "SLIBNAME=${SLIBNAME}" >> config.mak + echo "SLIBNAME_WITH_VERSION=${SLIBNAME_WITH_VERSION}" >> config.mak + echo "SLIBNAME_WITH_MAJOR=${SLIBNAME_WITH_MAJOR}" >> config.mak +fi +echo "EXTRALIBS=$extralibs" >> config.mak +version=`grep '#define FFMPEG_VERSION ' "$source_path/libavcodec/avcodec.h" | + cut -d '"' -f 2` +echo "VERSION=$version" >>config.mak +# If you do not want to use encoders, disable them. +echo "#define CONFIG_ENCODERS 1" >> $TMPH +echo "CONFIG_ENCODERS=yes" >> config.mak + +# If you do not want to use decoders, disable them. +echo "#define CONFIG_DECODERS 1" >> $TMPH +echo "CONFIG_DECODERS=yes" >> config.mak + +# muxers +if test "$muxers" = "yes" ; then + echo "#define CONFIG_MUXERS 1" >> $TMPH + echo "CONFIG_MUXERS=yes" >> config.mak +fi + +# demuxers +if test "$demuxers" = "yes" ; then + echo "#define CONFIG_DEMUXERS 1" >> $TMPH + echo "CONFIG_DEMUXERS=yes" >> config.mak +fi + +# AC3 +if test "$a52" = "yes" ; then + echo "#define CONFIG_AC3 1" >> $TMPH + echo "CONFIG_AC3=yes" >> config.mak + + if test "$a52bin" = "yes" ; then + echo "#define CONFIG_A52BIN 1" >> $TMPH + echo "CONFIG_A52BIN=yes" >> config.mak + fi +fi + +# DTS +if test "$dts" = "yes" ; then + echo "#define CONFIG_DTS 1" >> $TMPH + echo "CONFIG_DTS=yes" >> config.mak +fi + +# PP +if test "$pp" = "yes" ; then + echo "#define CONFIG_PP 1" >> $TMPH + echo "CONFIG_PP=yes" >> config.mak +fi + +# MPEG audio high precision mode +if test "$mpegaudio_hp" = "yes" ; then + echo "#define CONFIG_MPEGAUDIO_HP 1" >> $TMPH +fi + +if test "$v4l" = "yes" ; then + echo "#define CONFIG_VIDEO4LINUX 1" >> $TMPH + echo "CONFIG_VIDEO4LINUX=yes" >> config.mak +fi + +if test "$v4l2" = "yes" ; then + echo "#define CONFIG_VIDEO4LINUX2 1" >> $TMPH + echo "CONFIG_VIDEO4LINUX2=yes" >> config.mak +fi + +if test "$bktr" = "yes" ; then + echo "#define CONFIG_BKTR 1" >> $TMPH + echo "CONFIG_BKTR=yes" >> config.mak +fi + +if test "$dv1394" = "yes" ; then + echo "#define CONFIG_DV1394 1" >> $TMPH + echo "CONFIG_DV1394=yes" >> config.mak +fi + +if test "$dc1394" = "yes" ; then + echo "#define CONFIG_DC1394 1" >> $TMPH + echo "CONFIG_DC1394=yes" >> config.mak +fi + +if test "$dlopen" = "yes" ; then + echo "#define CONFIG_HAVE_DLOPEN 1" >> $TMPH +fi + +if test "$dlfcn" = "yes" ; then + echo "#define CONFIG_HAVE_DLFCN 1" >> $TMPH +fi + +if test "$audio_oss" = "yes" ; then + echo "#define CONFIG_AUDIO_OSS 1" >> $TMPH + echo "CONFIG_AUDIO_OSS=yes" >> config.mak +fi + +if test "$audio_beos" = "yes" ; then + echo "#define CONFIG_AUDIO_BEOS 1" >> $TMPH + echo "CONFIG_AUDIO_BEOS=yes" >> config.mak +fi + +if test "$network" = "yes" ; then + echo "#define CONFIG_NETWORK 1" >> $TMPH + echo "CONFIG_NETWORK=yes" >> config.mak +fi + +if test "$ipv6" = "yes" ; then + echo "#define CONFIG_IPV6 1" >> $TMPH +fi + +if test "$zlib" = "yes" ; then + echo "#define CONFIG_ZLIB 1" >> $TMPH + echo "CONFIG_ZLIB=yes" >> config.mak +fi + +if test "$lzo" = "yes" ; then + echo "#define CONFIG_LZO 1" >> $TMPH + echo "CONFIG_LZO=yes" >> config.mak +fi + +if test "$libgsm" = "yes" ; then + echo "#define CONFIG_LIBGSM 1" >> $TMPH + echo "CONFIG_LIBGSM=yes" >> config.mak +fi + +if test "$mp3lame" = "yes" ; then + echo "#define CONFIG_MP3LAME 1" >> $TMPH + echo "CONFIG_MP3LAME=yes" >> config.mak +fi + +if test "$libogg" = "yes" ; then + echo "#define CONFIG_LIBOGG 1" >> $TMPH + echo "CONFIG_LIBOGG=yes" >> config.mak +fi + +if test "$vorbis" = "yes" ; then + echo "#define CONFIG_LIBVORBIS 1" >> $TMPH + echo "CONFIG_LIBVORBIS=yes" >> config.mak +fi + +if test "$theora" = "yes" ; then + echo "#define CONFIG_LIBTHEORA 1" >> $TMPH + echo "CONFIG_LIBTHEORA=yes" >> config.mak +fi + +if test "$faad" = "yes" ; then + echo "#define CONFIG_FAAD 1" >> $TMPH + echo "CONFIG_FAAD=yes" >> config.mak +fi + +if test "$faadbin" = "yes" ; then + echo "#define CONFIG_FAADBIN 1" >> $TMPH + echo "CONFIG_FAADBIN=yes" >> config.mak +fi + +if test "$faac" = "yes" ; then + echo "#define CONFIG_FAAC 1" >> $TMPH + echo "CONFIG_FAAC=yes" >> config.mak +fi + +if test "$xvid" = "yes" ; then + echo "#define CONFIG_XVID 1" >> $TMPH + echo "CONFIG_XVID=yes" >> config.mak +fi + +if test "$x264" = "yes" ; then + echo "#define CONFIG_X264 1" >> $TMPH + echo "CONFIG_X264=yes" >> config.mak +fi + +if test "$mingw32" = "yes" ; then + echo "#define CONFIG_WIN32 1" >> $TMPH + echo "CONFIG_WIN32=yes" >> config.mak + echo "HAVE_W32THREADS=yes" >> config.mak + echo "#define HAVE_W32THREADS 1" >> $TMPH + echo "#define HAVE_THREADS 1" >> $TMPH + echo "#ifndef __MINGW32__" >> $TMPH + echo "#define __MINGW32__ 1" >> $TMPH + echo "#endif" >> $TMPH +fi + +if test "$mingwce" = "yes" ; then + echo "#define CONFIG_WIN32 1" >> $TMPH + echo "CONFIG_WIN32=yes" >> config.mak + echo "#define CONFIG_WINCE 1" >> $TMPH + echo "CONFIG_WINCE=yes" >> config.mak + echo "#ifndef __MINGW32__" >> $TMPH + echo "#define __MINGW32__ 1" >> $TMPH + echo "#endif" >> $TMPH +fi + +if test "$os2" = "yes" ; then + echo "#define CONFIG_OS2 1" >> $TMPH + echo "CONFIG_OS2=yes" >> config.mak + echo "HAVE_OS2THREADS=yes" >> config.mak + echo "#define HAVE_OS2THREADS 1" >> $TMPH + echo "#define HAVE_THREADS 1" >> $TMPH +fi + +if test "$TARGET_OS" = "SunOS" ; then + echo "#define CONFIG_SUNOS 1" >> $TMPH +fi + +if test "$TARGET_OS" = "BeOS" ; then + echo "HAVE_BEOSTHREADS=yes" >> config.mak + echo "#define HAVE_BEOSTHREADS 1" >> $TMPH + echo "#define HAVE_THREADS 1" >> $TMPH +fi + +if test "$darwin" = "yes"; then + echo "#define CONFIG_DARWIN 1" >> $TMPH + echo "CONFIG_DARWIN=yes" >> config.mak +fi + +if test "$_malloc_h" = "yes" ; then + echo "#define HAVE_MALLOC_H 1" >> $TMPH +else + echo "#undef HAVE_MALLOC_H" >> $TMPH +fi + +if test "$_memalign" = "yes" ; then + echo "#define HAVE_MEMALIGN 1" >> $TMPH +else + echo "#undef HAVE_MEMALIGN" >> $TMPH +fi + +if test "$memalignhack" = "yes" ; then + echo "#define MEMALIGN_HACK 1" >> $TMPH +fi + + +if test "$netserver" = "yes" ; then + echo "#define CONFIG_BEOS_NETSERVER 1" >> $TMPH + echo "CONFIG_BEOS_NETSERVER=yes" >> config.mak +fi + +if test "$need_inet_aton" = "yes" ; then + echo "NEED_INET_ATON=yes" >> config.mak +fi + +if test "$simpleidct" = "yes" ; then + echo "#define SIMPLE_IDCT 1" >> $TMPH +fi + +if test "$protocols" = "yes" ; then + echo "#define CONFIG_PROTOCOLS 1" >> $TMPH + echo "CONFIG_PROTOCOLS=yes" >> config.mak +fi + +if test "$ffserver" = "yes" ; then + echo "#define CONFIG_FFSERVER 1" >> $TMPH + echo "CONFIG_FFSERVER=yes" >> config.mak +fi + +if test "$ffplay" = "yes" ; then + echo "CONFIG_FFPLAY=yes" >> config.mak +fi + +if test "$gpl" = "yes" ; then + echo "#define CONFIG_GPL 1" >> $TMPH + echo "CONFIG_GPL=yes" >> config.mak +fi + +echo "#define restrict $_restrict" >> $TMPH + +if test "$optimize" = "small"; then + echo "#define always_inline" >> $TMPH +fi + +# build tree in object directory if source path is different from current one +if test "$source_path_used" = "yes" ; then + DIRS="\ + doc \ + libavformat \ + libavcodec \ + libavcodec/alpha \ + libavcodec/armv4l \ + libavcodec/i386 \ + libavcodec/sparc \ + libavcodec/mlib \ + libavcodec/ppc \ + libavcodec/liba52 \ + libavcodec/libpostproc \ + libavutil \ + tests \ + vhook \ + " + FILES="\ + Makefile \ + libavformat/Makefile \ + libavcodec/Makefile \ + libavcodec/libpostproc/Makefile \ + libavutil/Makefile \ + tests/Makefile \ + vhook/Makefile \ + doc/Makefile \ + doc/texi2pod.pl \ + " + for dir in $DIRS ; do + mkdir -p $dir + done + for f in $FILES ; do + ln -sf "$source_path/$f" $f + done +fi +echo "SRC_PATH=$source_path" >> config.mak +echo "BUILD_ROOT=$PWD" >> config.mak + +if test "$amr_wb" = "yes" ; then + echo "#define AMR_WB 1" >> $TMPH + echo "AMR_WB=yes" >> config.mak + echo + echo "AMR WB FLOAT NOTICE ! Make sure you have downloaded TS26.204" + echo "V5.1.0 from " + echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-510.zip" + echo "and extracted the source to libavcodec/amrwb_float" + echo +fi + +if test "$amr_nb" = "yes" ; then + echo "#define AMR_NB 1" >> $TMPH + echo "AMR_NB=yes" >> config.mak + echo +if test "$amr_nb_fixed" = "yes" ; then + echo "AMR_NB_FIXED=yes" >> config.mak + echo "#define AMR_NB_FIXED 1" >> $TMPH + echo + echo "AMR NB FIXED POINT NOTICE! Make sure you have downloaded TS26.073 " + echo "REL-5 version 5.1.0 from " + echo "http://www.3gpp.org/ftp/Specs/latest/Rel-5/26_series/26073-5??.zip" + echo "and extracted src to libavcodec/amr" + echo "You must also add -DMMS_IO and remove -pedantic-errors to/from CFLAGS in libavcodec/amr/makefile." + echo "i.e. CFLAGS = -Wall -I. \$(CFLAGS_\$(MODE)) -D\$(VAD) -DMMS_IO" + echo +else + echo "AMR NB FLOAT NOTICE ! Make sure you have downloaded TS26.104" + echo "REL-5 V5.1.0 from " + echo "http://www.3gpp.org/ftp/Specs/latest/Rel-5/26_series/26104-5??.zip" + echo "and extracted the source to libavcodec/amr_float" + echo "If you try this on alpha, you may need to change Word32 to int in amr/typedef.h" + echo +fi + +if test "$amr_if2" = "yes" ; then + echo "AMR_CFLAGS=-DIF2=1" >> config.mak +fi + +fi + +for codec in $CODEC_LIST ; do + echo "#define CONFIG_`echo $codec | tr a-z A-Z` 1" >> $TMPH + echo "CONFIG_`echo $codec | tr a-z A-Z`=yes" >> config.mak +done + +# Do not overwrite config.h if unchanged to avoid superfluous rebuilds. +diff $TMPH config.h >/dev/null 2>&1 +if test "$?" != "0" ; then + mv -f $TMPH config.h +else + echo "config.h is unchanged" +fi + +rm -f $TMPO $TMPC $TMPE $TMPS $TMPH + + +# build pkg-config files libav*.pc and libpostproc.pc +# libavutil.pc +cat <libavutil.pc +prefix=$prefix +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libavutil +Description: FFmpeg utility library +Version: $lavu_version +Requires: +Conflicts: +Libs: -L\${libdir} -lavutil +Cflags: -I\${includedir} -I\${includedir}/ffmpeg +EOF + +cat <libavutil-uninstalled.pc +prefix= +exec_prefix= +libdir=\${pcfiledir}/libavutil +includedir=\${pcfiledir}/libavutil + +Name: libavutil +Description: FFmpeg utility library +Version: $lavu_version +Requires: +Conflicts: +Libs: \${libdir}/${LIBPREF}avutil${LIBSUF} +Cflags: -I\${includedir} +EOF + +# libavcodec.pc +cat <libavcodec.pc +prefix=$prefix +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libavcodec +Description: FFmpeg codec library +Version: $lavc_version +Requires: $pkg_requires libavutil = $lavu_version +Conflicts: +Libs: -L\${libdir} -lavcodec $extralibs +Cflags: -I\${includedir} -I\${includedir}/ffmpeg +EOF + +cat <libavcodec-uninstalled.pc +prefix= +exec_prefix= +libdir=\${pcfiledir}/libavcodec +includedir=\${pcfiledir}/libavcodec + +Name: libavcodec +Description: FFmpeg codec library +Version: $lavc_version +Requires: $pkg_requires libavutil = $lavu_version +Conflicts: +Libs: \${libdir}/${LIBPREF}avcodec${LIBSUF} $extralibs +Cflags: -I\${includedir} +EOF + +# libavformat.pc +cat <libavformat.pc +prefix=$prefix +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libavformat +Description: FFmpeg container format library +Version: $lavf_version +Requires: $pkg_requires libavcodec = $lavc_version +Conflicts: +Libs: -L\${libdir} -lavformat $extralibs +Cflags: -I\${includedir} -I\${includedir}/ffmpeg +EOF + +cat <libavformat-uninstalled.pc +prefix= +exec_prefix= +libdir=\${pcfiledir}/libavformat +includedir=\${pcfiledir}/libavformat + +Name: libavformat +Description: FFmpeg container format library +Version: $lavf_version +Requires: $pkg_requires libavcodec = $lavc_version +Conflicts: +Libs: \${libdir}/${LIBPREF}avformat${LIBSUF} $extralibs +Cflags: -I\${includedir} +EOF + + +# libpostproc.pc +cat <libpostproc.pc +prefix=$prefix +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libpostproc +Description: FFmpeg post processing library +Version: $lavc_version +Requires: +Conflicts: +Libs: -L\${libdir} -lpostproc +Cflags: -I\${includedir} -I\${includedir}/postproc +EOF + +cat <libpostproc-uninstalled.pc +prefix= +exec_prefix= +libdir=\${pcfiledir}/libavcodec/libpostproc +includedir=\${pcfiledir}/libavcodec/libpostproc + +Name: libpostproc +Description: FFmpeg post processing library +Version: $lavc_version +Requires: +Conflicts: +Libs: \${libdir}/${LIBPREF}postproc${LIBSUF} +Cflags: -I\${includedir} +EOF diff --git a/mpeg4/src/cws2fws.c b/mpeg4/src/cws2fws.c new file mode 100644 index 00000000..eb02f581 --- /dev/null +++ b/mpeg4/src/cws2fws.c @@ -0,0 +1,126 @@ +/* + * cws2fws by Alex Beregszaszi + * + * This utility converts compressed Macromedia Flash files to uncompressed ones. + * + */ + +#include +#include +#include +#include + +#ifdef DEBUG +#define dbgprintf printf +#else +#define dbgprintf +#endif + +main(int argc, char *argv[]) +{ + int fd_in, fd_out, comp_len, uncomp_len, tag, i, last_out; + char buf_in[1024], buf_out[65536]; + z_stream zstream; + struct stat statbuf; + + if (argc < 3) + { + printf("Usage: %s \n", argv[0]); + exit(1); + } + + fd_in = open(argv[1], O_RDONLY); + if (fd_in < 0) + { + perror("Error while opening: "); + exit(1); + } + + fd_out = open(argv[2], O_WRONLY|O_CREAT, 00644); + if (fd_out < 0) + { + perror("Error while opening: "); + close(fd_in); + exit(1); + } + + if (read(fd_in, &buf_in, 8) != 8) + { + printf("Header error\n"); + close(fd_in); + close(fd_out); + exit(1); + } + + if (buf_in[0] != 'C' || buf_in[1] != 'W' || buf_in[2] != 'S') + { + printf("Not a compressed flash file\n"); + exit(1); + } + + fstat(fd_in, &statbuf); + comp_len = statbuf.st_size; + uncomp_len = buf_in[4] | (buf_in[5] << 8) | (buf_in[6] << 16) | (buf_in[7] << 24); + + printf("Compressed size: %d Uncompressed size: %d\n", comp_len-4, uncomp_len-4); + + // write out modified header + buf_in[0] = 'F'; + write(fd_out, &buf_in, 8); + + zstream.zalloc = NULL; + zstream.zfree = NULL; + zstream.opaque = NULL; + inflateInit(&zstream); + + for (i = 0; i < comp_len-8;) + { + int ret, len = read(fd_in, &buf_in, 1024); + + dbgprintf("read %d bytes\n", len); + + last_out = zstream.total_out; + + zstream.next_in = &buf_in[0]; + zstream.avail_in = len; + zstream.next_out = &buf_out[0]; + zstream.avail_out = 65536; + + ret = inflate(&zstream, Z_SYNC_FLUSH); + if (ret != Z_STREAM_END && ret != Z_OK) + { + printf("Error while decompressing: %d\n", ret); + inflateEnd(&zstream); + exit(1); + } + + dbgprintf("a_in: %d t_in: %d a_out: %d t_out: %d -- %d out\n", + zstream.avail_in, zstream.total_in, zstream.avail_out, zstream.total_out, + zstream.total_out-last_out); + + write(fd_out, &buf_out, zstream.total_out-last_out); + + i += len; + + if (ret == Z_STREAM_END || ret == Z_BUF_ERROR) + break; + } + + if (zstream.total_out != uncomp_len-8) + { + printf("Size mismatch (%d != %d), updating header...\n", + zstream.total_out, uncomp_len-8); + + buf_in[0] = (zstream.total_out+8) & 0xff; + buf_in[1] = (zstream.total_out+8 >> 8) & 0xff; + buf_in[2] = (zstream.total_out+8 >> 16) & 0xff; + buf_in[3] = (zstream.total_out+8 >> 24) & 0xff; + + lseek(fd_out, 4, SEEK_SET); + write(fd_out, &buf_in, 4); + } + + inflateEnd(&zstream); + close(fd_in); + close(fd_out); +} diff --git a/mpeg4/src/doc/.cvsignore b/mpeg4/src/doc/.cvsignore new file mode 100644 index 00000000..39bd1000 --- /dev/null +++ b/mpeg4/src/doc/.cvsignore @@ -0,0 +1,8 @@ +faq.html +ffmpeg-doc.html +ffmpeg.1 +ffplay-doc.html +ffplay.1 +ffserver-doc.html +ffserver.1 +hooks.html diff --git a/mpeg4/src/doc/Makefile b/mpeg4/src/doc/Makefile new file mode 100644 index 00000000..744a9fbc --- /dev/null +++ b/mpeg4/src/doc/Makefile @@ -0,0 +1,18 @@ +-include ../config.mak + +VPATH=$(SRC_PATH)/doc + +all: ffmpeg-doc.html faq.html ffserver-doc.html ffplay-doc.html hooks.html \ + ffmpeg.1 ffserver.1 ffplay.1 + +%.html: %.texi Makefile + texi2html -monolithic -number $< + +%.pod: %-doc.texi + ./texi2pod.pl $< $@ + +%.1: %.pod + pod2man --section=1 --center=" " --release=" " $< > $@ + +clean: + rm -f *.html *.pod *.1 diff --git a/mpeg4/src/doc/TODO b/mpeg4/src/doc/TODO new file mode 100644 index 00000000..ed0b6377 --- /dev/null +++ b/mpeg4/src/doc/TODO @@ -0,0 +1,74 @@ +ffmpeg TODO list: +---------------- + +Fabrice's TODO list: (unordered) +------------------- +Short term: + +- av_read_frame() API +- seeking API and example in ffplay +- parse_only mode +- use AVFMTCTX_DISCARD_PKT in ffplay so that DV has a chance to work +- add RTSP regression test (both client and server) +- make ffserver allocate AVFormatContext +- clean up (incompatible change, for 0.5.0): + * AVStream -> AVComponent + * AVFormatContext -> AVInputStream/AVOutputStream + * suppress rate_emu from AVCodecContext +- add av_log() in libavcodec and suppress all printf +- add new float/integer audio filterting and conversion : suppress + CODEC_ID_PCM_xxc and use CODEC_ID_RAWAUDIO. +- fix telecine and frame rate conversion + +Long term (ask me if you want to help): + +- commit new imgconvert API and new PIX_FMT_xxx alpha formats +- commit new LGPL'ed float and integer-only AC3 decoder +- add WMA integer-only decoder +- integrate custom Vorbis Tremor based integer and float decoder +- add new MPEG4-AAC audio decoder (both integer-only and float version) + +Michael's TODO list: (unordered) (if anyone wanna help with sth, just ask) +------------------- +- finish implementation of WMV2 j-picture +- H264 encoder +- H264 B frames +- optimize H264 CABAC +- per MB ratecontrol (so VCD and such do work better) +- more optimizations +- simper rate control +- split h263.c +- reverse engeneer RV30/RV40 +- finish NUT implementation + +Francois' TODO list: (unordered, without any timeframe) +------------------- +- test MACE decoder against the openquicktime one as suggested by A'rpi +- mov/mp4 muxer +- BeOS audio input grabbing backend +- BeOS video input grabbing backend +- have a REAL BeOS errno fix (return MKERROR(EXXX);), not a hack +- publish my BeOS libposix on BeBits so I can officially support ffserver :) +- check the whole code for thread-safety (global and init stuff) + +Philip'a TODO list: (alphabetically ordered) (please help) +------------------ +- Add a multi-ffm filetype so that feeds can be recorded into multiple files rather + than one big file. +- Authenticated users support -- where the authentication is in the URL +- Change ASF files so that the embedded timestamp in the frames is right rather + than being an offset from the start of the stream +- Make ffm files more resilient to changes in the codec structures so that you + can play old ffm files. + +unassigned TODO: (stuff which should/must be done but noone seems to do it) +--------------- +- use AVFrame for audio codecs too +- H264 interlacing +- rework aviobuf.c buffering strategy and fix url_fskip +- do audio resampling with bandlimited interpolation: + http://ccrma-www.stanford.edu/~jos/resample/resample.html +- add seeking support to the command line +- generate optimal huffman tables for mjpeg encoding +- fix ffserver regression tests + diff --git a/mpeg4/src/doc/faq.texi b/mpeg4/src/doc/faq.texi new file mode 100644 index 00000000..ec022d5b --- /dev/null +++ b/mpeg4/src/doc/faq.texi @@ -0,0 +1,220 @@ +\input texinfo @c -*- texinfo -*- + +@settitle FFmpeg FAQ +@titlepage +@sp 7 +@center @titlefont{FFmpeg FAQ} +@sp 3 +@end titlepage + + +@chapter General Problems + +@section I cannot read this file although this format seems to be supported by ffmpeg. + +Even if ffmpeg can read the file format, it may not support all its +codecs. Please consult the supported codec list in the ffmpeg +documentation. + +@section How do I encode JPEGs to another format ? + +If the JPEGs are named img1.jpg, img2.jpg, img3.jpg,..., use: + +@example + ffmpeg -i img%d.jpg /tmp/a.mpg +@end example + +@samp{%d} is replaced by the image number. + +@file{img%03d.jpg} generates @file{img001.jpg}, @file{img002.jpg}, etc... + +The same system is used for the other image formats. + +@section FFmpeg does not support codec XXX. Can you include a Windows DLL loader to support it ? + +No. FFmpeg only supports open source codecs. Windows DLLs are not +portable, bloated and often slow. + +@section Why do I see a slight quality degradation with multithreaded MPEG* encoding ? + +For multithreaded MPEG* encoding, the encoded slices must be independent, +otherwise thread n would practically have to wait for n-1 to finish, so it's +quite logical that there is a small reduction of quality. This is not a bug. + +@section How can I read from the standard input or write to the standard output ? + +Use @file{-} as filename. + +@section Why does ffmpeg not decode audio in VOB files ? + +The audio is AC3 (a.k.a. A/52). AC3 decoding is an optional component in ffmpeg +as the component that handles AC3 decoding (liba52) is currently released under +the GPL. If you have liba52 installed on your system, enable AC3 decoding +with @code{./configure --enable-a52}. Take care: by +enabling AC3, you automatically change the license of libavcodec from +LGPL to GPL. + +@section Which codecs are supported by Windows ? + +Windows does not support standard formats like MPEG very well, unless you +install some additional codecs + +The following list of video codecs should work on most Windows systems: +@table @option +@item msmpeg4v2 +.avi/.asf +@item msmpeg4 +.asf only +@item wmv1 +.asf only +@item wmv2 +.asf only +@item mpeg4 +only if you have some MPEG-4 codec installed like ffdshow or XviD +@item mpeg1 +.mpg only +@end table +Note, ASF files often have .wmv or .wma extensions in Windows. It should also +be mentioned that Microsoft claims a patent on the ASF format, and may sue +or threaten users who create ASF files with non-Microsoft software. It is +strongly advised to avoid ASF where possible. + +The following list of audio codecs should work on most Windows systems: +@table @option +@item adpcm_ima_wav +@item adpcm_ms +@item pcm +@item mp3 +if some MP3 codec like LAME is installed +@end table + +@section Why does the chrominance data seem to be sampled at a different time from the luminance data on bt8x8 captures on Linux? + +This is a well-known bug in the bt8x8 driver. For 2.4.26 there is a patch at +(@url{http://mplayerhq.hu/~michael/bttv-420-2.4.26.patch}). This may also +apply cleanly to other 2.4-series kernels. + +@section How do I avoid the ugly aliasing artifacts in bt8x8 captures on Linux? + +Pass 'combfilter=1 lumafilter=1' to the bttv driver. Note though that 'combfilter=1' +will cause somewhat too strong filtering. A fix is to apply (@url{http://mplayerhq.hu/~michael/bttv-comb-2.4.26.patch}) +or (@url{http://mplayerhq.hu/~michael/bttv-comb-2.6.6.patch}) +and pass 'combfilter=2'. + +@section I have a problem with an old version of ffmpeg; where should I report it? +Nowhere. Upgrade to the latest release or if there is no recent release upgrade +to CVS. You could also try to report it. Maybe you will get lucky and +become the first person in history to get an answer different from "upgrade +to CVS". + +@section -f jpeg doesn't work. + +Try '-f image -img jpeg test%d.jpg'. + +@section Why can I not change the framerate? + +Some codecs, like MPEG-1/2, only allow a small number of fixed framerates. +Choose a different codec with the -vcodec command line option. + +@section ffmpeg does not work; What is wrong? + +Try a 'make distclean' in the ffmpeg source directory. If this does not help see +(@url{http://ffmpeg.org/bugreports.php}). + +@section How do I encode XviD or DivX video with ffmpeg? + +Both XviD and DivX (version 4+) are implementations of the ISO MPEG-4 +standard (note that there are many other coding formats that use this +same standard). Thus, use '-vcodec mpeg4' to encode these formats. The +default fourcc stored in an MPEG-4-coded file will be 'FMP4'. If you want +a different fourcc, use the '-vtag' option. E.g., '-vtag xvid' will +force the fourcc 'xvid' to be stored as the video fourcc rather than the +default. + +@chapter Development + +@section When will the next FFmpeg version be released? / Why are FFmpeg releases so few and far between? + +Like most open source projects FFmpeg suffers from a certain lack of +manpower. For this reason the developers have to prioritize the work +they do and putting out releases is not at the top of the list, fixing +bugs and reviewing patches takes precedence. Please don't complain or +request more timely and/or frequent releases unless you are willing to +help out creating them. + +@section Why doesn't FFmpeg support feature [xyz]? + +Because no one has taken on that task yet. FFmpeg development is +driven by the tasks that are important to the individual developers. +If there is a feature that is important to you, the best way to get +it implemented is to undertake the task yourself. + + +@section Are there examples illustrating how to use the FFmpeg libraries, particularly libavcodec and libavformat ? + +Yes. Read the Developers Guide of the FFmpeg documentation. Alternatively, +examine the source code for one of the many open source projects that +already incorporate ffmpeg at (@url{projects.php}). + +@section Can you support my C compiler XXX ? + +No. Only GCC is supported. GCC is ported to most systems available and there +is no need to pollute the source code with @code{#ifdef}s +related to the compiler. + +@section Can I use FFmpeg or libavcodec under Windows ? + +Yes, but the MinGW tools @emph{must} be used to compile FFmpeg. You +can link the resulting DLLs with any other Windows program. Read the +@emph{Native Windows Compilation} and @emph{Visual C++ compatibility} +sections in the FFmpeg documentation to find more information. + +@section Can you add automake, libtool or autoconf support ? + +No. These tools are too bloated and they complicate the build. Moreover, +since only @samp{gcc} is supported they would add little advantages in +terms of portability. + +@section Why not rewrite ffmpeg in object-oriented C++ ? + +ffmpeg is already organized in a highly modular manner and does not need to +be rewritten in a formal object language. Further, many of the developers +favor straight C; it works for them. For more arguments on this matter, +read "Programming Religion" at (@url{http://lkml.org/faq/lkmlfaq-15.html}). + +@section Why are the ffmpeg programs devoid of debugging symbols ? + +The build process creates ffmpeg_g, ffplay_g, etc. which contain full debug +information. Those binaries are strip'd to create ffmpeg, ffplay, etc. If +you need the debug information, used the *_g versions. + +@section I do not like the LGPL, can I contribute code under the GPL instead ? + +Yes, as long as the code is optional and can easily and cleanly be placed +under #ifdef CONFIG_GPL without breaking anything. So for example a new codec +or filter would be OK under GPL while a bugfix to LGPL code would not. + +@section I want to compile xyz.c alone but my compiler produced many errors. + +Common code is in its own files in libav* and is used by the individual +codecs. They will not work without the common parts, you have to compile +the whole libav*. If you wish, disable some parts with configure switches. +You can also try to hack it and remove more, but if you had problems fixing +the compilation failure then you are probably not qualified for this. + +@section Visual C++ produces many errors. + +Visual C++ is not compliant to the C standard and does not support +the inline assembly used in FFmpeg. +If you wish - for whatever weird reason - to use Visual C++ for your +project then you can link the Visual C++ code with libav* as long as +you compile the latter with a working C compiler. For more information, see +the @emph{Visual C++ compatibility} section in the FFmpeg documentation. + +There have been efforts to make FFmpeg compatible with Visual C++ in the +past. However, they have all been rejected as too intrusive, especially +since MinGW does the job perfectly adequately. None of the core developers +work with Visual C++ and thus this item is low priority. Should you find +the silver bullet that solves this problem, feel free to shoot it at us. + +@bye diff --git a/mpeg4/src/doc/ffmpeg-doc.texi b/mpeg4/src/doc/ffmpeg-doc.texi new file mode 100644 index 00000000..cfa14880 --- /dev/null +++ b/mpeg4/src/doc/ffmpeg-doc.texi @@ -0,0 +1,1370 @@ +\input texinfo @c -*- texinfo -*- + +@settitle FFmpeg Documentation +@titlepage +@sp 7 +@center @titlefont{FFmpeg Documentation} +@sp 3 +@end titlepage + + +@chapter Introduction + +FFmpeg is a very fast video and audio converter. It can also grab from +a live audio/video source. + +The command line interface is designed to be intuitive, in the sense +that FFmpeg tries to figure out all parameters that can possibly be +derived automatically. You usually only have to specify the target +bitrate you want. + +FFmpeg can also convert from any sample rate to any other, and resize +video on the fly with a high quality polyphase filter. + +@chapter Quick Start + +@c man begin EXAMPLES +@section Video and Audio grabbing + +FFmpeg can use a video4linux compatible video source and any Open Sound +System audio source: + +@example +ffmpeg /tmp/out.mpg +@end example + +Note that you must activate the right video source and channel before +launching FFmpeg with any TV viewer such as xawtv +(@url{http://bytesex.org/xawtv/}) by Gerd Knorr. You also +have to set the audio recording levels correctly with a +standard mixer. + +@section Video and Audio file format conversion + +* FFmpeg can use any supported file format and protocol as input: + +Examples: + +* You can use YUV files as input: + +@example +ffmpeg -i /tmp/test%d.Y /tmp/out.mpg +@end example + +It will use the files: +@example +/tmp/test0.Y, /tmp/test0.U, /tmp/test0.V, +/tmp/test1.Y, /tmp/test1.U, /tmp/test1.V, etc... +@end example + +The Y files use twice the resolution of the U and V files. They are +raw files, without header. They can be generated by all decent video +decoders. You must specify the size of the image with the @option{-s} option +if FFmpeg cannot guess it. + +* You can input from a raw YUV420P file: + +@example +ffmpeg -i /tmp/test.yuv /tmp/out.avi +@end example + +test.yuv is a file containing raw YUV planar data. Each frame is composed +of the Y plane followed by the U and V planes at half vertical and +horizontal resolution. + +* You can output to a raw YUV420P file: + +@example +ffmpeg -i mydivx.avi hugefile.yuv +@end example + +* You can set several input files and output files: + +@example +ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg +@end example + +Converts the audio file a.wav and the raw YUV video file a.yuv +to MPEG file a.mpg. + +* You can also do audio and video conversions at the same time: + +@example +ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2 +@end example + +Converts a.wav to MPEG audio at 22050Hz sample rate. + +* You can encode to several formats at the same time and define a +mapping from input stream to output streams: + +@example +ffmpeg -i /tmp/a.wav -ab 64 /tmp/a.mp2 -ab 128 /tmp/b.mp2 -map 0:0 -map 0:0 +@end example + +Converts a.wav to a.mp2 at 64 kbits and to b.mp2 at 128 kbits. '-map +file:index' specifies which input stream is used for each output +stream, in the order of the definition of output streams. + +* You can transcode decrypted VOBs + +@example +ffmpeg -i snatch_1.vob -f avi -vcodec mpeg4 -b 800 -g 300 -bf 2 -acodec mp3 -ab 128 snatch.avi +@end example + +This is a typical DVD ripping example; the input is a VOB file, the +output an AVI file with MPEG-4 video and MP3 audio. Note that in this +command we use B-frames so the MPEG-4 stream is DivX5 compatible, and +GOP size is 300 which means one intra frame every 10 seconds for 29.97fps +input video. Furthermore, the audio stream is MP3-encoded so you need +to enable LAME support by passing @code{--enable-mp3lame} to configure. +The mapping is particularly useful for DVD transcoding +to get the desired audio language. + +NOTE: To see the supported input formats, use @code{ffmpeg -formats}. +@c man end + +@chapter Invocation + +@section Syntax + +The generic syntax is: + +@example +@c man begin SYNOPSIS +ffmpeg [[infile options][@option{-i} @var{infile}]]... @{[outfile options] @var{outfile}@}... +@c man end +@end example +@c man begin DESCRIPTION +If no input file is given, audio/video grabbing is done. + +As a general rule, options are applied to the next specified +file. For example, if you give the @option{-b 64} option, it sets the video +bitrate of the next file. The format option may be needed for raw input +files. + +By default, FFmpeg tries to convert as losslessly as possible: It +uses the same audio and video parameters for the outputs as the one +specified for the inputs. +@c man end + +@c man begin OPTIONS +@section Main options + +@table @option +@item -L +Show license. + +@item -h +Show help. + +@item -formats +Show available formats, codecs, protocols, ... + +@item -f fmt +Force format. + +@item -i filename +input filename + +@item -y +Overwrite output files. + +@item -t duration +Set the recording time in seconds. +@code{hh:mm:ss[.xxx]} syntax is also supported. + +@item -ss position +Seek to given time position in seconds. +@code{hh:mm:ss[.xxx]} syntax is also supported. + +@item -title string +Set the title. + +@item -author string +Set the author. + +@item -copyright string +Set the copyright. + +@item -comment string +Set the comment. + +@item -target type +Specify target file type ("vcd", "svcd", "dvd", "dv", "pal-vcd", +"ntsc-svcd", ... ). All the format options (bitrate, codecs, +buffer sizes) are then set automatically. You can just type: + +@example +ffmpeg -i myfile.avi -target vcd /tmp/vcd.mpg +@end example + +Nevertheless you can specify additional options as long as you know +they do not conflict with the standard, as in: + +@example +ffmpeg -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg +@end example + +@item -hq +Activate high quality settings. + +@item -itsoffset offset +Set the input time offset in seconds. +@code{[-]hh:mm:ss[.xxx]} syntax is also supported. +This option affects all the input files that follow it. +The offset is added to the timestamps of the input files. +Specifying a positive offset means that the corresponding +streams are delayed by 'offset' seconds. + +@end table + +@section Video Options + +@table @option +@item -b bitrate +Set the video bitrate in kbit/s (default = 200 kb/s). +@item -r fps +Set frame rate (default = 25). +@item -s size +Set frame size. The format is @samp{wxh} (default = 160x128). +The following abbreviations are recognized: +@table @samp +@item sqcif +128x96 +@item qcif +176x144 +@item cif +352x288 +@item 4cif +704x576 +@end table + +@item -aspect aspect +Set aspect ratio (4:3, 16:9 or 1.3333, 1.7777). +@item -croptop size +Set top crop band size (in pixels). +@item -cropbottom size +Set bottom crop band size (in pixels). +@item -cropleft size +Set left crop band size (in pixels). +@item -cropright size +Set right crop band size (in pixels). +@item -padtop size +Set top pad band size (in pixels). +@item -padbottom size +Set bottom pad band size (in pixels). +@item -padleft size +Set left pad band size (in pixels). +@item -padright size +Set right pad band size (in pixels). +@item -padcolor (hex color) +Set color of padded bands. The value for padcolor is expressed +as a six digit hexadecimal number where the first two digits +represent red, the middle two digits green and last two digits +blue (default = 000000 (black)). +@item -vn +Disable video recording. +@item -bt tolerance +Set video bitrate tolerance (in kbit/s). +@item -maxrate bitrate +Set max video bitrate tolerance (in kbit/s). +@item -minrate bitrate +Set min video bitrate tolerance (in kbit/s). +@item -bufsize size +Set rate control buffer size (in kbit). +@item -vcodec codec +Force video codec to @var{codec}. Use the @code{copy} special value to +tell that the raw codec data must be copied as is. +@item -sameq +Use same video quality as source (implies VBR). + +@item -pass n +Select the pass number (1 or 2). It is useful to do two pass +encoding. The statistics of the video are recorded in the first +pass and the video is generated at the exact requested bitrate +in the second pass. + +@item -passlogfile file +Set two pass logfile name to @var{file}. + +@end table + +@section Advanced Video Options + +@table @option +@item -g gop_size +Set the group of pictures size. +@item -intra +Use only intra frames. +@item -qscale q +Use fixed video quantiser scale (VBR). +@item -qmin q +minimum video quantiser scale (VBR) +@item -qmax q +maximum video quantiser scale (VBR) +@item -qdiff q +maximum difference between the quantiser scales (VBR) +@item -qblur blur +video quantiser scale blur (VBR) +@item -qcomp compression +video quantiser scale compression (VBR) + +@item -rc_init_cplx complexity +initial complexity for single pass encoding +@item -b_qfactor factor +qp factor between P- and B-frames +@item -i_qfactor factor +qp factor between P- and I-frames +@item -b_qoffset offset +qp offset between P- and B-frames +@item -i_qoffset offset +qp offset between P- and I-frames +@item -rc_eq equation +Set rate control equation (@pxref{FFmpeg formula +evaluator}) (default = @code{tex^qComp}). +@item -rc_override override +rate control override for specific intervals +@item -me method +Set motion estimation method to @var{method}. +Available methods are (from lowest to best quality): +@table @samp +@item zero +Try just the (0, 0) vector. +@item phods +@item log +@item x1 +@item epzs +(default method) +@item full +exhaustive search (slow and marginally better than epzs) +@end table + +@item -dct_algo algo +Set DCT algorithm to @var{algo}. Available values are: +@table @samp +@item 0 +FF_DCT_AUTO (default) +@item 1 +FF_DCT_FASTINT +@item 2 +FF_DCT_INT +@item 3 +FF_DCT_MMX +@item 4 +FF_DCT_MLIB +@item 5 +FF_DCT_ALTIVEC +@end table + +@item -idct_algo algo +Set IDCT algorithm to @var{algo}. Available values are: +@table @samp +@item 0 +FF_IDCT_AUTO (default) +@item 1 +FF_IDCT_INT +@item 2 +FF_IDCT_SIMPLE +@item 3 +FF_IDCT_SIMPLEMMX +@item 4 +FF_IDCT_LIBMPEG2MMX +@item 5 +FF_IDCT_PS2 +@item 6 +FF_IDCT_MLIB +@item 7 +FF_IDCT_ARM +@item 8 +FF_IDCT_ALTIVEC +@item 9 +FF_IDCT_SH4 +@item 10 +FF_IDCT_SIMPLEARM +@end table + +@item -er n +Set error resilience to @var{n}. +@table @samp +@item 1 +FF_ER_CAREFUL (default) +@item 2 +FF_ER_COMPLIANT +@item 3 +FF_ER_AGGRESSIVE +@item 4 +FF_ER_VERY_AGGRESSIVE +@end table + +@item -ec bit_mask +Set error concealment to @var{bit_mask}. @var{bit_mask} is a bit mask of +the following values: +@table @samp +@item 1 +FF_EC_GUESS_MVS (default = enabled) +@item 2 +FF_EC_DEBLOCK (default = enabled) +@end table + +@item -bf frames +Use 'frames' B-frames (supported for MPEG-1, MPEG-2 and MPEG-4). +@item -mbd mode +macroblock decision +@table @samp +@item 0 +FF_MB_DECISION_SIMPLE: Use mb_cmp (cannot change it yet in FFmpeg). +@item 1 +FF_MB_DECISION_BITS: Choose the one which needs the fewest bits. +@item 2 +FF_MB_DECISION_RD: rate distortion +@end table + +@item -4mv +Use four motion vector by macroblock (MPEG-4 only). +@item -part +Use data partitioning (MPEG-4 only). +@item -bug param +Work around encoder bugs that are not auto-detected. +@item -strict strictness +How strictly to follow the standards. +@item -aic +Enable Advanced intra coding (h263+). +@item -umv +Enable Unlimited Motion Vector (h263+) + +@item -deinterlace +Deinterlace pictures. +@item -interlace +Force interlacing support in encoder (MPEG-2 and MPEG-4 only). +Use this option if your input file is interlaced and you want +to keep the interlaced format for minimum losses. +The alternative is to deinterlace the input stream with +@option{-deinterlace}, but deinterlacing introduces losses. +@item -psnr +Calculate PSNR of compressed frames. +@item -vstats +Dump video coding statistics to @file{vstats_HHMMSS.log}. +@item -vhook module +Insert video processing @var{module}. @var{module} contains the module +name and its parameters separated by spaces. +@end table + +@section Audio Options + +@table @option +@item -ar freq +Set the audio sampling frequency (default = 44100 Hz). +@item -ab bitrate +Set the audio bitrate in kbit/s (default = 64). +@item -ac channels +Set the number of audio channels (default = 1). +@item -an +Disable audio recording. +@item -acodec codec +Force audio codec to @var{codec}. Use the @code{copy} special value to +specify that the raw codec data must be copied as is. +@end table + +@section Audio/Video grab options + +@table @option +@item -vd device +sEt video grab device (e.g. @file{/dev/video0}). +@item -vc channel +Set video grab channel (DV1394 only). +@item -tvstd standard +Set television standard (NTSC, PAL (SECAM)). +@item -dv1394 +Set DV1394 grab. +@item -ad device +Set audio device (e.g. @file{/dev/dsp}). +@end table + +@section Advanced options + +@table @option +@item -map file:stream +Set input stream mapping. +@item -debug +Print specific debug info. +@item -benchmark +Add timings for benchmarking. +@item -hex +Dump each input packet. +@item -bitexact +Only use bit exact algorithms (for codec testing). +@item -ps size +Set packet size in bits. +@item -re +Read input at native frame rate. Mainly used to simulate a grab device. +@item -loop +Loop over the input stream. Currently it works only for image +streams. This option is used for automatic FFserver testing. +@item -loop_output number_of_times +Repeatedly loop output for formats that support looping such as animated GIF +(0 will loop the output infinitely). +@end table + +@node FFmpeg formula evaluator +@section FFmpeg formula evaluator + +When evaluating a rate control string, FFmpeg uses an internal formula +evaluator. + +The following binary operators are available: @code{+}, @code{-}, +@code{*}, @code{/}, @code{^}. + +The following unary operators are available: @code{+}, @code{-}, +@code{(...)}. + +The following functions are available: +@table @var +@item sinh(x) +@item cosh(x) +@item tanh(x) +@item sin(x) +@item cos(x) +@item tan(x) +@item exp(x) +@item log(x) +@item squish(x) +@item gauss(x) +@item abs(x) +@item max(x, y) +@item min(x, y) +@item gt(x, y) +@item lt(x, y) +@item eq(x, y) +@item bits2qp(bits) +@item qp2bits(qp) +@end table + +The following constants are available: +@table @var +@item PI +@item E +@item iTex +@item pTex +@item tex +@item mv +@item fCode +@item iCount +@item mcVar +@item var +@item isI +@item isP +@item isB +@item avgQP +@item qComp +@item avgIITex +@item avgPITex +@item avgPPTex +@item avgBPTex +@item avgTex +@end table + +@c man end + +@ignore + +@setfilename ffmpeg +@settitle FFmpeg video converter + +@c man begin SEEALSO +ffserver(1), ffplay(1) and the HTML documentation of @file{ffmpeg}. +@c man end + +@c man begin AUTHOR +Fabrice Bellard +@c man end + +@end ignore + +@section Protocols + +The filename can be @file{-} to read from standard input or to write +to standard output. + +FFmpeg also handles many protocols specified with an URL syntax. + +Use 'ffmpeg -formats' to see a list of the supported protocols. + +The protocol @code{http:} is currently used only to communicate with +FFserver (see the FFserver documentation). When FFmpeg will be a +video player it will also be used for streaming :-) + +@chapter Tips + +@itemize +@item For streaming at very low bitrate application, use a low frame rate +and a small GOP size. This is especially true for RealVideo where +the Linux player does not seem to be very fast, so it can miss +frames. An example is: + +@example +ffmpeg -g 3 -r 3 -t 10 -b 50 -s qcif -f rv10 /tmp/b.rm +@end example + +@item The parameter 'q' which is displayed while encoding is the current +quantizer. The value 1 indicates that a very good quality could +be achieved. The value 31 indicates the worst quality. If q=31 appears +too often, it means that the encoder cannot compress enough to meet +your bitrate. You must either increase the bitrate, decrease the +frame rate or decrease the frame size. + +@item If your computer is not fast enough, you can speed up the +compression at the expense of the compression ratio. You can use +'-me zero' to speed up motion estimation, and '-intra' to disable +motion estimation completely (you have only I-frames, which means it +is about as good as JPEG compression). + +@item To have very low audio bitrates, reduce the sampling frequency +(down to 22050 kHz for MPEG audio, 22050 or 11025 for AC3). + +@item To have a constant quality (but a variable bitrate), use the option +'-qscale n' when 'n' is between 1 (excellent quality) and 31 (worst +quality). + +@item When converting video files, you can use the '-sameq' option which +uses the same quality factor in the encoder as in the decoder. +It allows almost lossless encoding. + +@end itemize + +@chapter Supported File Formats and Codecs + +You can use the @code{-formats} option to have an exhaustive list. + +@section File Formats + +FFmpeg supports the following file formats through the @code{libavformat} +library: + +@multitable @columnfractions .4 .1 .1 .4 +@item Supported File Format @tab Encoding @tab Decoding @tab Comments +@item MPEG audio @tab X @tab X +@item MPEG-1 systems @tab X @tab X +@tab muxed audio and video +@item MPEG-2 PS @tab X @tab X +@tab also known as @code{VOB} file +@item MPEG-2 TS @tab @tab X +@tab also known as DVB Transport Stream +@item ASF@tab X @tab X +@item AVI@tab X @tab X +@item WAV@tab X @tab X +@item Macromedia Flash@tab X @tab X +@tab Only embedded audio is decoded. +@item FLV @tab X @tab X +@tab Macromedia Flash video files +@item Real Audio and Video @tab X @tab X +@item Raw AC3 @tab X @tab X +@item Raw MJPEG @tab X @tab X +@item Raw MPEG video @tab X @tab X +@item Raw PCM8/16 bits, mulaw/Alaw@tab X @tab X +@item Raw CRI ADX audio @tab X @tab X +@item Raw Shorten audio @tab @tab X +@item SUN AU format @tab X @tab X +@item NUT @tab X @tab X @tab NUT Open Container Format +@item QuickTime @tab X @tab X +@item MPEG-4 @tab X @tab X +@tab MPEG-4 is a variant of QuickTime. +@item Raw MPEG4 video @tab X @tab X +@item DV @tab X @tab X +@item 4xm @tab @tab X +@tab 4X Technologies format, used in some games. +@item Playstation STR @tab @tab X +@item Id RoQ @tab @tab X +@tab Used in Quake III, Jedi Knight 2, other computer games. +@item Interplay MVE @tab @tab X +@tab Format used in various Interplay computer games. +@item WC3 Movie @tab @tab X +@tab Multimedia format used in Origin's Wing Commander III computer game. +@item Sega FILM/CPK @tab @tab X +@tab Used in many Sega Saturn console games. +@item Westwood Studios VQA/AUD @tab @tab X +@tab Multimedia formats used in Westwood Studios games. +@item Id Cinematic (.cin) @tab @tab X +@tab Used in Quake II. +@item FLIC format @tab @tab X +@tab .fli/.flc files +@item Sierra VMD @tab @tab X +@tab Used in Sierra CD-ROM games. +@item Sierra Online @tab @tab X +@tab .sol files used in Sierra Online games. +@item Matroska @tab @tab X +@item Electronic Arts Multimedia @tab @tab X +@tab Used in various EA games; files have extensions like WVE and UV2. +@item Nullsoft Video (NSV) format @tab @tab X +@item ADTS AAC audio @tab X @tab X +@item Creative VOC @tab X @tab X @tab Created for the Sound Blaster Pro. +@item American Laser Games MM @tab @tab X +@tab Multimedia format used in games like Mad Dog McCree +@item AVS @tab @tab X +@tab Multimedia format used by the Creature Shock game. +@item Smacker @tab @tab X +@tab Multimedia format used by many games. +@end multitable + +@code{X} means that encoding (resp. decoding) is supported. + +@section Image Formats + +FFmpeg can read and write images for each frame of a video sequence. The +following image formats are supported: + +@multitable @columnfractions .4 .1 .1 .4 +@item Supported Image Format @tab Encoding @tab Decoding @tab Comments +@item PGM, PPM @tab X @tab X +@item PAM @tab X @tab X @tab PAM is a PNM extension with alpha support. +@item PGMYUV @tab X @tab X @tab PGM with U and V components in YUV 4:2:0 +@item JPEG @tab X @tab X @tab Progressive JPEG is not supported. +@item .Y.U.V @tab X @tab X @tab one raw file per component +@item animated GIF @tab X @tab X @tab Only uncompressed GIFs are generated. +@item PNG @tab X @tab X @tab 2 bit and 4 bit/pixel not supported yet. +@item SGI @tab X @tab X @tab SGI RGB image format +@end multitable + +@code{X} means that encoding (resp. decoding) is supported. + +@section Video Codecs + +@multitable @columnfractions .4 .1 .1 .4 +@item Supported Codec @tab Encoding @tab Decoding @tab Comments +@item MPEG-1 video @tab X @tab X +@item MPEG-2 video @tab X @tab X +@item MPEG-4 @tab X @tab X @tab also known as DivX4/5 +@item MSMPEG4 V1 @tab X @tab X +@item MSMPEG4 V2 @tab X @tab X +@item MSMPEG4 V3 @tab X @tab X @tab also known as DivX3 +@item WMV7 @tab X @tab X +@item WMV8 @tab X @tab X @tab not completely working +@item H.261 @tab X @tab X +@item H.263(+) @tab X @tab X @tab also known as RealVideo 1.0 +@item H.264 @tab @tab X +@item RealVideo 1.0 @tab X @tab X +@item RealVideo 2.0 @tab X @tab X +@item MJPEG @tab X @tab X +@item lossless MJPEG @tab X @tab X +@item JPEG-LS @tab X @tab X @tab fourcc: MJLS, lossless and near-lossless is supported +@item Apple MJPEG-B @tab @tab X +@item Sunplus MJPEG @tab @tab X @tab fourcc: SP5X +@item DV @tab X @tab X +@item HuffYUV @tab X @tab X +@item FFmpeg Video 1 @tab X @tab X @tab experimental lossless codec (fourcc: FFV1) +@item FFmpeg Snow @tab X @tab X @tab experimental wavelet codec (fourcc: SNOW) +@item Asus v1 @tab X @tab X @tab fourcc: ASV1 +@item Asus v2 @tab X @tab X @tab fourcc: ASV2 +@item Creative YUV @tab @tab X @tab fourcc: CYUV +@item Sorenson Video 1 @tab X @tab X @tab fourcc: SVQ1 +@item Sorenson Video 3 @tab @tab X @tab fourcc: SVQ3 +@item On2 VP3 @tab @tab X @tab still experimental +@item Theora @tab @tab X @tab still experimental +@item Intel Indeo 3 @tab @tab X +@item FLV @tab X @tab X @tab Sorenson H.263 used in Flash +@item ATI VCR1 @tab @tab X @tab fourcc: VCR1 +@item ATI VCR2 @tab @tab X @tab fourcc: VCR2 +@item Cirrus Logic AccuPak @tab @tab X @tab fourcc: CLJR +@item 4X Video @tab @tab X @tab Used in certain computer games. +@item Sony Playstation MDEC @tab @tab X +@item Id RoQ @tab @tab X @tab Used in Quake III, Jedi Knight 2, other computer games. +@item Xan/WC3 @tab @tab X @tab Used in Wing Commander III .MVE files. +@item Interplay Video @tab @tab X @tab Used in Interplay .MVE files. +@item Apple Animation @tab @tab X @tab fourcc: 'rle ' +@item Apple Graphics @tab @tab X @tab fourcc: 'smc ' +@item Apple Video @tab @tab X @tab fourcc: rpza +@item Apple QuickDraw @tab @tab X @tab fourcc: qdrw +@item Cinepak @tab @tab X +@item Microsoft RLE @tab @tab X +@item Microsoft Video-1 @tab @tab X +@item Westwood VQA @tab @tab X +@item Id Cinematic Video @tab @tab X @tab Used in Quake II. +@item Planar RGB @tab @tab X @tab fourcc: 8BPS +@item FLIC video @tab @tab X +@item Duck TrueMotion v1 @tab @tab X @tab fourcc: DUCK +@item Duck TrueMotion v2 @tab @tab X @tab fourcc: TM20 +@item VMD Video @tab @tab X @tab Used in Sierra VMD files. +@item MSZH @tab @tab X @tab Part of LCL +@item ZLIB @tab X @tab X @tab Part of LCL, encoder experimental +@item TechSmith Camtasia @tab @tab X @tab fourcc: TSCC +@item IBM Ultimotion @tab @tab X @tab fourcc: ULTI +@item Miro VideoXL @tab @tab X @tab fourcc: VIXL +@item QPEG @tab @tab X @tab fourccs: QPEG, Q1.0, Q1.1 +@item LOCO @tab @tab X @tab +@item Winnov WNV1 @tab @tab X @tab +@item Autodesk Animator Studio Codec @tab @tab X @tab fourcc: AASC +@item Fraps FPS1 @tab @tab X @tab +@item CamStudio @tab @tab X @tab fourcc: CSCD +@item American Laser Games Video @tab @tab X @tab Used in games like Mad Dog McCree +@item ZMBV @tab @tab X @tab +@item AVS Video @tab @tab X @tab Video encoding used by the Creature Shock game. +@item Smacker Video @tab @tab X @tab Video encoding used in Smacker. +@item RTjpeg @tab @tab X @tab Video encoding used in NuppelVideo files. +@item KMVC @tab @tab X @tab Codec used in Worms games. +@end multitable + +@code{X} means that encoding (resp. decoding) is supported. + +See @url{http://mplayerhq.hu/~michael/codec-features.html} to +get a precise comparison of the FFmpeg MPEG-4 codec compared to +other implementations. + +@section Audio Codecs + +@multitable @columnfractions .4 .1 .1 .1 .7 +@item Supported Codec @tab Encoding @tab Decoding @tab Comments +@item MPEG audio layer 2 @tab IX @tab IX +@item MPEG audio layer 1/3 @tab IX @tab IX +@tab MP3 encoding is supported through the external library LAME. +@item AC3 @tab IX @tab IX +@tab liba52 is used internally for decoding. +@item Vorbis @tab X @tab X +@tab Supported through the external library libvorbis. +@item WMA V1/V2 @tab @tab X +@item AAC @tab X @tab X +@tab Supported through the external library libfaac/libfaad. +@item Microsoft ADPCM @tab X @tab X +@item MS IMA ADPCM @tab X @tab X +@item QT IMA ADPCM @tab @tab X +@item 4X IMA ADPCM @tab @tab X +@item G.726 ADPCM @tab X @tab X +@item Duck DK3 IMA ADPCM @tab @tab X +@tab Used in some Sega Saturn console games. +@item Duck DK4 IMA ADPCM @tab @tab X +@tab Used in some Sega Saturn console games. +@item Westwood Studios IMA ADPCM @tab @tab X +@tab Used in Westwood Studios games like Command and Conquer. +@item SMJPEG IMA ADPCM @tab @tab X +@tab Used in certain Loki game ports. +@item CD-ROM XA ADPCM @tab @tab X +@item CRI ADX ADPCM @tab X @tab X +@tab Used in Sega Dreamcast games. +@item Electronic Arts ADPCM @tab @tab X +@tab Used in various EA titles. +@item Creative ADPCM @tab @tab X +@tab 16 -> 4, 8 -> 4, 8 -> 3, 8 -> 2 +@item RA144 @tab @tab X +@tab Real 14400 bit/s codec +@item RA288 @tab @tab X +@tab Real 28800 bit/s codec +@item RADnet @tab X @tab IX +@tab Real low bitrate AC3 codec, liba52 is used for decoding. +@item AMR-NB @tab X @tab X +@tab Supported through an external library. +@item AMR-WB @tab X @tab X +@tab Supported through an external library. +@item DV audio @tab @tab X +@item Id RoQ DPCM @tab @tab X +@tab Used in Quake III, Jedi Knight 2, other computer games. +@item Interplay MVE DPCM @tab @tab X +@tab Used in various Interplay computer games. +@item Xan DPCM @tab @tab X +@tab Used in Origin's Wing Commander IV AVI files. +@item Sierra Online DPCM @tab @tab X +@tab Used in Sierra Online game audio files. +@item Apple MACE 3 @tab @tab X +@item Apple MACE 6 @tab @tab X +@item FLAC lossless audio @tab @tab X +@item Shorten lossless audio @tab @tab X +@item Apple lossless audio @tab @tab X +@tab QuickTime fourcc 'alac' +@item FFmpeg Sonic @tab X @tab X +@tab experimental lossy/lossless codec +@item Qdesign QDM2 @tab @tab X +@tab there are still some distortions +@item Real COOK @tab @tab X +@tab All versions except 5.1 are supported +@item DSP Group TrueSpeech @tab @tab X +@item True Audio (TTA) @tab @tab X +@item Smacker Audio @tab @tab X +@end multitable + +@code{X} means that encoding (resp. decoding) is supported. + +@code{I} means that an integer-only version is available, too (ensures high +performance on systems without hardware floating point support). + +@chapter Platform Specific information + +@section Linux + +FFmpeg should be compiled with at least GCC 2.95.3. GCC 3.2 is the +preferred compiler now for FFmpeg. All future optimizations will depend on +features only found in GCC 3.2. + +@section BSD + +BSD make will not build FFmpeg, you need to install and use GNU Make +(@file{gmake}). + +@section Windows + +@subsection Native Windows compilation + +@itemize +@item Install the current versions of MSYS and MinGW from +@url{http://www.mingw.org/}. You can find detailed installation +instructions in the download section and the FAQ. + +@item If you want to test the FFplay, also download +the MinGW development library of SDL 1.2.x +(@file{SDL-devel-1.2.x-mingw32.tar.gz}) from +@url{http://www.libsdl.org}. Unpack it in a temporary directory, and +unpack the archive @file{i386-mingw32msvc.tar.gz} in the MinGW tool +directory. Edit the @file{sdl-config} script so that it gives the +correct SDL directory when invoked. + +@item Extract the current version of FFmpeg. + +@item Start the MSYS shell (file @file{msys.bat}). + +@item Change to the FFmpeg directory and follow + the instructions of how to compile FFmpeg (file +@file{INSTALL}). Usually, launching @file{./configure} and @file{make} +suffices. If you have problems using SDL, verify that +@file{sdl-config} can be launched from the MSYS command line. + +@item You can install FFmpeg in @file{Program Files/FFmpeg} by typing +@file{make install}. Don't forget to copy @file{SDL.dll} to the place +you launch @file{ffplay} from. + +@end itemize + +Notes: +@itemize + +@item The target @file{make wininstaller} can be used to create a +Nullsoft based Windows installer for FFmpeg and FFplay. @file{SDL.dll} +must be copied to the FFmpeg directory in order to build the +installer. + +@item By using @code{./configure --enable-shared} when configuring FFmpeg, +you can build @file{avcodec.dll} and @file{avformat.dll}. With +@code{make install} you install the FFmpeg DLLs and the associated +headers in @file{Program Files/FFmpeg}. + +@item Visual C++ compatibility: If you used @code{./configure --enable-shared} +when configuring FFmpeg, FFmpeg tries to use the Microsoft Visual +C++ @code{lib} tool to build @code{avcodec.lib} and +@code{avformat.lib}. With these libraries you can link your Visual C++ +code directly with the FFmpeg DLLs (see below). + +@end itemize + +@subsection Visual C++ compatibility + +FFmpeg will not compile under Visual C++ -- and it has too many +dependencies on the GCC compiler to make a port viable. However, +if you want to use the FFmpeg libraries in your own applications, +you can still compile those applications using Visual C++. An +important restriction to this is that you have to use the +dynamically linked versions of the FFmpeg libraries (i.e. the +DLLs), and you have to make sure that Visual-C++-compatible +import libraries are created during the FFmpeg build process. + +This description of how to use the FFmpeg libraries with Visual C++ is +based on Visual C++ 2005 Express Edition Beta 2. If you have a different +version, you might have to modify the procedures slightly. + +Here are the step-by-step instructions for building the FFmpeg libraries +so they can be used with Visual C++: + +@enumerate + +@item Install Visual C++ (if you haven't done so already). + +@item Install MinGW and MSYS as described above. + +@item Add a call to @file{vcvars32.bat} (which sets up the environment +variables for the Visual C++ tools) as the first line of +@file{msys.bat}. The standard location for @file{vcvars32.bat} is +@file{C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat}, +and the standard location for @file{msys.bat} is +@file{C:\msys\1.0\msys.bat}. If this corresponds to your setup, add the +following line as the first line of @file{msys.bat}: + +@code{call "C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat"} + +@item Start the MSYS shell (file @file{msys.bat}) and type @code{link.exe}. +If you get a help message with the command line options of @code{link.exe}, +this means your environment variables are set up correctly, the +Microsoft linker is on the path and will be used by FFmpeg to +create Visual-C++-compatible import libraries. + +@item Extract the current version of FFmpeg and change to the FFmpeg directory. + +@item Type the command +@code{./configure --enable-shared --disable-static --enable-memalign-hack} +to configure and, if that didn't produce any errors, +type @code{make} to build FFmpeg. + +@item The subdirectories @file{libavformat}, @file{libavcodec}, and +@file{libavutil} should now contain the files @file{avformat.dll}, +@file{avformat.lib}, @file{avcodec.dll}, @file{avcodec.lib}, +@file{avutil.dll}, and @file{avutil.lib}, respectively. Copy the three +DLLs to your System32 directory (typically @file{C:\Windows\System32}). + +@end enumerate + +And here is how to use these libraries with Visual C++: + +@enumerate + +@item Create a new console application ("File / New / Project") and then +select "Win32 Console Application". On the appropriate page of the +Application Wizard, uncheck the "Precompiled headers" option. + +@item Write the source code for your application, or, for testing, just +copy the code from an existing sample application into the source file +that Visual C++ has already created for you. (Note that your source +filehas to have a @code{.cpp} extension; otherwise, Visual C++ won't +compile the FFmpeg headers correctly because in C mode, it doesn't +recognize the @code{inline} keyword.) For example, you can copy +@file{output_example.c} from the FFmpeg distribution (but you will +have to make minor modifications so the code will compile under +C++, see below). + +@item Open the "Project / Properties" dialog box. In the "Configuration" +combo box, select "All Configurations" so that the changes you make will +affect both debug and release builds. In the tree view on the left hand +side, select "C/C++ / General", then edit the "Additional Include +Directories" setting to contain the complete paths to the +@file{libavformat}, @file{libavcodec}, and @file{libavutil} +subdirectories of your FFmpeg directory. Note that the directories have +to be separated using semicolons. Now select "Linker / General" from the +tree view and edit the "Additional Library Directories" setting to +contain the same three directories. + +@item Still in the "Project / Properties" dialog box, select "Linker / Input" +from the tree view, then add the files @file{avformat.lib}, +@file{avcodec.lib}, and @file{avutil.lib} to the end of the "Additional +Dependencies". Note that the names of the libraries have to be separated +using spaces. + +@item Now, select "C/C++ / Code Generation" from the tree view. Select +"Debug" in the "Configuration" combo box. Make sure that "Runtime +Library" is set to "Multi-threaded Debug DLL". Then, select "Release" in +the "Configuration" combo box and make sure that "Runtime Library" is +set to "Multi-threaded DLL". + +@item Click "OK" to close the "Project / Properties" dialog box and build +the application. Hopefully, it should compile and run cleanly. If you +used @file{output_example.c} as your sample application, you will get a +few compiler errors, but they are easy to fix. The first type of error +occurs because Visual C++ doesn't allow an @code{int} to be converted to +an @code{enum} without a cast. To solve the problem, insert the required +casts (this error occurs once for a @code{CodecID} and once for a +@code{CodecType}). The second type of error occurs because C++ requires +the return value of @code{malloc} to be cast to the exact type of the +pointer it is being assigned to. Visual C++ will complain that, for +example, @code{(void *)} is being assigned to @code{(uint8_t *)} without +an explicit cast. So insert an explicit cast in these places to silence +the compiler. The third type of error occurs because the @code{snprintf} +library function is called @code{_snprintf} under Visual C++. So just +add an underscore to fix the problem. With these changes, +@file{output_example.c} should compile under Visual C++, and the +resulting executable should produce valid video files. + +@end enumerate + +@subsection Cross compilation for Windows with Linux + +You must use the MinGW cross compilation tools available at +@url{http://www.mingw.org/}. + +Then configure FFmpeg with the following options: +@example +./configure --enable-mingw32 --cross-prefix=i386-mingw32msvc- +@end example +(you can change the cross-prefix according to the prefix chosen for the +MinGW tools). + +Then you can easily test FFmpeg with Wine +(@url{http://www.winehq.com/}). + +@section Mac OS X + +@section BeOS + +The configure script should guess the configuration itself. +Networking support is currently not finished. +errno issues fixed by Andrew Bachmann. + +Old stuff: + +François Revol - revol at free dot fr - April 2002 + +The configure script should guess the configuration itself, +however I still didn't test building on the net_server version of BeOS. + +FFserver is broken (needs poll() implementation). + +There are still issues with errno codes, which are negative in BeOS, and +that FFmpeg negates when returning. This ends up turning errors into +valid results, then crashes. +(To be fixed) + +@chapter Developers Guide + +@section API +@itemize +@item libavcodec is the library containing the codecs (both encoding and +decoding). Look at @file{libavcodec/apiexample.c} to see how to use it. + +@item libavformat is the library containing the file format handling (mux and +demux code for several formats). Look at @file{ffplay.c} to use it in a +player. See @file{output_example.c} to use it to generate audio or video +streams. + +@end itemize + +@section Integrating libavcodec or libavformat in your program + +You can integrate all the source code of the libraries to link them +statically to avoid any version problem. All you need is to provide a +'config.mak' and a 'config.h' in the parent directory. See the defines +generated by ./configure to understand what is needed. + +You can use libavcodec or libavformat in your commercial program, but +@emph{any patch you make must be published}. The best way to proceed is +to send your patches to the FFmpeg mailing list. + +@node Coding Rules +@section Coding Rules + +FFmpeg is programmed in the ISO C90 language with a few additional +features from ISO C99, namely: +@itemize @bullet +@item +the @samp{inline} keyword; +@item +@samp{//} comments; +@item +designated struct initializers (@samp{struct s x = @{ .i = 17 @};}) +@item +compound literals (@samp{x = (struct s) @{ 17, 23 @};}) +@end itemize + +These features are supported by all compilers we care about, so we won't +accept patches to remove their use unless they absolutely don't impair +clarity and performance. + +All code must compile with GCC 2.95 and GCC 3.3. Currently, FFmpeg also +compiles with several other compilers, such as the Compaq ccc compiler +or Sun Studio 9, and we would like to keep it that way unless it would +be exceedingly involved. To ensure compatibility, please don't use any +additional C99 features or GCC extensions. Especially watch out for: +@itemize @bullet +@item +mixing statements and declarations; +@item +@samp{long long} (use @samp{int64_t} instead); +@item +@samp{__attribute__} not protected by @samp{#ifdef __GNUC__} or similar; +@item +GCC statement expressions (@samp{(x = (@{ int y = 4; y; @})}). +@end itemize + +Indent size is 4. +The presentation is the one specified by 'indent -i4 -kr -nut'. +The TAB character is forbidden outside of Makefiles as is any +form of trailing whitespace. Commits containing either will be +rejected by the CVS repository. + +Main priority in FFmpeg is simplicity and small code size (=less +bugs). + +Comments: Use the JavaDoc/Doxygen +format (see examples below) so that code documentation +can be generated automatically. All nontrivial functions should have a comment +above them explaining what the function does, even if it's just one sentence. +All structures and their member variables should be documented, too. +@example +/** + * @@file mpeg.c + * MPEG codec. + * @@author ... + */ + +/** + * Summary sentence. + * more text ... + * ... + */ +typedef struct Foobar@{ + int var1; /**< var1 description */ + int var2; ///< var2 description + /** var3 description */ + int var3; +@} Foobar; + +/** + * Summary sentence. + * more text ... + * ... + * @@param my_parameter description of my_parameter + * @@return return value description + */ +int myfunc(int my_parameter) +... +@end example + +fprintf and printf are forbidden in libavformat and libavcodec, +please use av_log() instead. + +@node CVS Policy +@section CVS Policy + +@enumerate +@item + You must not commit code which breaks FFmpeg! (Meaning unfinished but + enabled code which breaks compilation or compiles but does not work or + breaks the regression tests) + You can commit unfinished stuff (for testing etc), but it must be disabled + (#ifdef etc) by default so it does not interfere with other developers' + work. +@item + You don't have to over-test things. If it works for you, and you think it + should work for others, then commit. If your code has problems + (portability, triggers compiler bugs, unusual environment etc) they will be + reported and eventually fixed. +@item + Do not commit unrelated changes together, split them into self-contained + pieces. +@item + Do not change behavior of the program (renaming options etc) without + first discussing it on the ffmpeg-devel mailing list. Do not remove + functionality from the code. Just improve! + + Note: Redundant code can be removed. +@item + Do not commit changes to the build system (Makefiles, configure script) + which change behavior, defaults etc, without asking first. The same + applies to compiler warning fixes, trivial looking fixes and to code + maintained by other developers. We usually have a reason for doing things + the way we do. Send your changes as patches to the ffmpeg-devel mailing + list, and if the code maintainers say OK, you may commit. This does not + apply to files you wrote and/or maintain. +@item + We refuse source indentation and other cosmetic changes if they are mixed + with functional changes, such commits will be rejected and removed. Every + developer has his own indentation style, you should not change it. Of course + if you (re)write something, you can use your own style, even though we would + prefer if the indentation throughout FFmpeg was consistent (Many projects + force a given indentation style - we don't.). If you really need to make + indentation changes (try to avoid this), separate them strictly from real + changes. + + NOTE: If you had to put if()@{ .. @} over a large (> 5 lines) chunk of code, + then either do NOT change the indentation of the inner part within (don't + move it to the right)! or do so in a separate commit +@item + Always fill out the commit log message. Describe in a few lines what you + changed and why. You can refer to mailing list postings if you fix a + particular bug. Comments such as "fixed!" or "Changed it." are unacceptable. +@item + If you apply a patch by someone else, include the name and email address in + the CVS log message. Since the ffmpeg-cvslog mailing list is publicly + archived you should add some SPAM protection to the email address. Send an + answer to ffmpeg-devel (or wherever you got the patch from) saying that + you applied the patch. +@item + Do NOT commit to code actively maintained by others without permission. Send + a patch to ffmpeg-devel instead. +@item + Subscribe to the ffmpeg-cvslog mailing list. The diffs of all CVS commits + are sent there and reviewed by all the other developers. Bugs and possible + improvements or general questions regarding commits are discussed there. We + expect you to react if problems with your code are uncovered. +@item + Update the documentation if you change behavior or add features. If you are + unsure how best to do this, send a patch to ffmpeg-devel, the documentation + maintainer(s) will review and commit your stuff. +@item + Revert a commit ONLY in case of a big blunder like committing something not + intended to be committed or committing a wrong file, the wrong version of a + patch, CVS policy violation or broken code and you are going to recommit the + right thing immediately. + + Never revert changes made a long time ago or buggy code. Fix it in the + normal way instead. +@item + Never write to unallocated memory, never write over the end of arrays, + always check values read from some untrusted source before using them + as array index or other risky things. +@item + Remember to check if you need to bump versions for the specific libav + parts (libavutil, libavcodec, libavformat) you are changing. You need + to change the version integer and the version string. + Incrementing the first component means no backward compatibility to + previous versions (e.g. removal of a function). + Incrementing the second component means backward compatible change + (e.g. addition of a function). + Incrementing the third component means a noteworthy binary compatible + change (e.g. encoder bug fix that matters for the decoder). +@item + If you add a new codec, remember to update the changelog, add it to + the supported codecs table in the documentation and bump the second + component of the @file{libavcodec} version number appropriately. If + it has a fourcc, add it to @file{libavformat/avienc.c}, even if it + is only a decoder. +@end enumerate + +We think our rules are not too hard. If you have comments, contact us. + +Note, these rules are mostly borrowed from the MPlayer project. + +@subsection Renaming/moving files or content of files + You CANNOT do that. Post a request for such a change to the mailing list + Do NOT remove & readd a file - it will kill the changelog!!!! + +@section Submitting patches + +First, (@pxref{Coding Rules}) above if you didn't yet. + +When you submit your patch, try to send a unified diff (diff '-up' +option). I cannot read other diffs :-) + +Also please do not submit patches which contain several unrelated changes. +Split them into individual self-contained patches; this makes reviewing +them much easier. + +Run the regression tests before submitting a patch so that you can +verify that there are no big problems. + +Patches should be posted as base64 encoded attachments (or any other +encoding which ensures that the patch won't be trashed during +transmission) to the ffmpeg-devel mailing list, see +@url{http://www1.mplayerhq.hu/mailman/listinfo/ffmpeg-devel} + +It also helps quite a bit if you tell us what the patch does (for example +'replaces lrint by lrintf'), and why (for example '*BSD isn't C99 compliant +and has no lrint()') + +We reply to all submitted patches and either apply or reject with some +explanation why, but sometimes we are quite busy so it can take a week or two. + +@section Regression tests + +Before submitting a patch (or committing to CVS), you should at least +test that you did not break anything. + +The regression tests build a synthetic video stream and a synthetic +audio stream. These are then encoded and decoded with all codecs or +formats. The CRC (or MD5) of each generated file is recorded in a +result file. A 'diff' is launched to compare the reference results and +the result file. + +The regression tests then go on to test the FFserver code with a +limited set of streams. It is important that this step runs correctly +as well. + +Run 'make test' to test all the codecs and formats. + +Run 'make fulltest' to test all the codecs, formats and FFserver. + +[Of course, some patches may change the results of the regression tests. In +this case, the reference results of the regression tests shall be modified +accordingly]. + +@bye diff --git a/mpeg4/src/doc/ffmpeg_powerpc_performance_evaluation_howto.txt b/mpeg4/src/doc/ffmpeg_powerpc_performance_evaluation_howto.txt new file mode 100644 index 00000000..a331212f --- /dev/null +++ b/mpeg4/src/doc/ffmpeg_powerpc_performance_evaluation_howto.txt @@ -0,0 +1,163 @@ +FFmpeg & evaluating performance on the PowerPC Architecture HOWTO + +(c) 2003-2004 Romain Dolbeau + + + +I - Introduction + +The PowerPC architecture and its SIMD extension AltiVec offer some +interesting tools to evaluate performance and improve the code. +This document tries to explain how to use those tools with FFmpeg. + +The architecture itself offers two ways to evaluate the performance of +a given piece of code: + +1) The Time Base Registers (TBL) +2) The Performance Monitor Counter Registers (PMC) + +The first ones are always available, always active, but they're not very +accurate: the registers increment by one every four *bus* cycles. On +my 667 Mhz tiBook (ppc7450), this means once every twenty *processor* +cycles. So we won't use that. + +The PMC are much more useful: not only can they report cycle-accurate +timing, but they can also be used to monitor many other parameters, +such as the number of AltiVec stalls for every kind of instruction, +or instruction cache misses. The downside is that not all processors +support the PMC (all G3, all G4 and the 970 do support them), and +they're inactive by default - you need to activate them with a +dedicated tool. Also, the number of available PMC depends on the +procesor: the various 604 have 2, the various 75x (aka. G3) have 4, +and the various 74xx (aka G4) have 6. + +*WARNING*: The PowerPC 970 is not very well documented, and its PMC +registers are 64 bits wide. To properly notify the code, you *must* +tune for the 970 (using --tune=970), or the code will assume 32 bit +registers. + + +II - Enabling FFmpeg PowerPC performance support + +This needs to be done by hand. First, you need to configure FFmpeg as +usual, but add the "--powerpc-perf-enable" option. For instance: + +##### +./configure --prefix=/usr/local/ffmpeg-cvs --cc=gcc-3.3 --tune=7450 --powerpc-perf-enable +##### + +This will configure FFmpeg to install inside /usr/local/ffmpeg-cvs, +compiling with gcc-3.3 (you should try to use this one or a newer +gcc), and tuning for the PowerPC 7450 (i.e. the newer G4; as a rule of +thumb, those at 550Mhz and more). It will also enable the PMC. + +You may also edit the file "config.h" to enable the following line: + +##### +// #define ALTIVEC_USE_REFERENCE_C_CODE 1 +##### + +If you enable this line, then the code will not make use of AltiVec, +but will use the reference C code instead. This is useful to compare +performance between two versions of the code. + +Also, the number of enabled PMC is defined in "libavcodec/ppc/dsputil_ppc.h": + +##### +#define POWERPC_NUM_PMC_ENABLED 4 +##### + +If you have a G4 CPU, you can enable all 6 PMC. DO NOT enable more +PMC than available on your CPU! + +Then, simply compile FFmpeg as usual (make && make install). + + + +III - Using FFmpeg PowerPC performance support + +This FFmeg can be used exactly as usual. But before exiting, FFmpeg +will dump a per-function report that looks like this: + +##### +PowerPC performance report + Values are from the PMC registers, and represent whatever the + registers are set to record. + Function "gmc1_altivec" (pmc1): + min: 231 + max: 1339867 + avg: 558.25 (255302) + Function "gmc1_altivec" (pmc2): + min: 93 + max: 2164 + avg: 267.31 (255302) + Function "gmc1_altivec" (pmc3): + min: 72 + max: 1987 + avg: 276.20 (255302) +(...) +##### + +In this example, PMC1 was set to record CPU cycles, PMC2 was set to +record AltiVec Permute Stall Cycles, and PMC3 was set to record AltiVec +Issue Stalls. + +The function "gmc1_altivec" was monitored 255302 times, and the +minimum execution time was 231 processor cycles. The max and average +aren't much use, as it's very likely the OS interrupted execution for +reasons of its own :-( + +With the exact same settings and source file, but using the reference C +code we get: + +##### +PowerPC performance report + Values are from the PMC registers, and represent whatever the + registers are set to record. + Function "gmc1_altivec" (pmc1): + min: 592 + max: 2532235 + avg: 962.88 (255302) + Function "gmc1_altivec" (pmc2): + min: 0 + max: 33 + avg: 0.00 (255302) + Function "gmc1_altivec" (pmc3): + min: 0 + max: 350 + avg: 0.03 (255302) +(...) +##### + +592 cycles, so the fastest AltiVec execution is about 2.5x faster than +the fastest C execution in this example. It's not perfect but it's not +bad (well I wrote this function so I can't say otherwise :-). + +Once you have that kind of report, you can try to improve things by +finding what goes wrong and fixing it; in the example above, one +should try to diminish the number of AltiVec stalls, as this *may* +improve performance. + + + +IV) Enabling the PMC in Mac OS X + +This is easy. Use "Monster" and "monster". Those tools come from +Apple's CHUD package, and can be found hidden in the developer web +site & FTP site. "MONster" is the graphical application, use it to +generate a config file specifying what each register should +monitor. Then use the command-line application "monster" to use that +config file, and enjoy the results. + +Note that "MONster" can be used for many other things, but it's +documented by Apple, it's not my subject. + + + +V) Enabling the PMC on Linux + +I don't know how to do it, sorry :-) Any idea very much welcome. + +-- +Romain Dolbeau + diff --git a/mpeg4/src/doc/ffplay-doc.texi b/mpeg4/src/doc/ffplay-doc.texi new file mode 100644 index 00000000..f3e9dc33 --- /dev/null +++ b/mpeg4/src/doc/ffplay-doc.texi @@ -0,0 +1,110 @@ +\input texinfo @c -*- texinfo -*- + +@settitle FFplay Documentation +@titlepage +@sp 7 +@center @titlefont{FFplay Documentation} +@sp 3 +@end titlepage + + +@chapter Introduction + +@c man begin DESCRIPTION +FFplay is a very simple and portable media player using the FFmpeg +libraries and the SDL library. It is mostly used as a testbed for the +various FFmpeg APIs. +@c man end + +@chapter Invocation + +@section Syntax +@example +@c man begin SYNOPSIS +ffplay [options] @file{input_file} +@c man end +@end example + +@c man begin OPTIONS +@section Main options + +@table @option +@item -h +show help +@item -x width +force displayed width +@item -y height +force displayed height +@item -an +disable audio +@item -vn +disable video +@item -nodisp +disable graphical display +@item -f fmt +force format +@item -img img_fmt +This option is used to force a given image format +when playing image sequences. Example: +@example +ffplay -img pgmyuv tests/vsynth1/%d.pgm +@end example +@end table + +@section Advanced options +@table @option +@item -stats +Show the stream duration, the codec parameters, the current position in +the stream and the audio/video synchronisation drift. +@item -rtp_tcp +Force RTP/TCP protocol usage instead of RTP/UDP. It is only meaningful +if you are streaming with the RTSP protocol. +@item -sync type +Set the master clock to audio (@code{type=audio}), video +(@code{type=video}) or external (@code{type=ext}). Default is audio. The +master clock is used to control audio-video synchronization. Most media +players use audio as master clock, but in some cases (streaming or high +quality broadcast) it is necessary to change that. This option is mainly +used for debugging purposes. +@end table + +@section While playing + +@table @key +@item q, ESC +quit + +@item f +toggle full screen + +@item p, SPC +pause + +@item a +cycle audio channel + +@item v +cycle video channel + +@item w +show audio waves +@end table + +@c man end + +@ignore + +@setfilename ffplay +@settitle FFplay media player + +@c man begin SEEALSO +ffmpeg(1), ffserver(1) and the html documentation of @file{ffmpeg}. +@c man end + +@c man begin AUTHOR +Fabrice Bellard +@c man end + +@end ignore + +@bye diff --git a/mpeg4/src/doc/ffserver-doc.texi b/mpeg4/src/doc/ffserver-doc.texi new file mode 100644 index 00000000..ed67bb6c --- /dev/null +++ b/mpeg4/src/doc/ffserver-doc.texi @@ -0,0 +1,224 @@ +\input texinfo @c -*- texinfo -*- + +@settitle FFserver Documentation +@titlepage +@sp 7 +@center @titlefont{FFserver Documentation} +@sp 3 +@end titlepage + + +@chapter Introduction + +@c man begin DESCRIPTION +FFserver is a streaming server for both audio and video. It supports +several live feeds, streaming from files and time shifting on live feeds +(you can seek to positions in the past on each live feed, provided you +specify a big enough feed storage in ffserver.conf). + +This documentation covers only the streaming aspects of ffserver / +ffmpeg. All questions about parameters for ffmpeg, codec questions, +etc. are not covered here. Read @file{ffmpeg-doc.html} for more +information. +@c man end + +@chapter QuickStart + +[Contributed by Philip Gladstone, philip-ffserver at gladstonefamily dot net] + +@section What can this do? + +When properly configured and running, you can capture video and audio in real +time from a suitable capture card, and stream it out over the Internet to +either Windows Media Player or RealAudio player (with some restrictions). + +It can also stream from files, though that is currently broken. Very often, a +web server can be used to serve up the files just as well. + +It can stream prerecorded video from .ffm files, though it is somewhat tricky +to make it work correctly. + +@section What do I need? + +I use Linux on a 900MHz Duron with a cheapo Bt848 based TV capture card. I'm +using stock Linux 2.4.17 with the stock drivers. [Actually that isn't true, +I needed some special drivers for my motherboard-based sound card.] + +I understand that FreeBSD systems work just fine as well. + +@section How do I make it work? + +First, build the kit. It *really* helps to have installed LAME first. Then when +you run the ffserver ./configure, make sure that you have the --enable-mp3lame +flag turned on. + +LAME is important as it allows for streaming audio to Windows Media Player. +Don't ask why the other audio types do not work. + +As a simple test, just run the following two command lines (assuming that you +have a V4L video capture card): + +@example +./ffserver -f doc/ffserver.conf & +./ffmpeg http://localhost:8090/feed1.ffm +@end example + +At this point you should be able to go to your Windows machine and fire up +Windows Media Player (WMP). Go to Open URL and enter + +@example + http://:8090/test.asf +@end example + +You should (after a short delay) see video and hear audio. + +WARNING: trying to stream test1.mpg doesn't work with WMP as it tries to +transfer the entire file before starting to play. +The same is true of AVI files. + +@section What happens next? + +You should edit the ffserver.conf file to suit your needs (in terms of +frame rates etc). Then install ffserver and ffmpeg, write a script to start +them up, and off you go. + +@section Troubleshooting + +@subsection I don't hear any audio, but video is fine. + +Maybe you didn't install LAME, or got your ./configure statement wrong. Check +the ffmpeg output to see if a line referring to MP3 is present. If not, then +your configuration was incorrect. If it is, then maybe your wiring is not +set up correctly. Maybe the sound card is not getting data from the right +input source. Maybe you have a really awful audio interface (like I do) +that only captures in stereo and also requires that one channel be flipped. +If you are one of these people, then export 'AUDIO_FLIP_LEFT=1' before +starting ffmpeg. + +@subsection The audio and video loose sync after a while. + +Yes, they do. + +@subsection After a long while, the video update rate goes way down in WMP. + +Yes, it does. Who knows why? + +@subsection WMP 6.4 behaves differently to WMP 7. + +Yes, it does. Any thoughts on this would be gratefully received. These +differences extend to embedding WMP into a web page. [There are two +object IDs that you can use: The old one, which does not play well, and +the new one, which does (both tested on the same system). However, +I suspect that the new one is not available unless you have installed WMP 7]. + +@section What else can it do? + +You can replay video from .ffm files that was recorded earlier. +However, there are a number of caveats, including the fact that the +ffserver parameters must match the original parameters used to record the +file. If they do not, then ffserver deletes the file before recording into it. +(Now that I write this, it seems broken). + +You can fiddle with many of the codec choices and encoding parameters, and +there are a bunch more parameters that you cannot control. Post a message +to the mailing list if there are some 'must have' parameters. Look in +ffserver.conf for a list of the currently available controls. + +It will automatically generate the ASX or RAM files that are often used +in browsers. These files are actually redirections to the underlying ASF +or RM file. The reason for this is that the browser often fetches the +entire file before starting up the external viewer. The redirection files +are very small and can be transferred quickly. [The stream itself is +often 'infinite' and thus the browser tries to download it and never +finishes.] + +@section Tips + +* When you connect to a live stream, most players (WMP, RA, etc) want to +buffer a certain number of seconds of material so that they can display the +signal continuously. However, ffserver (by default) starts sending data +in realtime. This means that there is a pause of a few seconds while the +buffering is being done by the player. The good news is that this can be +cured by adding a '?buffer=5' to the end of the URL. This means that the +stream should start 5 seconds in the past -- and so the first 5 seconds +of the stream are sent as fast as the network will allow. It will then +slow down to real time. This noticeably improves the startup experience. + +You can also add a 'Preroll 15' statement into the ffserver.conf that will +add the 15 second prebuffering on all requests that do not otherwise +specify a time. In addition, ffserver will skip frames until a key_frame +is found. This further reduces the startup delay by not transferring data +that will be discarded. + +* You may want to adjust the MaxBandwidth in the ffserver.conf to limit +the amount of bandwidth consumed by live streams. + +@section Why does the ?buffer / Preroll stop working after a time? + +It turns out that (on my machine at least) the number of frames successfully +grabbed is marginally less than the number that ought to be grabbed. This +means that the timestamp in the encoded data stream gets behind realtime. +This means that if you say 'Preroll 10', then when the stream gets 10 +or more seconds behind, there is no Preroll left. + +Fixing this requires a change in the internals of how timestamps are +handled. + +@section Does the @code{?date=} stuff work. + +Yes (subject to the limitation outlined above). Also note that whenever you +start ffserver, it deletes the ffm file (if any parameters have changed), +thus wiping out what you had recorded before. + +The format of the @code{?date=xxxxxx} is fairly flexible. You should use one +of the following formats (the 'T' is literal): + +@example +* YYYY-MM-DDTHH:MM:SS (localtime) +* YYYY-MM-DDTHH:MM:SSZ (UTC) +@end example + +You can omit the YYYY-MM-DD, and then it refers to the current day. However +note that @samp{?date=16:00:00} refers to 16:00 on the current day -- this +may be in the future and so is unlikely to be useful. + +You use this by adding the ?date= to the end of the URL for the stream. +For example: @samp{http://localhost:8080/test.asf?date=2002-07-26T23:05:00}. + +@chapter Invocation +@section Syntax +@example +@c man begin SYNOPSIS +ffserver [options] +@c man end +@end example + +@section Options +@c man begin OPTIONS +@table @option +@item -L +Print the license. +@item -h +Print the help. +@item -f configfile +Use @file{configfile} instead of @file{/etc/ffserver.conf}. +@end table +@c man end + +@ignore + +@setfilename ffsserver +@settitle FFserver video server + +@c man begin SEEALSO +ffmpeg(1), ffplay(1), the @file{ffmpeg/doc/ffserver.conf} example and +the HTML documentation of @file{ffmpeg}. +@c man end + +@c man begin AUTHOR +Fabrice Bellard +@c man end + +@end ignore + +@bye diff --git a/mpeg4/src/doc/ffserver.conf b/mpeg4/src/doc/ffserver.conf new file mode 100644 index 00000000..a3b3ff41 --- /dev/null +++ b/mpeg4/src/doc/ffserver.conf @@ -0,0 +1,349 @@ +# Port on which the server is listening. You must select a different +# port from your standard HTTP web server if it is running on the same +# computer. +Port 8090 + +# Address on which the server is bound. Only useful if you have +# several network interfaces. +BindAddress 0.0.0.0 + +# Number of simultaneous requests that can be handled. Since FFServer +# is very fast, it is more likely that you will want to leave this high +# and use MaxBandwidth, below. +MaxClients 1000 + +# This the maximum amount of kbit/sec that you are prepared to +# consume when streaming to clients. +MaxBandwidth 1000 + +# Access log file (uses standard Apache log file format) +# '-' is the standard output. +CustomLog - + +# Suppress that if you want to launch ffserver as a daemon. +NoDaemon + + +################################################################## +# Definition of the live feeds. Each live feed contains one video +# and/or audio sequence coming from an ffmpeg encoder or another +# ffserver. This sequence may be encoded simultaneously with several +# codecs at several resolutions. + + + +# You must use 'ffmpeg' to send a live feed to ffserver. In this +# example, you can type: +# +# ffmpeg http://localhost:8090/feed1.ffm + +# ffserver can also do time shifting. It means that it can stream any +# previously recorded live stream. The request should contain: +# "http://xxxx?date=[YYYY-MM-DDT][[HH:]MM:]SS[.m...]".You must specify +# a path where the feed is stored on disk. You also specify the +# maximum size of the feed, where zero means unlimited. Default: +# File=/tmp/feed_name.ffm FileMaxSize=5M +File /tmp/feed1.ffm +FileMaxSize 200K + +# You could specify +# ReadOnlyFile /saved/specialvideo.ffm +# This marks the file as readonly and it will not be deleted or updated. + +# Specify launch in order to start ffmpeg automatically. +# First ffmpeg must be defined with an appropriate path if needed, +# after that options can follow, but avoid adding the http:// field +#Launch ffmpeg + +# Only allow connections from localhost to the feed. +ACL allow 127.0.0.1 + + + + +################################################################## +# Now you can define each stream which will be generated from the +# original audio and video stream. Each format has a filename (here +# 'test1.mpg'). FFServer will send this stream when answering a +# request containing this filename. + + + +# coming from live feed 'feed1' +Feed feed1.ffm + +# Format of the stream : you can choose among: +# mpeg : MPEG-1 multiplexed video and audio +# mpegvideo : only MPEG-1 video +# mp2 : MPEG-2 audio (use AudioCodec to select layer 2 and 3 codec) +# ogg : Ogg format (Vorbis audio codec) +# rm : RealNetworks-compatible stream. Multiplexed audio and video. +# ra : RealNetworks-compatible stream. Audio only. +# mpjpeg : Multipart JPEG (works with Netscape without any plugin) +# jpeg : Generate a single JPEG image. +# asf : ASF compatible streaming (Windows Media Player format). +# swf : Macromedia Flash compatible stream +# avi : AVI format (MPEG-4 video, MPEG audio sound) +# master : special ffmpeg stream used to duplicate a server +Format mpeg + +# Bitrate for the audio stream. Codecs usually support only a few +# different bitrates. +AudioBitRate 32 + +# Number of audio channels: 1 = mono, 2 = stereo +AudioChannels 1 + +# Sampling frequency for audio. When using low bitrates, you should +# lower this frequency to 22050 or 11025. The supported frequencies +# depend on the selected audio codec. +AudioSampleRate 44100 + +# Bitrate for the video stream +VideoBitRate 64 + +# Ratecontrol buffer size +VideoBufferSize 40 + +# Number of frames per second +VideoFrameRate 3 + +# Size of the video frame: WxH (default: 160x128) +# The following abbreviations are defined: sqcif, qcif, cif, 4cif +VideoSize 160x128 + +# Transmit only intra frames (useful for low bitrates, but kills frame rate). +#VideoIntraOnly + +# If non-intra only, an intra frame is transmitted every VideoGopSize +# frames. Video synchronization can only begin at an intra frame. +VideoGopSize 12 + +# More MPEG-4 parameters +# VideoHighQuality +# Video4MotionVector + +# Choose your codecs: +#AudioCodec mp2 +#VideoCodec mpeg1video + +# Suppress audio +#NoAudio + +# Suppress video +#NoVideo + +#VideoQMin 3 +#VideoQMax 31 + +# Set this to the number of seconds backwards in time to start. Note that +# most players will buffer 5-10 seconds of video, and also you need to allow +# for a keyframe to appear in the data stream. +#Preroll 15 + +# ACL: + +# You can allow ranges of addresses (or single addresses) +#ACL ALLOW + +# You can deny ranges of addresses (or single addresses) +#ACL DENY + +# You can repeat the ACL allow/deny as often as you like. It is on a per +# stream basis. The first match defines the action. If there are no matches, +# then the default is the inverse of the last ACL statement. +# +# Thus 'ACL allow localhost' only allows access from localhost. +# 'ACL deny 1.0.0.0 1.255.255.255' would deny the whole of network 1 and +# allow everybody else. + + + + +################################################################## +# Example streams + + +# Multipart JPEG + +# +#Feed feed1.ffm +#Format mpjpeg +#VideoFrameRate 2 +#VideoIntraOnly +#NoAudio +#Strict -1 +# + + +# Single JPEG + +# +#Feed feed1.ffm +#Format jpeg +#VideoFrameRate 2 +#VideoIntraOnly +##VideoSize 352x240 +#NoAudio +#Strict -1 +# + + +# Flash + +# +#Feed feed1.ffm +#Format swf +#VideoFrameRate 2 +#VideoIntraOnly +#NoAudio +# + + +# ASF compatible + + +Feed feed1.ffm +Format asf +VideoFrameRate 15 +VideoSize 352x240 +VideoBitRate 256 +VideoBufferSize 40 +VideoGopSize 30 +AudioBitRate 64 +StartSendOnKey + + + +# MP3 audio + +# +#Feed feed1.ffm +#Format mp2 +#AudioCodec mp3 +#AudioBitRate 64 +#AudioChannels 1 +#AudioSampleRate 44100 +#NoVideo +# + + +# Ogg Vorbis audio + +# +#Feed feed1.ffm +#Title "Stream title" +#AudioBitRate 64 +#AudioChannels 2 +#AudioSampleRate 44100 +#NoVideo +# + + +# Real with audio only at 32 kbits + +# +#Feed feed1.ffm +#Format rm +#AudioBitRate 32 +#NoVideo +#NoAudio +# + + +# Real with audio and video at 64 kbits + +# +#Feed feed1.ffm +#Format rm +#AudioBitRate 32 +#VideoBitRate 128 +#VideoFrameRate 25 +#VideoGopSize 25 +#NoAudio +# + + +################################################################## +# A stream coming from a file: you only need to set the input +# filename and optionally a new format. Supported conversions: +# AVI -> ASF + +# +#File "/usr/local/httpd/htdocs/tlive.rm" +#NoAudio +# + +# +#File "/usr/local/httpd/htdocs/test.asf" +#NoAudio +#Author "Me" +#Copyright "Super MegaCorp" +#Title "Test stream from disk" +#Comment "Test comment" +# + + +################################################################## +# RTSP examples +# +# You can access this stream with the RTSP URL: +# rtsp://localhost:5454/test1-rtsp.mpg +# +# A non-standard RTSP redirector is also created. Its URL is: +# http://localhost:8090/test1-rtsp.rtsp + +# +#Format rtp +#File "/usr/local/httpd/htdocs/test1.mpg" +# + + +################################################################## +# SDP/multicast examples +# +# If you want to send your stream in multicast, you must set the +# multicast address with MulticastAddress. The port and the TTL can +# also be set. +# +# An SDP file is automatically generated by ffserver by adding the +# 'sdp' extension to the stream name (here +# http://localhost:8090/test1-sdp.sdp). You should usually give this +# file to your player to play the stream. +# +# The 'NoLoop' option can be used to avoid looping when the stream is +# terminated. + +# +#Format rtp +#File "/usr/local/httpd/htdocs/test1.mpg" +#MulticastAddress 224.124.0.1 +#MulticastPort 5000 +#MulticastTTL 16 +#NoLoop +# + + +################################################################## +# Special streams + +# Server status + + +Format status + +# Only allow local people to get the status +ACL allow localhost +ACL allow 192.168.0.0 192.168.255.255 + +#FaviconURL http://pond1.gladstonefamily.net:8080/favicon.ico + + + +# Redirect index.html to the appropriate site + + +URL http://www.ffmpeg.org/ + + + diff --git a/mpeg4/src/doc/hooks.texi b/mpeg4/src/doc/hooks.texi new file mode 100644 index 00000000..a9c1255e --- /dev/null +++ b/mpeg4/src/doc/hooks.texi @@ -0,0 +1,49 @@ +\input texinfo @c -*- texinfo -*- + +@settitle Video Hook Documentation +@titlepage +@sp 7 +@center @titlefont{Video Hook Documentation} +@sp 3 +@end titlepage + + +@chapter Introduction + + +The video hook functionality is designed (mostly) for live video. It allows +the video to be modified or examined between the decoder and the encoder. + +Any number of hook modules can be placed inline, and they are run in the +order that they were specified on the ffmpeg command line. + +Three modules are provided and are described below. They are all intended to +be used as a base for your own modules. + +Modules are loaded using the -vhook option to ffmpeg. The value of this parameter +is a space separated list of arguments. The first is the module name, and the rest +are passed as arguments to the Configure function of the module. + +@section null.c + +This does nothing. Actually it converts the input image to RGB24 and then converts +it back again. This is meant as a sample that you can use to test your setup. + +@section fish.c + +This implements a 'fish detector'. Essentially it converts the image into HSV +space and tests whether more than a certain percentage of the pixels fall into +a specific HSV cuboid. If so, then the image is saved into a file for processing +by other bits of code. + +Why use HSV? It turns out that HSV cuboids represent a more compact range of +colors than would an RGB cuboid. + +@section imlib2.c + +This allows a caption to be placed onto each frame. It supports inserting the +time and date. By using the imlib functions, it would be easy to add your own +graphical logo, add a frame/border, etc. + + +@bye diff --git a/mpeg4/src/doc/optimization.txt b/mpeg4/src/doc/optimization.txt new file mode 100644 index 00000000..011e9e4f --- /dev/null +++ b/mpeg4/src/doc/optimization.txt @@ -0,0 +1,158 @@ +optimization Tips (for libavcodec): + +What to optimize: +If you plan to do non-x86 architecture specific optimizations (SIMD normally), +then take a look in the i386/ directory, as most important functions are +already optimized for MMX. + +If you want to do x86 optimizations then you can either try to finetune the +stuff in the i386 directory or find some other functions in the C source to +optimize, but there aren't many left. + +Understanding these overoptimized functions: +As many functions tend to be a bit difficult to understand because +of optimizations, it can be hard to optimize them further, or write +architecture-specific versions. It is recommened to look at older +CVS versions of the interesting files (just use ViewCVS at +http://www1.mplayerhq.hu/cgi-bin/cvsweb.cgi/ffmpeg/?cvsroot=FFMpeg). +Alternatively, look into the other architecture-specific versions in +the i386/, ppc/, alpha/ subdirectories. Even if you don't exactly +comprehend the instructions, it could help understanding the functions +and how they can be optimized. + +NOTE: If you still don't understand some function, ask at our mailing list!!! +(http://www1.mplayerhq.hu/mailman/listinfo/ffmpeg-devel) + + + +WTF is that function good for ....: +The primary purpose of that list is to avoid wasting time to optimize functions +which are rarely used + +put(_no_rnd)_pixels{,_x2,_y2,_xy2} + Used in motion compensation (en/decoding). + +avg_pixels{,_x2,_y2,_xy2} + Used in motion compensation of B-frames. + These are less important than the put*pixels functions. + +avg_no_rnd_pixels* + unused + +pix_abs16x16{,_x2,_y2,_xy2} + Used in motion estimation (encoding) with SAD. + +pix_abs8x8{,_x2,_y2,_xy2} + Used in motion estimation (encoding) with SAD of MPEG-4 4MV only. + These are less important than the pix_abs16x16* functions. + +put_mspel8_mc* / wmv2_mspel8* + Used only in WMV2. + it is not recommended that you waste your time with these, as WMV2 + is an ugly and relatively useless codec. + +mpeg4_qpel* / *qpel_mc* + Used in MPEG-4 qpel motion compensation (encoding & decoding). + The qpel8 functions are used only for 4mv, + the avg_* functions are used only for B-frames. + Optimizing them should have a significant impact on qpel + encoding & decoding. + +qpel{8,16}_mc??_old_c / *pixels{8,16}_l4 + Just used to work around a bug in an old libavcodec encoder version. + Don't optimize them. + +tpel_mc_func {put,avg}_tpel_pixels_tab + Used only for SVQ3, so only optimize them if you need fast SVQ3 decoding. + +add_bytes/diff_bytes + For huffyuv only, optimize if you want a faster ffhuffyuv codec. + +get_pixels / diff_pixels + Used for encoding, easy. + +clear_blocks + easiest to optimize + +gmc + Used for MPEG-4 gmc. + Optimizing this should have a significant effect on the gmc decoding + speed but it's very likely impossible to write in SIMD. + +gmc1 + Used for chroma blocks in MPEG-4 gmc with 1 warp point + (there are 4 luma & 2 chroma blocks per macroblock, so + only 1/3 of the gmc blocks use this, the other 2/3 + use the normal put_pixel* code, but only if there is + just 1 warp point). + Note: DivX5 gmc always uses just 1 warp point. + +pix_sum + Used for encoding. + +hadamard8_diff / sse / sad == pix_norm1 / dct_sad / quant_psnr / rd / bit + Specific compare functions used in encoding, it depends upon the + command line switches which of these are used. + Don't waste your time with dct_sad & quant_psnr, they aren't + really useful. + +put_pixels_clamped / add_pixels_clamped + Used for en/decoding in the IDCT, easy. + Note, some optimized IDCTs have the add/put clamped code included and + then put_pixels_clamped / add_pixels_clamped will be unused. + +idct/fdct + idct (encoding & decoding) + fdct (encoding) + difficult to optimize + +dct_quantize_trellis + Used for encoding with trellis quantization. + difficult to optimize + +dct_quantize + Used for encoding. + +dct_unquantize_mpeg1 + Used in MPEG-1 en/decoding. + +dct_unquantize_mpeg2 + Used in MPEG-2 en/decoding. + +dct_unquantize_h263 + Used in MPEG-4/H.263 en/decoding. + +FIXME remaining functions? +BTW, most of these functions are in dsputil.c/.h, some are in mpegvideo.c/.h. + + + +Alignment: +Some instructions on some architectures have strict alignment restrictions, +for example most SSE/SSE2 instructions on x86. +The minimum guaranteed alignment is written in the .h files, for example: + void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, UINT8 *pixels/*align 8*/, int line_size); + + + +Links: +http://www.aggregate.org/MAGIC/ + +x86-specific: +http://developer.intel.com/design/pentium4/manuals/248966.htm + +The IA-32 Intel Architecture Software Developer's Manual, Volume 2: +Instruction Set Reference +http://developer.intel.com/design/pentium4/manuals/245471.htm + +http://www.agner.org/assem/ + +AMD Athlon Processor x86 Code Optimization Guide: +http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/22007.pdf + +GCC asm links: +official doc but quite ugly +http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html + +a bit old (note "+" is valid for input-output, even though the next disagrees) +http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf diff --git a/mpeg4/src/doc/texi2pod.pl b/mpeg4/src/doc/texi2pod.pl new file mode 100755 index 00000000..c414ffcc --- /dev/null +++ b/mpeg4/src/doc/texi2pod.pl @@ -0,0 +1,427 @@ +#! /usr/bin/perl -w + +# Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + +# This file is part of GNU CC. + +# GNU CC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# GNU CC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with GNU CC; see the file COPYING. If not, write to +# the Free Software Foundation, 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301 USA + +# This does trivial (and I mean _trivial_) conversion of Texinfo +# markup to Perl POD format. It's intended to be used to extract +# something suitable for a manpage from a Texinfo document. + +$output = 0; +$skipping = 0; +%sects = (); +$section = ""; +@icstack = (); +@endwstack = (); +@skstack = (); +@instack = (); +$shift = ""; +%defs = (); +$fnno = 1; +$inf = ""; +$ibase = ""; + +while ($_ = shift) { + if (/^-D(.*)$/) { + if ($1 ne "") { + $flag = $1; + } else { + $flag = shift; + } + $value = ""; + ($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/); + die "no flag specified for -D\n" + unless $flag ne ""; + die "flags may only contain letters, digits, hyphens, dashes and underscores\n" + unless $flag =~ /^[a-zA-Z0-9_-]+$/; + $defs{$flag} = $value; + } elsif (/^-/) { + usage(); + } else { + $in = $_, next unless defined $in; + $out = $_, next unless defined $out; + usage(); + } +} + +if (defined $in) { + $inf = gensym(); + open($inf, "<$in") or die "opening \"$in\": $!\n"; + $ibase = $1 if $in =~ m|^(.+)/[^/]+$|; +} else { + $inf = \*STDIN; +} + +if (defined $out) { + open(STDOUT, ">$out") or die "opening \"$out\": $!\n"; +} + +while(defined $inf) { +while(<$inf>) { + # Certain commands are discarded without further processing. + /^\@(?: + [a-z]+index # @*index: useful only in complete manual + |need # @need: useful only in printed manual + |(?:end\s+)?group # @group .. @end group: ditto + |page # @page: ditto + |node # @node: useful only in .info file + |(?:end\s+)?ifnottex # @ifnottex .. @end ifnottex: use contents + )\b/x and next; + + chomp; + + # Look for filename and title markers. + /^\@setfilename\s+([^.]+)/ and $fn = $1, next; + /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next; + + # Identify a man title but keep only the one we are interested in. + /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do { + if (exists $defs{$1}) { + $fn = $1; + $tl = postprocess($2); + } + next; + }; + + # Look for blocks surrounded by @c man begin SECTION ... @c man end. + # This really oughta be @ifman ... @end ifman and the like, but such + # would require rev'ing all other Texinfo translators. + /^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do { + $output = 1 if exists $defs{$2}; + $sect = $1; + next; + }; + /^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next; + /^\@c\s+man\s+end/ and do { + $sects{$sect} = "" unless exists $sects{$sect}; + $sects{$sect} .= postprocess($section); + $section = ""; + $output = 0; + next; + }; + + # handle variables + /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do { + $defs{$1} = $2; + next; + }; + /^\@clear\s+([a-zA-Z0-9_-]+)/ and do { + delete $defs{$1}; + next; + }; + + next unless $output; + + # Discard comments. (Can't do it above, because then we'd never see + # @c man lines.) + /^\@c\b/ and next; + + # End-block handler goes up here because it needs to operate even + # if we are skipping. + /^\@end\s+([a-z]+)/ and do { + # Ignore @end foo, where foo is not an operation which may + # cause us to skip, if we are presently skipping. + my $ended = $1; + next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex)$/; + + die "\@end $ended without \@$ended at line $.\n" unless defined $endw; + die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw; + + $endw = pop @endwstack; + + if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) { + $skipping = pop @skstack; + next; + } elsif ($ended =~ /^(?:example|smallexample|display)$/) { + $shift = ""; + $_ = ""; # need a paragraph break + } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) { + $_ = "\n=back\n"; + $ic = pop @icstack; + } else { + die "unknown command \@end $ended at line $.\n"; + } + }; + + # We must handle commands which can cause skipping even while we + # are skipping, otherwise we will not process nested conditionals + # correctly. + /^\@ifset\s+([a-zA-Z0-9_-]+)/ and do { + push @endwstack, $endw; + push @skstack, $skipping; + $endw = "ifset"; + $skipping = 1 unless exists $defs{$1}; + next; + }; + + /^\@ifclear\s+([a-zA-Z0-9_-]+)/ and do { + push @endwstack, $endw; + push @skstack, $skipping; + $endw = "ifclear"; + $skipping = 1 if exists $defs{$1}; + next; + }; + + /^\@(ignore|menu|iftex)\b/ and do { + push @endwstack, $endw; + push @skstack, $skipping; + $endw = $1; + $skipping = 1; + next; + }; + + next if $skipping; + + # Character entities. First the ones that can be replaced by raw text + # or discarded outright: + s/\@copyright\{\}/(c)/g; + s/\@dots\{\}/.../g; + s/\@enddots\{\}/..../g; + s/\@([.!? ])/$1/g; + s/\@[:-]//g; + s/\@bullet(?:\{\})?/*/g; + s/\@TeX\{\}/TeX/g; + s/\@pounds\{\}/\#/g; + s/\@minus(?:\{\})?/-/g; + s/\\,/,/g; + + # Now the ones that have to be replaced by special escapes + # (which will be turned back into text by unmunge()) + s/&/&/g; + s/\@\{/{/g; + s/\@\}/}/g; + s/\@\@/&at;/g; + + # Inside a verbatim block, handle @var specially. + if ($shift ne "") { + s/\@var\{([^\}]*)\}/<$1>/g; + } + + # POD doesn't interpret E<> inside a verbatim block. + if ($shift eq "") { + s//>/g; + } else { + s//>/g; + } + + # Single line command handlers. + + /^\@include\s+(.+)$/ and do { + push @instack, $inf; + $inf = gensym(); + + # Try cwd and $ibase. + open($inf, "<" . $1) + or open($inf, "<" . $ibase . "/" . $1) + or die "cannot open $1 or $ibase/$1: $!\n"; + next; + }; + + /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/ + and $_ = "\n=head2 $1\n"; + /^\@subsection\s+(.+)$/ + and $_ = "\n=head3 $1\n"; + + # Block command handlers: + /^\@itemize\s+(\@[a-z]+|\*|-)/ and do { + push @endwstack, $endw; + push @icstack, $ic; + $ic = $1; + $_ = "\n=over 4\n"; + $endw = "itemize"; + }; + + /^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do { + push @endwstack, $endw; + push @icstack, $ic; + if (defined $1) { + $ic = $1 . "."; + } else { + $ic = "1."; + } + $_ = "\n=over 4\n"; + $endw = "enumerate"; + }; + + /^\@([fv]?table)\s+(\@[a-z]+)/ and do { + push @endwstack, $endw; + push @icstack, $ic; + $endw = $1; + $ic = $2; + $ic =~ s/\@(?:samp|strong|key|gcctabopt|option|env)/B/; + $ic =~ s/\@(?:code|kbd)/C/; + $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/; + $ic =~ s/\@(?:file)/F/; + $_ = "\n=over 4\n"; + }; + + /^\@((?:small)?example|display)/ and do { + push @endwstack, $endw; + $endw = $1; + $shift = "\t"; + $_ = ""; # need a paragraph break + }; + + /^\@itemx?\s*(.+)?$/ and do { + if (defined $1) { + # Entity escapes prevent munging by the <> processing below. + $_ = "\n=item $ic\<$1\>\n"; + } else { + $_ = "\n=item $ic\n"; + $ic =~ y/A-Ya-y/B-Zb-z/; + $ic =~ s/(\d+)/$1 + 1/eg; + } + }; + + $section .= $shift.$_."\n"; +} +# End of current file. +close($inf); +$inf = pop @instack; +} + +die "No filename or title\n" unless defined $fn && defined $tl; + +$sects{NAME} = "$fn \- $tl\n"; +$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES}; + +for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS EXAMPLES ENVIRONMENT FILES + BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) { + if(exists $sects{$sect}) { + $head = $sect; + $head =~ s/SEEALSO/SEE ALSO/; + print "=head1 $head\n\n"; + print scalar unmunge ($sects{$sect}); + print "\n"; + } +} + +sub usage +{ + die "usage: $0 [-D toggle...] [infile [outfile]]\n"; +} + +sub postprocess +{ + local $_ = $_[0]; + + # @value{foo} is replaced by whatever 'foo' is defined as. + while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) { + if (! exists $defs{$2}) { + print STDERR "Option $2 not defined\n"; + s/\Q$1\E//; + } else { + $value = $defs{$2}; + s/\Q$1\E/$value/; + } + } + + # Formatting commands. + # Temporary escape for @r. + s/\@r\{([^\}]*)\}/R<$1>/g; + s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g; + s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g; + s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g; + s/\@sc\{([^\}]*)\}/\U$1/g; + s/\@file\{([^\}]*)\}/F<$1>/g; + s/\@w\{([^\}]*)\}/S<$1>/g; + s/\@(?:dmn|math)\{([^\}]*)\}/$1/g; + + # Cross references are thrown away, as are @noindent and @refill. + # (@noindent is impossible in .pod, and @refill is unnecessary.) + # @* is also impossible in .pod; we discard it and any newline that + # follows it. Similarly, our macro @gol must be discarded. + + s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g; + s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g; + s/;\s+\@pxref\{(?:[^\}]*)\}//g; + s/\@noindent\s*//g; + s/\@refill//g; + s/\@gol//g; + s/\@\*\s*\n?//g; + + # @uref can take one, two, or three arguments, with different + # semantics each time. @url and @email are just like @uref with + # one argument, for our purposes. + s/\@(?:uref|url|email)\{([^\},]*)\}/<B<$1>>/g; + s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g; + s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g; + + # Turn B blah> into B I B to + # match Texinfo semantics of @emph inside @samp. Also handle @r + # inside bold. + s/<//g; + 1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B]*)I<([^>]+)>/B<$1>I<$2>B]*)B<([^>]+)>/I<$1>B<$2>I//g; + s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g; + s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g; + + # Extract footnotes. This has to be done after all other + # processing because otherwise the regexp will choke on formatting + # inside @footnote. + while (/\@footnote/g) { + s/\@footnote\{([^\}]+)\}/[$fnno]/; + add_footnote($1, $fnno); + $fnno++; + } + + return $_; +} + +sub unmunge +{ + # Replace escaped symbols with their equivalents. + local $_ = $_[0]; + + s/</E/g; + s/>/E/g; + s/{/\{/g; + s/}/\}/g; + s/&at;/\@/g; + s/&/&/g; + return $_; +} + +sub add_footnote +{ + unless (exists $sects{FOOTNOTES}) { + $sects{FOOTNOTES} = "\n=over 4\n\n"; + } + + $sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++; + $sects{FOOTNOTES} .= $_[0]; + $sects{FOOTNOTES} .= "\n\n"; +} + +# stolen from Symbol.pm +{ + my $genseq = 0; + sub gensym + { + my $name = "GEN" . $genseq++; + my $ref = \*{$name}; + delete $::{$name}; + return $ref; + } +} diff --git a/mpeg4/src/ffinstall.nsi b/mpeg4/src/ffinstall.nsi new file mode 100644 index 00000000..f483b017 --- /dev/null +++ b/mpeg4/src/ffinstall.nsi @@ -0,0 +1,75 @@ +;NSIS Script For FFmpeg + +;Title Of Your Application +Name "FFmpeg" +CompletedText "FFmpeg install completed! Enjoy your meal!" + +; do a CRC check +CRCCheck On + +; output file name +OutFile "FFinstall.exe" + +; license page introduction +LicenseText "You must agree to this license before installing." + +; license data +LicenseData ".\COPYING" + +; the default installation directory +InstallDir "$PROGRAMFILES\FFmpeg" + +;The text to prompt the user to enter a directory +DirText "Please select the folder below" + +Section "Install" + ;Install Files + SetOutPath $INSTDIR + SetCompress Auto + SetOverwrite IfNewer + File ".\ffmpeg.exe" + File ".\SDL.dll" + File ".\ffplay.exe" + File ".\COPYING" + File ".\CREDITS" + + ; documentation + SetOutPath $INSTDIR\doc + File ".\doc\faq.html" + File ".\doc\ffmpeg-doc.html" + File ".\doc\ffplay-doc.html" + + ; Write the uninstall keys for Windows + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FFmpeg" "DisplayName" "FFmpeg (remove only)" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\FFmpeg" "UninstallString" "$INSTDIR\Uninst.exe" +WriteUninstaller "Uninst.exe" +SectionEnd + +Section "Shortcuts" + ;Add Shortcuts +SectionEnd + +UninstallText "This will uninstall FFmpeg from your system" + +Section Uninstall + ; delete files + Delete "$INSTDIR\ffmpeg.exe" + Delete "$INSTDIR\SDL.dll" + Delete "$INSTDIR\ffplay.exe" + Delete "$INSTDIR\COPYING" + Delete "$INSTDIR\CREDITS" + + ; delete documentation + Delete "$INSTDIR\doc\faq.html" + Delete "$INSTDIR\ffmpeg-doc.html" + Delete "$INSTDIR\doc\ffplay-doc.html" + + RMDir /r $INSTDIR\doc + + ; delete uninstaller and unistall registry entries + Delete "$INSTDIR\Uninst.exe" + DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\FFmpeg" + DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\FFmpeg" + RMDir "$INSTDIR" +SectionEnd + diff --git a/mpeg4/src/ffmpeg.c b/mpeg4/src/ffmpeg.c new file mode 100644 index 00000000..d03a5384 --- /dev/null +++ b/mpeg4/src/ffmpeg.c @@ -0,0 +1,4221 @@ +/* + * FFmpeg main + * Copyright (c) 2000-2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#define HAVE_AV_CONFIG_H +#include +#include "avformat.h" +#include "framehook.h" +#include "dsputil.h" +#include "opt.h" + +#ifndef CONFIG_WIN32 +#include +#include +#include +#include +#include +#include +#include +#endif +#ifdef CONFIG_OS2 +#include +#include +#include +#endif +#undef time //needed because HAVE_AV_CONFIG_H is defined on top +#include + +#include "cmdutils.h" + +#undef NDEBUG +#include + +#if !defined(INFINITY) && defined(HUGE_VAL) +#define INFINITY HUGE_VAL +#endif + +/* select an input stream for an output stream */ +typedef struct AVStreamMap { + int file_index; + int stream_index; + int sync_file_index; + int sync_stream_index; +} AVStreamMap; + +/** select an input file for an output file */ +typedef struct AVMetaDataMap { + int out_file; + int in_file; +} AVMetaDataMap; + +extern const OptionDef options[]; + +static void show_help(void); +static void show_license(void); +static int opt_default(const char *opt, const char *arg); + +#define MAX_FILES 20 + +static AVFormatContext *input_files[MAX_FILES]; +static int64_t input_files_ts_offset[MAX_FILES]; +static int nb_input_files = 0; + +static AVFormatContext *output_files[MAX_FILES]; +static int nb_output_files = 0; + +static AVStreamMap stream_maps[MAX_FILES]; +static int nb_stream_maps; + +static AVMetaDataMap meta_data_maps[MAX_FILES]; +static int nb_meta_data_maps; + +static AVInputFormat *file_iformat; +static AVOutputFormat *file_oformat; +static AVImageFormat *image_format; +static int frame_width = 0; +static int frame_height = 0; +static float frame_aspect_ratio = 0; +static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE; +static int frame_padtop = 0; +static int frame_padbottom = 0; +static int frame_padleft = 0; +static int frame_padright = 0; +static int padcolor[3] = {16,128,128}; /* default to black */ +static int frame_topBand = 0; +static int frame_bottomBand = 0; +static int frame_leftBand = 0; +static int frame_rightBand = 0; +static int max_frames[4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX}; +static int frame_rate = 25; +static int frame_rate_base = 1; +static int video_bit_rate = 200*1000; +static int video_bit_rate_tolerance = 4000*1000; +static float video_qscale = 0; +static int video_qmin = 2; +static int video_qmax = 31; +static int video_lmin = 2*FF_QP2LAMBDA; +static int video_lmax = 31*FF_QP2LAMBDA; +static int video_mb_lmin = 2*FF_QP2LAMBDA; +static int video_mb_lmax = 31*FF_QP2LAMBDA; +static int video_qdiff = 3; +static float video_qblur = 0.5; +static float video_qsquish = 0.0; +static float video_qcomp = 0.5; +static uint16_t *intra_matrix = NULL; +static uint16_t *inter_matrix = NULL; +#if 0 //experimental, (can be removed) +static float video_rc_qsquish=1.0; +static float video_rc_qmod_amp=0; +static int video_rc_qmod_freq=0; +#endif +static char *video_rc_override_string=NULL; +static char *video_rc_eq="tex^qComp"; +static int video_rc_buffer_size=0; +static float video_rc_buffer_aggressivity=1.0; +static int video_rc_max_rate=0; +static int video_rc_min_rate=0; +static float video_rc_initial_cplx=0; +static float video_b_qfactor = 1.25; +static float video_b_qoffset = 1.25; +static float video_i_qfactor = -0.8; +static float video_i_qoffset = 0.0; +static int video_intra_quant_bias= FF_DEFAULT_QUANT_BIAS; +static int video_inter_quant_bias= FF_DEFAULT_QUANT_BIAS; +static int me_method = ME_EPZS; +static int video_disable = 0; +static int video_discard = 0; +static int video_codec_id = CODEC_ID_NONE; +static int video_codec_tag = 0; +static int same_quality = 0; +static int b_frames = 0; +static int pre_me = 0; +static int do_deinterlace = 0; +static int workaround_bugs = FF_BUG_AUTODETECT; +static int packet_size = 0; +static int error_rate = 0; +static int strict = 0; +static int top_field_first = -1; +static int sc_threshold = 0; +static int me_threshold = 0; +static int mb_threshold = 0; +static int intra_dc_precision = 8; +static int me_penalty_compensation= 256; +static int frame_skip_threshold= 0; +static int frame_skip_factor= 0; +static int frame_skip_exp= 0; +extern int loop_input; /* currently a hack */ +static int loop_output = AVFMT_NOOUTPUTLOOP; +static int genpts = 0; +static int qp_hist = 0; + +static int gop_size = 12; +static int intra_only = 0; +static int audio_sample_rate = 44100; +static int audio_bit_rate = 64000; +#define QSCALE_NONE -99999 +static float audio_qscale = QSCALE_NONE; +static int audio_disable = 0; +static int audio_channels = 1; +static int audio_codec_id = CODEC_ID_NONE; +static int audio_codec_tag = 0; +static char *audio_language = NULL; + +static int subtitle_codec_id = CODEC_ID_NONE; +static char *subtitle_language = NULL; + +static int mux_rate= 0; +static int mux_packet_size= 0; +static float mux_preload= 0.5; +static float mux_max_delay= 0.7; + +static int64_t recording_time = 0; +static int64_t start_time = 0; +static int64_t rec_timestamp = 0; +static int64_t input_ts_offset = 0; +static int file_overwrite = 0; +static char *str_title = NULL; +static char *str_author = NULL; +static char *str_copyright = NULL; +static char *str_comment = NULL; +static int do_benchmark = 0; +static int do_hex_dump = 0; +static int do_pkt_dump = 0; +static int do_psnr = 0; +static int do_vstats = 0; +static int do_pass = 0; +static char *pass_logfilename = NULL; +static int audio_stream_copy = 0; +static int video_stream_copy = 0; +static int subtitle_stream_copy = 0; +static int video_sync_method= 1; +static int audio_sync_method= 0; +static int copy_ts= 0; +static int opt_shortest = 0; // +static int video_global_header = 0; + +static int rate_emu = 0; + +#ifdef CONFIG_BKTR +static char *video_grab_format = "bktr"; +#else +#ifdef CONFIG_VIDEO4LINUX2 +static char *video_grab_format = "video4linux2"; +#else +static char *video_grab_format = "video4linux"; +#endif +#endif +static char *video_device = NULL; +static char *grab_device = NULL; +static int video_channel = 0; +static char *video_standard = "ntsc"; + +static char *audio_grab_format = "audio_device"; +static char *audio_device = NULL; +static int audio_volume = 256; + +static int using_stdin = 0; +static int using_vhook = 0; +static int verbose = 1; +static int thread_count= 1; +static int q_pressed = 0; +static int me_range = 0; +static int64_t video_size = 0; +static int64_t audio_size = 0; +static int64_t extra_size = 0; +static int nb_frames_dup = 0; +static int nb_frames_drop = 0; +static int input_sync; +static int limit_filesize = 0; // + +static int pgmyuv_compatibility_hack=0; +static int dts_delta_threshold = 10; + +const char **opt_names=NULL; +int opt_name_count=0; +AVCodecContext *avctx_opts; + + +#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass" + +struct AVInputStream; + +typedef struct AVOutputStream { + int file_index; /* file index */ + int index; /* stream index in the output file */ + int source_index; /* AVInputStream index */ + AVStream *st; /* stream in the output file */ + int encoding_needed; /* true if encoding needed for this stream */ + int frame_number; + /* input pts and corresponding output pts + for A/V sync */ + //double sync_ipts; /* dts from the AVPacket of the demuxer in second units */ + struct AVInputStream *sync_ist; /* input stream to sync against */ + int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ //FIXME look at frame_number + /* video only */ + int video_resample; + AVFrame pict_tmp; /* temporary image for resampling */ + ImgReSampleContext *img_resample_ctx; /* for image resampling */ + + int video_crop; + int topBand; /* cropping area sizes */ + int leftBand; + + int video_pad; + int padtop; /* padding area sizes */ + int padbottom; + int padleft; + int padright; + + /* audio only */ + int audio_resample; + ReSampleContext *resample; /* for audio resampling */ + FifoBuffer fifo; /* for compression: one audio fifo per codec */ + FILE *logfile; +} AVOutputStream; + +typedef struct AVInputStream { + int file_index; + int index; + AVStream *st; + int discard; /* true if stream data should be discarded */ + int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */ + int64_t sample_index; /* current sample */ + + int64_t start; /* time when read started */ + unsigned long frame; /* current frame */ + int64_t next_pts; /* synthetic pts for cases where pkt.pts + is not defined */ + int64_t pts; /* current pts */ + int is_start; /* is 1 at the start and after a discontinuity */ +} AVInputStream; + +typedef struct AVInputFile { + int eof_reached; /* true if eof reached */ + int ist_index; /* index of first stream in ist_table */ + int buffer_size; /* current total buffer size */ + int buffer_size_max; /* buffer size at which we consider we can stop + buffering */ + int nb_streams; /* nb streams we are aware of */ +} AVInputFile; + +#ifndef CONFIG_WIN32 + +/* init terminal so that we can grab keys */ +static struct termios oldtty; + +static void term_exit(void) +{ + tcsetattr (0, TCSANOW, &oldtty); +} + +static volatile sig_atomic_t received_sigterm = 0; + +static void +sigterm_handler(int sig) +{ + received_sigterm = sig; + term_exit(); +} + +static void term_init(void) +{ + struct termios tty; + + tcgetattr (0, &tty); + oldtty = tty; + + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + tty.c_oflag |= OPOST; + tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); + tty.c_cflag &= ~(CSIZE|PARENB); + tty.c_cflag |= CS8; + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + + tcsetattr (0, TCSANOW, &tty); + + signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */ + signal(SIGQUIT, sigterm_handler); /* Quit (POSIX). */ + signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */ + /* + register a function to be called at normal program termination + */ + atexit(term_exit); +#ifdef CONFIG_BEOS_NETSERVER + fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK); +#endif +} + +/* read a key without blocking */ +static int read_key(void) +{ + int n = 1; + unsigned char ch; +#ifndef CONFIG_BEOS_NETSERVER + struct timeval tv; + fd_set rfds; + + FD_ZERO(&rfds); + FD_SET(0, &rfds); + tv.tv_sec = 0; + tv.tv_usec = 0; + n = select(1, &rfds, NULL, NULL, &tv); +#endif + if (n > 0) { + n = read(0, &ch, 1); + if (n == 1) + return ch; + + return n; + } + return -1; +} + +static int decode_interrupt_cb(void) +{ + return q_pressed || (q_pressed = read_key() == 'q'); +} + +#else + +static volatile int received_sigterm = 0; + +/* no interactive support */ +static void term_exit(void) +{ +} + +static void term_init(void) +{ +} + +static int read_key(void) +{ + return 0; +} + +#endif + +static int read_ffserver_streams(AVFormatContext *s, const char *filename) +{ + int i, err; + AVFormatContext *ic; + + err = av_open_input_file(&ic, filename, NULL, FFM_PACKET_SIZE, NULL); + if (err < 0) + return err; + /* copy stream format */ + s->nb_streams = ic->nb_streams; + for(i=0;inb_streams;i++) { + AVStream *st; + + // FIXME: a more elegant solution is needed + st = av_mallocz(sizeof(AVStream)); + memcpy(st, ic->streams[i], sizeof(AVStream)); + st->codec = avcodec_alloc_context(); + memcpy(st->codec, ic->streams[i]->codec, sizeof(AVCodecContext)); + s->streams[i] = st; + } + + av_close_input_file(ic); + return 0; +} + +static double +get_sync_ipts(const AVOutputStream *ost) +{ + const AVInputStream *ist = ost->sync_ist; + return (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/AV_TIME_BASE; +} + +#define MAX_AUDIO_PACKET_SIZE (128 * 1024) + +static void do_audio_out(AVFormatContext *s, + AVOutputStream *ost, + AVInputStream *ist, + unsigned char *buf, int size) +{ + uint8_t *buftmp; + static uint8_t *audio_buf = NULL; + static uint8_t *audio_out = NULL; + const int audio_out_size= 4*MAX_AUDIO_PACKET_SIZE; + + int size_out, frame_bytes, ret; + AVCodecContext *enc= ost->st->codec; + + /* SC: dynamic allocation of buffers */ + if (!audio_buf) + audio_buf = av_malloc(2*MAX_AUDIO_PACKET_SIZE); + if (!audio_out) + audio_out = av_malloc(audio_out_size); + if (!audio_buf || !audio_out) + return; /* Should signal an error ! */ + + if(audio_sync_method){ + double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts + - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2); + double idelta= delta*ist->st->codec->sample_rate / enc->sample_rate; + int byte_delta= ((int)idelta)*2*ist->st->codec->channels; + + //FIXME resample delay + if(fabs(delta) > 50){ + if(ist->is_start){ + if(byte_delta < 0){ + byte_delta= FFMAX(byte_delta, -size); + size += byte_delta; + buf -= byte_delta; + if(verbose > 2) + fprintf(stderr, "discarding %d audio samples\n", (int)-delta); + if(!size) + return; + ist->is_start=0; + }else{ + static uint8_t *input_tmp= NULL; + input_tmp= av_realloc(input_tmp, byte_delta + size); + + if(byte_delta + size <= MAX_AUDIO_PACKET_SIZE) + ist->is_start=0; + else + byte_delta= MAX_AUDIO_PACKET_SIZE - size; + + memset(input_tmp, 0, byte_delta); + memcpy(input_tmp + byte_delta, buf, size); + buf= input_tmp; + size += byte_delta; + if(verbose > 2) + fprintf(stderr, "adding %d audio samples of silence\n", (int)delta); + } + }else if(audio_sync_method>1){ + int comp= clip(delta, -audio_sync_method, audio_sync_method); + assert(ost->audio_resample); + if(verbose > 2) + fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate); +// fprintf(stderr, "drift:%f len:%d opts:%lld ipts:%lld fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2)); + av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate); + } + } + }else + ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate) + - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2); //FIXME wrong + + if (ost->audio_resample) { + buftmp = audio_buf; + size_out = audio_resample(ost->resample, + (short *)buftmp, (short *)buf, + size / (ist->st->codec->channels * 2)); + size_out = size_out * enc->channels * 2; + } else { + buftmp = buf; + size_out = size; + } + + /* now encode as many frames as possible */ + if (enc->frame_size > 1) { + /* output resampled raw samples */ + fifo_write(&ost->fifo, buftmp, size_out, + &ost->fifo.wptr); + + frame_bytes = enc->frame_size * 2 * enc->channels; + + while (fifo_read(&ost->fifo, audio_buf, frame_bytes, + &ost->fifo.rptr) == 0) { + AVPacket pkt; + av_init_packet(&pkt); + + ret = avcodec_encode_audio(enc, audio_out, audio_out_size, + (short *)audio_buf); + audio_size += ret; + pkt.stream_index= ost->index; + pkt.data= audio_out; + pkt.size= ret; + if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); + pkt.flags |= PKT_FLAG_KEY; + av_interleaved_write_frame(s, &pkt); + + ost->sync_opts += enc->frame_size; + } + } else { + AVPacket pkt; + av_init_packet(&pkt); + + ost->sync_opts += size_out / (2 * enc->channels); + + /* output a pcm frame */ + /* XXX: change encoding codec API to avoid this ? */ + switch(enc->codec->id) { + case CODEC_ID_PCM_S32LE: + case CODEC_ID_PCM_S32BE: + case CODEC_ID_PCM_U32LE: + case CODEC_ID_PCM_U32BE: + size_out = size_out << 1; + break; + case CODEC_ID_PCM_S24LE: + case CODEC_ID_PCM_S24BE: + case CODEC_ID_PCM_U24LE: + case CODEC_ID_PCM_U24BE: + case CODEC_ID_PCM_S24DAUD: + size_out = size_out / 2 * 3; + break; + case CODEC_ID_PCM_S16LE: + case CODEC_ID_PCM_S16BE: + case CODEC_ID_PCM_U16LE: + case CODEC_ID_PCM_U16BE: + break; + default: + size_out = size_out >> 1; + break; + } + ret = avcodec_encode_audio(enc, audio_out, size_out, + (short *)buftmp); + audio_size += ret; + pkt.stream_index= ost->index; + pkt.data= audio_out; + pkt.size= ret; + if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); + pkt.flags |= PKT_FLAG_KEY; + av_interleaved_write_frame(s, &pkt); + } +} + +static void pre_process_video_frame(AVInputStream *ist, AVPicture *picture, void **bufp) +{ + AVCodecContext *dec; + AVPicture *picture2; + AVPicture picture_tmp; + uint8_t *buf = 0; + + dec = ist->st->codec; + + /* deinterlace : must be done before any resize */ + if (do_deinterlace || using_vhook) { + int size; + + /* create temporary picture */ + size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height); + buf = av_malloc(size); + if (!buf) + return; + + picture2 = &picture_tmp; + avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height); + + if (do_deinterlace){ + if(avpicture_deinterlace(picture2, picture, + dec->pix_fmt, dec->width, dec->height) < 0) { + /* if error, do not deinterlace */ + av_free(buf); + buf = NULL; + picture2 = picture; + } + } else { + img_copy(picture2, picture, dec->pix_fmt, dec->width, dec->height); + } + } else { + picture2 = picture; + } + + frame_hook_process(picture2, dec->pix_fmt, dec->width, dec->height); + + if (picture != picture2) + *picture = *picture2; + *bufp = buf; +} + +/* we begin to correct av delay at this threshold */ +#define AV_DELAY_MAX 0.100 + +static void do_subtitle_out(AVFormatContext *s, + AVOutputStream *ost, + AVInputStream *ist, + AVSubtitle *sub, + int64_t pts) +{ + static uint8_t *subtitle_out = NULL; + int subtitle_out_max_size = 65536; + int subtitle_out_size, nb, i; + AVCodecContext *enc; + AVPacket pkt; + + if (pts == AV_NOPTS_VALUE) { + fprintf(stderr, "Subtitle packets must have a pts\n"); + return; + } + + enc = ost->st->codec; + + if (!subtitle_out) { + subtitle_out = av_malloc(subtitle_out_max_size); + } + + /* Note: DVB subtitle need one packet to draw them and one other + packet to clear them */ + /* XXX: signal it in the codec context ? */ + if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) + nb = 2; + else + nb = 1; + + for(i = 0; i < nb; i++) { + subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out, + subtitle_out_max_size, sub); + + av_init_packet(&pkt); + pkt.stream_index = ost->index; + pkt.data = subtitle_out; + pkt.size = subtitle_out_size; + pkt.pts = av_rescale_q(av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); + if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) { + /* XXX: the pts correction is handled here. Maybe handling + it in the codec would be better */ + if (i == 0) + pkt.pts += 90 * sub->start_display_time; + else + pkt.pts += 90 * sub->end_display_time; + } + av_interleaved_write_frame(s, &pkt); + } +} + +static int bit_buffer_size= 1024*256; +static uint8_t *bit_buffer= NULL; + +static void do_video_out(AVFormatContext *s, + AVOutputStream *ost, + AVInputStream *ist, + AVFrame *in_picture, + int *frame_size) +{ + int nb_frames, i, ret; + AVFrame *final_picture, *formatted_picture, *resampling_dst, *padding_src; + AVFrame picture_format_temp, picture_crop_temp, picture_pad_temp; + uint8_t *buf = NULL, *buf1 = NULL; + AVCodecContext *enc, *dec; + enum PixelFormat target_pixfmt; + + avcodec_get_frame_defaults(&picture_format_temp); + avcodec_get_frame_defaults(&picture_crop_temp); + avcodec_get_frame_defaults(&picture_pad_temp); + + enc = ost->st->codec; + dec = ist->st->codec; + + /* by default, we output a single frame */ + nb_frames = 1; + + *frame_size = 0; + + if(video_sync_method){ + double vdelta; + vdelta = get_sync_ipts(ost) / av_q2d(enc->time_base) - ost->sync_opts; + //FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c + if (vdelta < -1.1) + nb_frames = 0; + else if (vdelta > 1.1) + nb_frames = lrintf(vdelta); +//fprintf(stderr, "vdelta:%f, ost->sync_opts:%lld, ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, ost->sync_ipts, nb_frames); + if (nb_frames == 0){ + ++nb_frames_drop; + if (verbose>2) + fprintf(stderr, "*** drop!\n"); + }else if (nb_frames > 1) { + nb_frames_dup += nb_frames; + if (verbose>2) + fprintf(stderr, "*** %d dup!\n", nb_frames-1); + } + }else + ost->sync_opts= lrintf(get_sync_ipts(ost) / av_q2d(enc->time_base)); + + nb_frames= FFMIN(nb_frames, max_frames[CODEC_TYPE_VIDEO] - ost->frame_number); + if (nb_frames <= 0) + return; + + /* convert pixel format if needed */ + target_pixfmt = ost->video_resample ? PIX_FMT_YUV420P : enc->pix_fmt; + if (dec->pix_fmt != target_pixfmt) { + int size; + + /* create temporary picture */ + size = avpicture_get_size(target_pixfmt, dec->width, dec->height); + buf = av_malloc(size); + if (!buf) + return; + formatted_picture = &picture_format_temp; + avpicture_fill((AVPicture*)formatted_picture, buf, target_pixfmt, dec->width, dec->height); + + if (img_convert((AVPicture*)formatted_picture, target_pixfmt, + (AVPicture *)in_picture, dec->pix_fmt, + dec->width, dec->height) < 0) { + + if (verbose >= 0) + fprintf(stderr, "pixel format conversion not handled\n"); + + goto the_end; + } + } else { + formatted_picture = in_picture; + } + + if (ost->video_crop) { + if (img_crop((AVPicture *)&picture_crop_temp, (AVPicture *)formatted_picture, target_pixfmt, ost->topBand, ost->leftBand) < 0) { + av_log(NULL, AV_LOG_ERROR, "error cropping picture\n"); + goto the_end; + } + formatted_picture = &picture_crop_temp; + } + + final_picture = formatted_picture; + padding_src = formatted_picture; + resampling_dst = &ost->pict_tmp; + if (ost->video_pad) { + final_picture = &ost->pict_tmp; + if (ost->video_resample) { + if (img_crop((AVPicture *)&picture_pad_temp, (AVPicture *)final_picture, target_pixfmt, ost->padtop, ost->padleft) < 0) { + av_log(NULL, AV_LOG_ERROR, "error padding picture\n"); + goto the_end; + } + resampling_dst = &picture_pad_temp; + } + } + + /* XXX: resampling could be done before raw format conversion in + some cases to go faster */ + /* XXX: only works for YUV420P */ + if (ost->video_resample) { + padding_src = NULL; + final_picture = &ost->pict_tmp; + img_resample(ost->img_resample_ctx, (AVPicture *)resampling_dst, (AVPicture*)formatted_picture); + } + + if (enc->pix_fmt != target_pixfmt) { + int size; + + av_free(buf); + /* create temporary picture */ + size = avpicture_get_size(enc->pix_fmt, enc->width, enc->height); + buf = av_malloc(size); + if (!buf) + return; + final_picture = &picture_format_temp; + avpicture_fill((AVPicture*)final_picture, buf, enc->pix_fmt, enc->width, enc->height); + + if (img_convert((AVPicture*)final_picture, enc->pix_fmt, + (AVPicture*)&ost->pict_tmp, target_pixfmt, + enc->width, enc->height) < 0) { + + if (verbose >= 0) + fprintf(stderr, "pixel format conversion not handled\n"); + + goto the_end; + } + } + + if (ost->video_pad) { + img_pad((AVPicture*)final_picture, (AVPicture *)padding_src, + enc->height, enc->width, enc->pix_fmt, + ost->padtop, ost->padbottom, ost->padleft, ost->padright, padcolor); + } + + /* duplicates frame if needed */ + for(i=0;iindex; + + if (s->oformat->flags & AVFMT_RAWPICTURE) { + /* raw pictures are written as AVPicture structure to + avoid any copies. We support temorarily the older + method. */ + AVFrame* old_frame = enc->coded_frame; + enc->coded_frame = dec->coded_frame; //FIXME/XXX remove this hack + pkt.data= (uint8_t *)final_picture; + pkt.size= sizeof(AVPicture); + if(dec->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); + if(dec->coded_frame && dec->coded_frame->key_frame) + pkt.flags |= PKT_FLAG_KEY; + + av_interleaved_write_frame(s, &pkt); + enc->coded_frame = old_frame; + } else { + AVFrame big_picture; + + big_picture= *final_picture; + /* better than nothing: use input picture interlaced + settings */ + big_picture.interlaced_frame = in_picture->interlaced_frame; + if(avctx_opts->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)){ + if(top_field_first == -1) + big_picture.top_field_first = in_picture->top_field_first; + else + big_picture.top_field_first = top_field_first; + } + + /* handles sameq here. This is not correct because it may + not be a global option */ + if (same_quality) { + big_picture.quality = ist->st->quality; + }else + big_picture.quality = ost->st->quality; + if(!me_threshold) + big_picture.pict_type = 0; +// big_picture.pts = AV_NOPTS_VALUE; + big_picture.pts= ost->sync_opts; +// big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->time_base.num, enc->time_base.den); +//av_log(NULL, AV_LOG_DEBUG, "%lld -> encoder\n", ost->sync_opts); + ret = avcodec_encode_video(enc, + bit_buffer, bit_buffer_size, + &big_picture); + //enc->frame_number = enc->real_pict_num; + if(ret>0){ + pkt.data= bit_buffer; + pkt.size= ret; + if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); +/*av_log(NULL, AV_LOG_DEBUG, "encoder -> %lld/%lld\n", + pkt.pts != AV_NOPTS_VALUE ? av_rescale(pkt.pts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1, + pkt.dts != AV_NOPTS_VALUE ? av_rescale(pkt.dts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1);*/ + + if(enc->coded_frame && enc->coded_frame->key_frame) + pkt.flags |= PKT_FLAG_KEY; + av_interleaved_write_frame(s, &pkt); + *frame_size = ret; + //fprintf(stderr,"\nFrame: %3d %3d size: %5d type: %d", + // enc->frame_number-1, enc->real_pict_num, ret, + // enc->pict_type); + /* if two pass, output log */ + if (ost->logfile && enc->stats_out) { + fprintf(ost->logfile, "%s", enc->stats_out); + } + } + } + ost->sync_opts++; + ost->frame_number++; + } + the_end: + av_free(buf); + av_free(buf1); +} + +static double psnr(double d){ + if(d==0) return INFINITY; + return -10.0*log(d)/log(10.0); +} + +static void do_video_stats(AVFormatContext *os, AVOutputStream *ost, + int frame_size) +{ + static FILE *fvstats=NULL; + char filename[40]; + time_t today2; + struct tm *today; + AVCodecContext *enc; + int frame_number; + int64_t ti; + double ti1, bitrate, avg_bitrate; + + if (!fvstats) { + today2 = time(NULL); + today = localtime(&today2); + snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, + today->tm_min, + today->tm_sec); + fvstats = fopen(filename,"w"); + if (!fvstats) { + perror("fopen"); + exit(1); + } + } + + ti = MAXINT64; + enc = ost->st->codec; + if (enc->codec_type == CODEC_TYPE_VIDEO) { + frame_number = ost->frame_number; + fprintf(fvstats, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality/(float)FF_QP2LAMBDA); + if (enc->flags&CODEC_FLAG_PSNR) + fprintf(fvstats, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0]/(enc->width*enc->height*255.0*255.0))); + + fprintf(fvstats,"f_size= %6d ", frame_size); + /* compute pts value */ + ti1 = ost->sync_opts * av_q2d(enc->time_base); + if (ti1 < 0.01) + ti1 = 0.01; + + bitrate = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0; + avg_bitrate = (double)(video_size * 8) / ti1 / 1000.0; + fprintf(fvstats, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", + (double)video_size / 1024, ti1, bitrate, avg_bitrate); + fprintf(fvstats,"type= %c\n", av_get_pict_type_char(enc->coded_frame->pict_type)); + } +} + +static void print_report(AVFormatContext **output_files, + AVOutputStream **ost_table, int nb_ostreams, + int is_last_report) +{ + char buf[1024]; + AVOutputStream *ost; + AVFormatContext *oc, *os; + int64_t total_size; + AVCodecContext *enc; + int frame_number, vid, i; + double bitrate, ti1, pts; + static int64_t last_time = -1; + static int qp_histogram[52]; + + if (!is_last_report) { + int64_t cur_time; + /* display the report every 0.5 seconds */ + cur_time = av_gettime(); + if (last_time == -1) { + last_time = cur_time; + return; + } + if ((cur_time - last_time) < 500000) + return; + last_time = cur_time; + } + + + oc = output_files[0]; + + total_size = url_ftell(&oc->pb); + + buf[0] = '\0'; + ti1 = 1e10; + vid = 0; + for(i=0;ifile_index]; + enc = ost->st->codec; + if (vid && enc->codec_type == CODEC_TYPE_VIDEO) { + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", + enc->coded_frame->quality/(float)FF_QP2LAMBDA); + } + if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) { + frame_number = ost->frame_number; + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d q=%3.1f ", + frame_number, enc->coded_frame ? enc->coded_frame->quality/(float)FF_QP2LAMBDA : -1); + if(is_last_report) + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L"); + if(qp_hist && enc->coded_frame){ + int j; + int qp= lrintf(enc->coded_frame->quality/(float)FF_QP2LAMBDA); + if(qp>=0 && qpflags&CODEC_FLAG_PSNR){ + int j; + double error, error_sum=0; + double scale, scale_sum=0; + char type[3]= {'Y','U','V'}; + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR="); + for(j=0; j<3; j++){ + if(is_last_report){ + error= enc->error[j]; + scale= enc->width*enc->height*255.0*255.0*frame_number; + }else{ + error= enc->coded_frame->error[j]; + scale= enc->width*enc->height*255.0*255.0; + } + if(j) scale/=4; + error_sum += error; + scale_sum += scale; + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], psnr(error/scale)); + } + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum/scale_sum)); + } + vid = 1; + } + /* compute min output value */ + pts = (double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den; + if ((pts < ti1) && (pts > 0)) + ti1 = pts; + } + if (ti1 < 0.01) + ti1 = 0.01; + + if (verbose || is_last_report) { + bitrate = (double)(total_size * 8) / ti1 / 1000.0; + + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), + "size=%8.0fkB time=%0.1f bitrate=%6.1fkbits/s", + (double)total_size / 1024, ti1, bitrate); + + if (verbose > 1) + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d", + nb_frames_dup, nb_frames_drop); + + if (verbose >= 0) + fprintf(stderr, "%s \r", buf); + + fflush(stderr); + } + + if (is_last_report && verbose >= 0){ + int64_t raw= audio_size + video_size + extra_size; + fprintf(stderr, "\n"); + fprintf(stderr, "video:%1.0fkB audio:%1.0fkB global headers:%1.0fkB muxing overhead %f%%\n", + video_size/1024.0, + audio_size/1024.0, + extra_size/1024.0, + 100.0*(total_size - raw)/raw + ); + } +} + +/* pkt = NULL means EOF (needed to flush decoder buffers) */ +static int output_packet(AVInputStream *ist, int ist_index, + AVOutputStream **ost_table, int nb_ostreams, + const AVPacket *pkt) +{ + AVFormatContext *os; + AVOutputStream *ost; + uint8_t *ptr; + int len, ret, i; + uint8_t *data_buf; + int data_size, got_picture; + AVFrame picture; + void *buffer_to_free; + static unsigned int samples_size= 0; + static short *samples= NULL; + AVSubtitle subtitle, *subtitle_to_free; + int got_subtitle; + + if(!pkt){ + ist->pts= ist->next_pts; // needed for last packet if vsync=0 + } else if (pkt->dts != AV_NOPTS_VALUE) { //FIXME seems redundant, as libavformat does this too + ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); + } else { +// assert(ist->pts == ist->next_pts); + } + + if (pkt == NULL) { + /* EOF handling */ + ptr = NULL; + len = 0; + goto handle_eof; + } + + len = pkt->size; + ptr = pkt->data; + while (len > 0) { + handle_eof: + /* decode the packet if needed */ + data_buf = NULL; /* fail safe */ + data_size = 0; + subtitle_to_free = NULL; + if (ist->decoding_needed) { + switch(ist->st->codec->codec_type) { + case CODEC_TYPE_AUDIO:{ + if(pkt) + samples= av_fast_realloc(samples, &samples_size, FFMAX(pkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE)); + /* XXX: could avoid copy if PCM 16 bits with same + endianness as CPU */ + ret = avcodec_decode_audio(ist->st->codec, samples, &data_size, + ptr, len); + if (ret < 0) + goto fail_decode; + ptr += ret; + len -= ret; + /* Some bug in mpeg audio decoder gives */ + /* data_size < 0, it seems they are overflows */ + if (data_size <= 0) { + /* no audio frame */ + continue; + } + data_buf = (uint8_t *)samples; + ist->next_pts += ((int64_t)AV_TIME_BASE/2 * data_size) / + (ist->st->codec->sample_rate * ist->st->codec->channels); + break;} + case CODEC_TYPE_VIDEO: + data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2; + /* XXX: allocate picture correctly */ + avcodec_get_frame_defaults(&picture); + + ret = avcodec_decode_video(ist->st->codec, + &picture, &got_picture, ptr, len); + ist->st->quality= picture.quality; + if (ret < 0) + goto fail_decode; + if (!got_picture) { + /* no picture yet */ + goto discard_packet; + } + if (ist->st->codec->time_base.num != 0) { + ist->next_pts += ((int64_t)AV_TIME_BASE * + ist->st->codec->time_base.num) / + ist->st->codec->time_base.den; + } + len = 0; + break; + case CODEC_TYPE_SUBTITLE: + ret = avcodec_decode_subtitle(ist->st->codec, + &subtitle, &got_subtitle, ptr, len); + if (ret < 0) + goto fail_decode; + if (!got_subtitle) { + goto discard_packet; + } + subtitle_to_free = &subtitle; + len = 0; + break; + default: + goto fail_decode; + } + } else { + switch(ist->st->codec->codec_type) { + case CODEC_TYPE_AUDIO: + ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) / + (ist->st->codec->sample_rate * ist->st->codec->channels); + break; + case CODEC_TYPE_VIDEO: + if (ist->st->codec->time_base.num != 0) { + ist->next_pts += ((int64_t)AV_TIME_BASE * + ist->st->codec->time_base.num) / + ist->st->codec->time_base.den; + } + break; + } + data_buf = ptr; + data_size = len; + ret = len; + len = 0; + } + + buffer_to_free = NULL; + if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) { + pre_process_video_frame(ist, (AVPicture *)&picture, + &buffer_to_free); + } + + // preprocess audio (volume) + if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) { + if (audio_volume != 256) { + short *volp; + volp = samples; + for(i=0;i<(data_size / sizeof(short));i++) { + int v = ((*volp) * audio_volume + 128) >> 8; + if (v < -32768) v = -32768; + if (v > 32767) v = 32767; + *volp++ = v; + } + } + } + + /* frame rate emulation */ + if (ist->st->codec->rate_emu) { + int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec->time_base.num, 1000000, ist->st->codec->time_base.den); + int64_t now = av_gettime() - ist->start; + if (pts > now) + usleep(pts - now); + + ist->frame++; + } + +#if 0 + /* mpeg PTS deordering : if it is a P or I frame, the PTS + is the one of the next displayed one */ + /* XXX: add mpeg4 too ? */ + if (ist->st->codec->codec_id == CODEC_ID_MPEG1VIDEO) { + if (ist->st->codec->pict_type != B_TYPE) { + int64_t tmp; + tmp = ist->last_ip_pts; + ist->last_ip_pts = ist->frac_pts.val; + ist->frac_pts.val = tmp; + } + } +#endif + /* if output time reached then transcode raw format, + encode packets and output them */ + if (start_time == 0 || ist->pts >= start_time) + for(i=0;isource_index == ist_index) { + os = output_files[ost->file_index]; + +#if 0 + printf("%d: got pts=%0.3f %0.3f\n", i, + (double)pkt->pts / AV_TIME_BASE, + ((double)ist->pts / AV_TIME_BASE) - + ((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den)); +#endif + /* set the input output pts pairs */ + //ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE; + + if (ost->encoding_needed) { + switch(ost->st->codec->codec_type) { + case CODEC_TYPE_AUDIO: + do_audio_out(os, ost, ist, data_buf, data_size); + break; + case CODEC_TYPE_VIDEO: + do_video_out(os, ost, ist, &picture, &frame_size); + video_size += frame_size; + if (do_vstats && frame_size) + do_video_stats(os, ost, frame_size); + break; + case CODEC_TYPE_SUBTITLE: + do_subtitle_out(os, ost, ist, &subtitle, + pkt->pts); + break; + default: + av_abort(); + } + } else { + AVFrame avframe; //FIXME/XXX remove this + AVPacket opkt; + av_init_packet(&opkt); + + /* no reencoding needed : output the packet directly */ + /* force the input stream PTS */ + + avcodec_get_frame_defaults(&avframe); + ost->st->codec->coded_frame= &avframe; + avframe.key_frame = pkt->flags & PKT_FLAG_KEY; + + if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO) + audio_size += data_size; + else if (ost->st->codec->codec_type == CODEC_TYPE_VIDEO) { + video_size += data_size; + ost->sync_opts++; + } + + opkt.stream_index= ost->index; + if(pkt->pts != AV_NOPTS_VALUE) + opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); + else + opkt.pts= AV_NOPTS_VALUE; + + { + int64_t dts; + if (pkt->dts == AV_NOPTS_VALUE) + dts = ist->next_pts; + else + dts= av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); + opkt.dts= av_rescale_q(dts + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); + } + opkt.flags= pkt->flags; + if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY)) + opkt.destruct= av_destruct_packet; + av_interleaved_write_frame(os, &opkt); + ost->st->codec->frame_number++; + ost->frame_number++; + av_free_packet(&opkt); + } + } + } + av_free(buffer_to_free); + /* XXX: allocate the subtitles in the codec ? */ + if (subtitle_to_free) { + if (subtitle_to_free->rects != NULL) { + for (i = 0; i < subtitle_to_free->num_rects; i++) { + av_free(subtitle_to_free->rects[i].bitmap); + av_free(subtitle_to_free->rects[i].rgba_palette); + } + av_freep(&subtitle_to_free->rects); + } + subtitle_to_free->num_rects = 0; + subtitle_to_free = NULL; + } + } + discard_packet: + if (pkt == NULL) { + /* EOF handling */ + + for(i=0;isource_index == ist_index) { + AVCodecContext *enc= ost->st->codec; + os = output_files[ost->file_index]; + + if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO && enc->frame_size <=1) + continue; + if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE)) + continue; + + if (ost->encoding_needed) { + for(;;) { + AVPacket pkt; + av_init_packet(&pkt); + pkt.stream_index= ost->index; + + switch(ost->st->codec->codec_type) { + case CODEC_TYPE_AUDIO: + ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL); + audio_size += ret; + pkt.flags |= PKT_FLAG_KEY; + break; + case CODEC_TYPE_VIDEO: + ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); + video_size += ret; + if(enc->coded_frame && enc->coded_frame->key_frame) + pkt.flags |= PKT_FLAG_KEY; + if (ost->logfile && enc->stats_out) { + fprintf(ost->logfile, "%s", enc->stats_out); + } + break; + default: + ret=-1; + } + + if(ret<=0) + break; + pkt.data= bit_buffer; + pkt.size= ret; + if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); + av_interleaved_write_frame(os, &pkt); + } + } + } + } + } + + return 0; + fail_decode: + return -1; +} + + +/* + * The following code is the main loop of the file converter + */ +static int av_encode(AVFormatContext **output_files, + int nb_output_files, + AVFormatContext **input_files, + int nb_input_files, + AVStreamMap *stream_maps, int nb_stream_maps) +{ + int ret, i, j, k, n, nb_istreams = 0, nb_ostreams = 0; + AVFormatContext *is, *os; + AVCodecContext *codec, *icodec; + AVOutputStream *ost, **ost_table = NULL; + AVInputStream *ist, **ist_table = NULL; + AVInputFile *file_table; + AVFormatContext *stream_no_data; + int key; + + file_table= (AVInputFile*) av_mallocz(nb_input_files * sizeof(AVInputFile)); + if (!file_table) + goto fail; + + /* input stream init */ + j = 0; + for(i=0;inb_streams; + j += is->nb_streams; + } + nb_istreams = j; + + ist_table = av_mallocz(nb_istreams * sizeof(AVInputStream *)); + if (!ist_table) + goto fail; + + for(i=0;inb_streams;k++) { + ist = ist_table[j++]; + ist->st = is->streams[k]; + ist->file_index = i; + ist->index = k; + ist->discard = 1; /* the stream is discarded by default + (changed later) */ + + if (ist->st->codec->rate_emu) { + ist->start = av_gettime(); + ist->frame = 0; + } + } + } + + /* output stream init */ + nb_ostreams = 0; + for(i=0;inb_streams; + } + if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) { + fprintf(stderr, "Number of stream maps must match number of output streams\n"); + exit(1); + } + + /* Sanity check the mapping args -- do the input files & streams exist? */ + for(i=0;i nb_input_files - 1 || + si < 0 || si > file_table[fi].nb_streams - 1) { + fprintf(stderr,"Could not find input stream #%d.%d\n", fi, si); + exit(1); + } + fi = stream_maps[i].sync_file_index; + si = stream_maps[i].sync_stream_index; + if (fi < 0 || fi > nb_input_files - 1 || + si < 0 || si > file_table[fi].nb_streams - 1) { + fprintf(stderr,"Could not find sync stream #%d.%d\n", fi, si); + exit(1); + } + } + + ost_table = av_mallocz(sizeof(AVOutputStream *) * nb_ostreams); + if (!ost_table) + goto fail; + for(i=0;inb_streams;i++) { + int found; + ost = ost_table[n++]; + ost->file_index = k; + ost->index = i; + ost->st = os->streams[i]; + if (nb_stream_maps > 0) { + ost->source_index = file_table[stream_maps[n-1].file_index].ist_index + + stream_maps[n-1].stream_index; + + /* Sanity check that the stream types match */ + if (ist_table[ost->source_index]->st->codec->codec_type != ost->st->codec->codec_type) { + fprintf(stderr, "Codec type mismatch for mapping #%d.%d -> #%d.%d\n", + stream_maps[n-1].file_index, stream_maps[n-1].stream_index, + ost->file_index, ost->index); + exit(1); + } + + } else { + /* get corresponding input stream index : we select the first one with the right type */ + found = 0; + for(j=0;jdiscard && + ist->st->codec->codec_type == ost->st->codec->codec_type) { + ost->source_index = j; + found = 1; + break; + } + } + + if (!found) { + /* try again and reuse existing stream */ + for(j=0;jst->codec->codec_type == ost->st->codec->codec_type) { + ost->source_index = j; + found = 1; + } + } + if (!found) { + fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n", + ost->file_index, ost->index); + exit(1); + } + } + } + ist = ist_table[ost->source_index]; + ist->discard = 0; + ost->sync_ist = (nb_stream_maps > 0) ? + ist_table[file_table[stream_maps[n-1].sync_file_index].ist_index + + stream_maps[n-1].sync_stream_index] : ist; + } + } + + /* for each output stream, we compute the right encoding parameters */ + for(i=0;isource_index]; + + codec = ost->st->codec; + icodec = ist->st->codec; + + if (ost->st->stream_copy) { + /* if stream_copy is selected, no need to decode or encode */ + codec->codec_id = icodec->codec_id; + codec->codec_type = icodec->codec_type; + if(!codec->codec_tag) codec->codec_tag = icodec->codec_tag; + codec->bit_rate = icodec->bit_rate; + codec->extradata= icodec->extradata; + codec->extradata_size= icodec->extradata_size; + codec->time_base = icodec->time_base; + switch(codec->codec_type) { + case CODEC_TYPE_AUDIO: + codec->sample_rate = icodec->sample_rate; + codec->channels = icodec->channels; + codec->frame_size = icodec->frame_size; + codec->block_align= icodec->block_align; + break; + case CODEC_TYPE_VIDEO: + codec->pix_fmt = icodec->pix_fmt; + codec->width = icodec->width; + codec->height = icodec->height; + codec->has_b_frames = icodec->has_b_frames; + break; + case CODEC_TYPE_SUBTITLE: + break; + default: + av_abort(); + } + } else { + switch(codec->codec_type) { + case CODEC_TYPE_AUDIO: + if (fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE)) + goto fail; + + if (codec->channels == icodec->channels && + codec->sample_rate == icodec->sample_rate) { + ost->audio_resample = 0; + } else { + if (codec->channels != icodec->channels && + (icodec->codec_id == CODEC_ID_AC3 || + icodec->codec_id == CODEC_ID_DTS)) { + /* Special case for 5:1 AC3 and DTS input */ + /* and mono or stereo output */ + /* Request specific number of channels */ + icodec->channels = codec->channels; + if (codec->sample_rate == icodec->sample_rate) + ost->audio_resample = 0; + else { + ost->audio_resample = 1; + } + } else { + ost->audio_resample = 1; + } + } + if(audio_sync_method>1) + ost->audio_resample = 1; + + if(ost->audio_resample){ + ost->resample = audio_resample_init(codec->channels, icodec->channels, + codec->sample_rate, icodec->sample_rate); + if(!ost->resample){ + printf("Can't resample. Aborting.\n"); + av_abort(); + } + } + ist->decoding_needed = 1; + ost->encoding_needed = 1; + break; + case CODEC_TYPE_VIDEO: + ost->video_crop = ((frame_leftBand + frame_rightBand + frame_topBand + frame_bottomBand) != 0); + ost->video_pad = ((frame_padleft + frame_padright + frame_padtop + frame_padbottom) != 0); + ost->video_resample = ((codec->width != icodec->width - + (frame_leftBand + frame_rightBand) + + (frame_padleft + frame_padright)) || + (codec->height != icodec->height - + (frame_topBand + frame_bottomBand) + + (frame_padtop + frame_padbottom))); + if (ost->video_crop) { + ost->topBand = frame_topBand; + ost->leftBand = frame_leftBand; + } + if (ost->video_pad) { + ost->padtop = frame_padtop; + ost->padleft = frame_padleft; + ost->padbottom = frame_padbottom; + ost->padright = frame_padright; + if (!ost->video_resample) { + avcodec_get_frame_defaults(&ost->pict_tmp); + if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, codec->pix_fmt, + codec->width, codec->height ) ) + goto fail; + } + } + if (ost->video_resample) { + avcodec_get_frame_defaults(&ost->pict_tmp); + if( avpicture_alloc( (AVPicture*)&ost->pict_tmp, PIX_FMT_YUV420P, + codec->width, codec->height ) ) + goto fail; + + ost->img_resample_ctx = img_resample_init( + codec->width - (frame_padleft + frame_padright), + codec->height - (frame_padtop + frame_padbottom), + icodec->width - (frame_leftBand + frame_rightBand), + icodec->height - (frame_topBand + frame_bottomBand)); + + } + ost->encoding_needed = 1; + ist->decoding_needed = 1; + break; + case CODEC_TYPE_SUBTITLE: + ost->encoding_needed = 1; + ist->decoding_needed = 1; + break; + default: + av_abort(); + break; + } + /* two pass mode */ + if (ost->encoding_needed && + (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) { + char logfilename[1024]; + FILE *f; + int size; + char *logbuffer; + + snprintf(logfilename, sizeof(logfilename), "%s-%d.log", + pass_logfilename ? + pass_logfilename : DEFAULT_PASS_LOGFILENAME, i); + if (codec->flags & CODEC_FLAG_PASS1) { + f = fopen(logfilename, "w"); + if (!f) { + perror(logfilename); + exit(1); + } + ost->logfile = f; + } else { + /* read the log file */ + f = fopen(logfilename, "r"); + if (!f) { + perror(logfilename); + exit(1); + } + fseek(f, 0, SEEK_END); + size = ftell(f); + fseek(f, 0, SEEK_SET); + logbuffer = av_malloc(size + 1); + if (!logbuffer) { + fprintf(stderr, "Could not allocate log buffer\n"); + exit(1); + } + size = fread(logbuffer, 1, size, f); + fclose(f); + logbuffer[size] = '\0'; + codec->stats_in = logbuffer; + } + } + } + if(codec->codec_type == CODEC_TYPE_VIDEO){ + int size= codec->width * codec->height; + bit_buffer_size= FFMAX(bit_buffer_size, 4*size); + } + } + + if (!bit_buffer) + bit_buffer = av_malloc(bit_buffer_size); + if (!bit_buffer) + goto fail; + + /* dump the file output parameters - cannot be done before in case + of stream copy */ + for(i=0;ifilename, 1); + } + + /* dump the stream mapping */ + if (verbose >= 0) { + fprintf(stderr, "Stream mapping:\n"); + for(i=0;i #%d.%d", + ist_table[ost->source_index]->file_index, + ist_table[ost->source_index]->index, + ost->file_index, + ost->index); + if (ost->sync_ist != ist_table[ost->source_index]) + fprintf(stderr, " [sync #%d.%d]", + ost->sync_ist->file_index, + ost->sync_ist->index); + fprintf(stderr, "\n"); + } + } + + /* open each encoder */ + for(i=0;iencoding_needed) { + AVCodec *codec; + codec = avcodec_find_encoder(ost->st->codec->codec_id); + if (!codec) { + fprintf(stderr, "Unsupported codec for output stream #%d.%d\n", + ost->file_index, ost->index); + exit(1); + } + if (avcodec_open(ost->st->codec, codec) < 0) { + fprintf(stderr, "Error while opening codec for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height\n", + ost->file_index, ost->index); + exit(1); + } + extra_size += ost->st->codec->extradata_size; + } + } + + /* open each decoder */ + for(i=0;idecoding_needed) { + AVCodec *codec; + codec = avcodec_find_decoder(ist->st->codec->codec_id); + if (!codec) { + fprintf(stderr, "Unsupported codec (id=%d) for input stream #%d.%d\n", + ist->st->codec->codec_id, ist->file_index, ist->index); + exit(1); + } + if (avcodec_open(ist->st->codec, codec) < 0) { + fprintf(stderr, "Error while opening codec for input stream #%d.%d\n", + ist->file_index, ist->index); + exit(1); + } + //if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) + // ist->st->codec->flags |= CODEC_FLAG_REPEAT_FIELD; + } + } + + /* init pts */ + for(i=0;ifile_index]; + ist->pts = 0; + ist->next_pts = av_rescale_q(ist->st->start_time, ist->st->time_base, AV_TIME_BASE_Q); + if(ist->st->start_time == AV_NOPTS_VALUE) + ist->next_pts=0; + if(input_files_ts_offset[ist->file_index]) + ist->next_pts= AV_NOPTS_VALUE; + ist->is_start = 1; + } + + /* compute buffer size max (should use a complete heuristic) */ + for(i=0;i= nb_output_files ) { + fprintf(stderr, "Invalid output file index %d map_meta_data(%d,%d)\n", out_file_index, out_file_index, in_file_index); + ret = -EINVAL; + goto fail; + } + if ( in_file_index < 0 || in_file_index >= nb_input_files ) { + fprintf(stderr, "Invalid input file index %d map_meta_data(%d,%d)\n", in_file_index, out_file_index, in_file_index); + ret = -EINVAL; + goto fail; + } + + out_file = output_files[out_file_index]; + in_file = input_files[in_file_index]; + + strcpy(out_file->title, in_file->title); + strcpy(out_file->author, in_file->author); + strcpy(out_file->copyright, in_file->copyright); + strcpy(out_file->comment, in_file->comment); + strcpy(out_file->album, in_file->album); + out_file->year = in_file->year; + out_file->track = in_file->track; + strcpy(out_file->genre, in_file->genre); + } + + /* open files and write file headers */ + for(i=0;i= 0) { + fprintf(stderr, "Press [q] to stop encoding\n"); + url_set_interrupt_cb(decode_interrupt_cb); + } +#endif + term_init(); + + stream_no_data = 0; + key = -1; + + for(; received_sigterm == 0;) { + int file_index, ist_index; + AVPacket pkt; + double ipts_min; + double opts_min; + + redo: + ipts_min= 1e100; + opts_min= 1e100; + /* if 'q' pressed, exits */ + if (!using_stdin) { + if (q_pressed) + break; + /* read_key() returns 0 on EOF */ + key = read_key(); + if (key == 'q') + break; + } + + /* select the stream that we must read now by looking at the + smallest output pts */ + file_index = -1; + for(i=0;ifile_index]; + ist = ist_table[ost->source_index]; + if(ost->st->codec->codec_type == CODEC_TYPE_VIDEO) + opts = ost->sync_opts * av_q2d(ost->st->codec->time_base); + else + opts = ost->st->pts.val * av_q2d(ost->st->time_base); + ipts = (double)ist->pts; + if (!file_table[ist->file_index].eof_reached){ + if(ipts < ipts_min) { + ipts_min = ipts; + if(input_sync ) file_index = ist->file_index; + } + if(opts < opts_min) { + opts_min = opts; + if(!input_sync) file_index = ist->file_index; + } + } + if(ost->frame_number >= max_frames[ost->st->codec->codec_type]){ + file_index= -1; + break; + } + } + /* if none, if is finished */ + if (file_index < 0) { + break; + } + + /* finish if recording time exhausted */ + if (recording_time > 0 && opts_min >= (recording_time / 1000000.0)) + break; + + /* finish if limit size exhausted */ + if (limit_filesize != 0 && (limit_filesize * 1024) < url_ftell(&output_files[0]->pb)) + break; + + /* read a frame from it and output it in the fifo */ + is = input_files[file_index]; + if (av_read_frame(is, &pkt) < 0) { + file_table[file_index].eof_reached = 1; + if (opt_shortest) break; else continue; // + } + + if (!pkt.size) { + stream_no_data = is; + } else { + stream_no_data = 0; + } + if (do_pkt_dump) { + av_pkt_dump(stdout, &pkt, do_hex_dump); + } + /* the following test is needed in case new streams appear + dynamically in stream : we ignore them */ + if (pkt.stream_index >= file_table[file_index].nb_streams) + goto discard_packet; + ist_index = file_table[file_index].ist_index + pkt.stream_index; + ist = ist_table[ist_index]; + if (ist->discard) + goto discard_packet; + +// fprintf(stderr, "next:%lld dts:%lld off:%lld %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type); + if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE) { + int64_t delta= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q) - ist->next_pts; + if(ABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE && !copy_ts){ + input_files_ts_offset[ist->file_index]-= delta; + if (verbose > 2) + fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, input_files_ts_offset[ist->file_index]); + for(i=0; inext_pts += delta; + ist_table[index]->is_start=1; + } + } + } + + //fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size); + if (output_packet(ist, ist_index, ost_table, nb_ostreams, &pkt) < 0) { + + if (verbose >= 0) + fprintf(stderr, "Error while decoding stream #%d.%d\n", + ist->file_index, ist->index); + + av_free_packet(&pkt); + goto redo; + } + + discard_packet: + av_free_packet(&pkt); + + /* dump report by using the output first video and audio streams */ + print_report(output_files, ost_table, nb_ostreams, 0); + } + + /* at the end of stream, we must flush the decoder buffers */ + for(i=0;idecoding_needed) { + output_packet(ist, i, ost_table, nb_ostreams, NULL); + } + } + + term_exit(); + + /* write the trailer if needed and close file */ + for(i=0;iencoding_needed) { + av_freep(&ost->st->codec->stats_in); + avcodec_close(ost->st->codec); + } + } + + /* close each decoder */ + for(i=0;idecoding_needed) { + avcodec_close(ist->st->codec); + } + } + + /* finished ! */ + + ret = 0; + fail1: + av_freep(&bit_buffer); + av_free(file_table); + + if (ist_table) { + for(i=0;ilogfile) { + fclose(ost->logfile); + ost->logfile = NULL; + } + fifo_free(&ost->fifo); /* works even if fifo is not + initialized but set to zero */ + av_free(ost->pict_tmp.data[0]); + if (ost->video_resample) + img_resample_close(ost->img_resample_ctx); + if (ost->audio_resample) + audio_resample_close(ost->resample); + av_free(ost); + } + } + av_free(ost_table); + } + return ret; + fail: + ret = -ENOMEM; + goto fail1; +} + +#if 0 +int file_read(const char *filename) +{ + URLContext *h; + unsigned char buffer[1024]; + int len, i; + + if (url_open(&h, filename, O_RDONLY) < 0) { + printf("could not open '%s'\n", filename); + return -1; + } + for(;;) { + len = url_read(h, buffer, sizeof(buffer)); + if (len <= 0) + break; + for(i=0;inext) { + if (!strcmp(arg, f->name)) + break; + } + if (!f) { + fprintf(stderr, "Unknown image format: '%s'\n", arg); + exit(1); + } + image_format = f; +} + +static void opt_format(const char *arg) +{ + /* compatibility stuff for pgmyuv */ + if (!strcmp(arg, "pgmyuv")) { + pgmyuv_compatibility_hack=1; +// opt_image_format(arg); + arg = "image2"; + } + + file_iformat = av_find_input_format(arg); + file_oformat = guess_format(arg, NULL, NULL); + if (!file_iformat && !file_oformat) { + fprintf(stderr, "Unknown input or output format: %s\n", arg); + exit(1); + } +} + +static void opt_video_bitrate(const char *arg) +{ + video_bit_rate = atoi(arg) * 1000; +} + +static void opt_video_bitrate_tolerance(const char *arg) +{ + video_bit_rate_tolerance = atoi(arg) * 1000; +} + +static void opt_video_bitrate_max(const char *arg) +{ + video_rc_max_rate = atoi(arg) * 1000; +} + +static void opt_video_bitrate_min(const char *arg) +{ + video_rc_min_rate = atoi(arg) * 1000; +} + +static void opt_video_buffer_size(const char *arg) +{ + video_rc_buffer_size = atoi(arg) * 8*1024; +} + +static void opt_video_rc_eq(char *arg) +{ + video_rc_eq = arg; +} + +static void opt_video_rc_override_string(char *arg) +{ + video_rc_override_string = arg; +} + + +static void opt_workaround_bugs(const char *arg) +{ + workaround_bugs = atoi(arg); +} + +static void opt_me_threshold(const char *arg) +{ + me_threshold = atoi(arg); +} + +static void opt_mb_threshold(const char *arg) +{ + mb_threshold = atoi(arg); +} + +static void opt_verbose(const char *arg) +{ + verbose = atoi(arg); + av_log_set_level(atoi(arg)); +} + +static void opt_frame_rate(const char *arg) +{ + if (parse_frame_rate(&frame_rate, &frame_rate_base, arg) < 0) { + fprintf(stderr, "Incorrect frame rate\n"); + exit(1); + } +} + +static void opt_frame_crop_top(const char *arg) +{ + frame_topBand = atoi(arg); + if (frame_topBand < 0) { + fprintf(stderr, "Incorrect top crop size\n"); + exit(1); + } + if ((frame_topBand % 2) != 0) { + fprintf(stderr, "Top crop size must be a multiple of 2\n"); + exit(1); + } + if ((frame_topBand) >= frame_height){ + fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n"); + exit(1); + } + frame_height -= frame_topBand; +} + +static void opt_frame_crop_bottom(const char *arg) +{ + frame_bottomBand = atoi(arg); + if (frame_bottomBand < 0) { + fprintf(stderr, "Incorrect bottom crop size\n"); + exit(1); + } + if ((frame_bottomBand % 2) != 0) { + fprintf(stderr, "Bottom crop size must be a multiple of 2\n"); + exit(1); + } + if ((frame_bottomBand) >= frame_height){ + fprintf(stderr, "Vertical crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n"); + exit(1); + } + frame_height -= frame_bottomBand; +} + +static void opt_frame_crop_left(const char *arg) +{ + frame_leftBand = atoi(arg); + if (frame_leftBand < 0) { + fprintf(stderr, "Incorrect left crop size\n"); + exit(1); + } + if ((frame_leftBand % 2) != 0) { + fprintf(stderr, "Left crop size must be a multiple of 2\n"); + exit(1); + } + if ((frame_leftBand) >= frame_width){ + fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n"); + exit(1); + } + frame_width -= frame_leftBand; +} + +static void opt_frame_crop_right(const char *arg) +{ + frame_rightBand = atoi(arg); + if (frame_rightBand < 0) { + fprintf(stderr, "Incorrect right crop size\n"); + exit(1); + } + if ((frame_rightBand % 2) != 0) { + fprintf(stderr, "Right crop size must be a multiple of 2\n"); + exit(1); + } + if ((frame_rightBand) >= frame_width){ + fprintf(stderr, "Horizontal crop dimensions are outside the range of the original image.\nRemember to crop first and scale second.\n"); + exit(1); + } + frame_width -= frame_rightBand; +} + +static void opt_frame_size(const char *arg) +{ + if (parse_image_size(&frame_width, &frame_height, arg) < 0) { + fprintf(stderr, "Incorrect frame size\n"); + exit(1); + } + if ((frame_width % 2) != 0 || (frame_height % 2) != 0) { + fprintf(stderr, "Frame size must be a multiple of 2\n"); + exit(1); + } +} + + +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<> SCALEBITS) + +#define RGB_TO_U(r1, g1, b1, shift)\ +(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ + FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V(r1, g1, b1, shift)\ +(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ + FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +static void opt_pad_color(const char *arg) { + /* Input is expected to be six hex digits similar to + how colors are expressed in html tags (but without the #) */ + int rgb = strtol(arg, NULL, 16); + int r,g,b; + + r = (rgb >> 16); + g = ((rgb >> 8) & 255); + b = (rgb & 255); + + padcolor[0] = RGB_TO_Y(r,g,b); + padcolor[1] = RGB_TO_U(r,g,b,0); + padcolor[2] = RGB_TO_V(r,g,b,0); +} + +static void opt_frame_pad_top(const char *arg) +{ + frame_padtop = atoi(arg); + if (frame_padtop < 0) { + fprintf(stderr, "Incorrect top pad size\n"); + exit(1); + } + if ((frame_padtop % 2) != 0) { + fprintf(stderr, "Top pad size must be a multiple of 2\n"); + exit(1); + } +} + +static void opt_frame_pad_bottom(const char *arg) +{ + frame_padbottom = atoi(arg); + if (frame_padbottom < 0) { + fprintf(stderr, "Incorrect bottom pad size\n"); + exit(1); + } + if ((frame_padbottom % 2) != 0) { + fprintf(stderr, "Bottom pad size must be a multiple of 2\n"); + exit(1); + } +} + + +static void opt_frame_pad_left(const char *arg) +{ + frame_padleft = atoi(arg); + if (frame_padleft < 0) { + fprintf(stderr, "Incorrect left pad size\n"); + exit(1); + } + if ((frame_padleft % 2) != 0) { + fprintf(stderr, "Left pad size must be a multiple of 2\n"); + exit(1); + } +} + + +static void opt_frame_pad_right(const char *arg) +{ + frame_padright = atoi(arg); + if (frame_padright < 0) { + fprintf(stderr, "Incorrect right pad size\n"); + exit(1); + } + if ((frame_padright % 2) != 0) { + fprintf(stderr, "Right pad size must be a multiple of 2\n"); + exit(1); + } +} + + +static void opt_frame_pix_fmt(const char *arg) +{ + frame_pix_fmt = avcodec_get_pix_fmt(arg); +} + +static void opt_frame_aspect_ratio(const char *arg) +{ + int x = 0, y = 0; + double ar = 0; + const char *p; + + p = strchr(arg, ':'); + if (p) { + x = strtol(arg, (char **)&arg, 10); + if (arg == p) + y = strtol(arg+1, (char **)&arg, 10); + if (x > 0 && y > 0) + ar = (double)x / (double)y; + } else + ar = strtod(arg, (char **)&arg); + + if (!ar) { + fprintf(stderr, "Incorrect aspect ratio specification.\n"); + exit(1); + } + frame_aspect_ratio = ar; +} + +static void opt_gop_size(const char *arg) +{ + gop_size = atoi(arg); +} + +static void opt_b_frames(const char *arg) +{ + b_frames = atoi(arg); + if (b_frames > FF_MAX_B_FRAMES) { + fprintf(stderr, "\nCannot have more than %d B frames, increase FF_MAX_B_FRAMES.\n", FF_MAX_B_FRAMES); + exit(1); + } else if (b_frames < 1) { + fprintf(stderr, "\nNumber of B frames must be higher than 0\n"); + exit(1); + } +} + +static void opt_pre_me(const char *arg) +{ + pre_me = atoi(arg); +} + +static void opt_qscale(const char *arg) +{ + video_qscale = atof(arg); + if (video_qscale < 0.01 || + video_qscale > 255) { + fprintf(stderr, "qscale must be >= 0.01 and <= 255\n"); + exit(1); + } +} + +static void opt_qsquish(const char *arg) +{ + video_qsquish = atof(arg); + if (video_qsquish < 0.0 || + video_qsquish > 99.0) { + fprintf(stderr, "qsquish must be >= 0.0 and <= 99.0\n"); + exit(1); + } +} + +static void opt_lmax(const char *arg) +{ + video_lmax = atof(arg)*FF_QP2LAMBDA; +} + +static void opt_lmin(const char *arg) +{ + video_lmin = atof(arg)*FF_QP2LAMBDA; +} + +static void opt_qmin(const char *arg) +{ + video_qmin = atoi(arg); + if (video_qmin < 1 || + video_qmin > 51) { + fprintf(stderr, "qmin must be >= 1 and <= 51\n"); + exit(1); + } +} + +static void opt_qmax(const char *arg) +{ + video_qmax = atoi(arg); + if (video_qmax < 1 || + video_qmax > 51) { + fprintf(stderr, "qmax must be >= 1 and <= 51\n"); + exit(1); + } +} + +static void opt_mb_lmin(const char *arg) +{ + video_mb_lmin = atof(arg)*FF_QP2LAMBDA; + if (video_mb_lmin < 1 || + video_mb_lmin > FF_LAMBDA_MAX) { + fprintf(stderr, "mblmin must be >= 1 and <= %d\n", FF_LAMBDA_MAX / FF_QP2LAMBDA); + exit(1); + } +} + +static void opt_mb_lmax(const char *arg) +{ + video_mb_lmax = atof(arg)*FF_QP2LAMBDA; + if (video_mb_lmax < 1 || + video_mb_lmax > FF_LAMBDA_MAX) { + fprintf(stderr, "mblmax must be >= 1 and <= %d\n", FF_LAMBDA_MAX / FF_QP2LAMBDA); + exit(1); + } +} + +static void opt_qdiff(const char *arg) +{ + video_qdiff = atoi(arg); + if (video_qdiff < 0 || + video_qdiff > 31) { + fprintf(stderr, "qdiff must be >= 1 and <= 31\n"); + exit(1); + } +} + +static void opt_qblur(const char *arg) +{ + video_qblur = atof(arg); +} + +static void opt_qcomp(const char *arg) +{ + video_qcomp = atof(arg); +} + +static void opt_rc_initial_cplx(const char *arg) +{ + video_rc_initial_cplx = atof(arg); +} +static void opt_b_qfactor(const char *arg) +{ + video_b_qfactor = atof(arg); +} +static void opt_i_qfactor(const char *arg) +{ + video_i_qfactor = atof(arg); +} +static void opt_b_qoffset(const char *arg) +{ + video_b_qoffset = atof(arg); +} +static void opt_i_qoffset(const char *arg) +{ + video_i_qoffset = atof(arg); +} + +static void opt_ibias(const char *arg) +{ + video_intra_quant_bias = atoi(arg); +} +static void opt_pbias(const char *arg) +{ + video_inter_quant_bias = atoi(arg); +} + +static void opt_packet_size(const char *arg) +{ + packet_size= atoi(arg); +} + +static void opt_error_rate(const char *arg) +{ + error_rate= atoi(arg); +} + +static void opt_strict(const char *arg) +{ + strict= atoi(arg); +} + +static void opt_top_field_first(const char *arg) +{ + top_field_first= atoi(arg); +} + +static void opt_sc_threshold(const char *arg) +{ + sc_threshold= atoi(arg); +} + +static void opt_me_range(const char *arg) +{ + me_range = atoi(arg); +} + +static void opt_thread_count(const char *arg) +{ + thread_count= atoi(arg); +#if !defined(HAVE_THREADS) + if (verbose >= 0) + fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n"); +#endif +} + +static void opt_audio_bitrate(const char *arg) +{ + audio_bit_rate = atoi(arg) * 1000; +} + +static void opt_audio_rate(const char *arg) +{ + audio_sample_rate = atoi(arg); +} + +static void opt_audio_channels(const char *arg) +{ + audio_channels = atoi(arg); +} + +static void opt_video_device(const char *arg) +{ + video_device = av_strdup(arg); +} + +static void opt_grab_device(const char *arg) +{ + grab_device = av_strdup(arg); +} + +static void opt_video_channel(const char *arg) +{ + video_channel = strtol(arg, NULL, 0); +} + +static void opt_video_standard(const char *arg) +{ + video_standard = av_strdup(arg); +} + +static void opt_audio_device(const char *arg) +{ + audio_device = av_strdup(arg); +} + +static void opt_codec(int *pstream_copy, int *pcodec_id, + int codec_type, const char *arg) +{ + AVCodec *p; + + if (!strcmp(arg, "copy")) { + *pstream_copy = 1; + } else { + p = first_avcodec; + while (p) { + if (!strcmp(p->name, arg) && p->type == codec_type) + break; + p = p->next; + } + if (p == NULL) { + fprintf(stderr, "Unknown codec '%s'\n", arg); + exit(1); + } else { + *pcodec_id = p->id; + } + } +} + +static void opt_audio_codec(const char *arg) +{ + opt_codec(&audio_stream_copy, &audio_codec_id, CODEC_TYPE_AUDIO, arg); +} + +static void opt_audio_tag(const char *arg) +{ + char *tail; + audio_codec_tag= strtol(arg, &tail, 0); + + if(!tail || *tail) + audio_codec_tag= arg[0] + (arg[1]<<8) + (arg[2]<<16) + (arg[3]<<24); +} + +static void opt_video_tag(const char *arg) +{ + char *tail; + video_codec_tag= strtol(arg, &tail, 0); + + if(!tail || *tail) + video_codec_tag= arg[0] + (arg[1]<<8) + (arg[2]<<16) + (arg[3]<<24); +} + +static void add_frame_hooker(const char *arg) +{ + int argc = 0; + char *argv[64]; + int i; + char *args = av_strdup(arg); + + using_vhook = 1; + + argv[0] = strtok(args, " "); + while (argc < 62 && (argv[++argc] = strtok(NULL, " "))) { + } + + i = frame_hook_add(argc, argv); + + if (i != 0) { + fprintf(stderr, "Failed to add video hook function: %s\n", arg); + exit(1); + } +} + +const char *motion_str[] = { + "zero", + "full", + "log", + "phods", + "epzs", + "x1", + "hex", + "umh", + "iter", + NULL, +}; + +static void opt_motion_estimation(const char *arg) +{ + const char **p; + p = motion_str; + for(;;) { + if (!*p) { + fprintf(stderr, "Unknown motion estimation method '%s'\n", arg); + exit(1); + } + if (!strcmp(*p, arg)) + break; + p++; + } + me_method = (p - motion_str) + 1; +} + +static void opt_video_codec(const char *arg) +{ + opt_codec(&video_stream_copy, &video_codec_id, CODEC_TYPE_VIDEO, arg); +} + +static void opt_subtitle_codec(const char *arg) +{ + opt_codec(&subtitle_stream_copy, &subtitle_codec_id, CODEC_TYPE_SUBTITLE, arg); +} + +static void opt_map(const char *arg) +{ + AVStreamMap *m; + const char *p; + + p = arg; + m = &stream_maps[nb_stream_maps++]; + + m->file_index = strtol(arg, (char **)&p, 0); + if (*p) + p++; + + m->stream_index = strtol(p, (char **)&p, 0); + if (*p) { + p++; + m->sync_file_index = strtol(p, (char **)&p, 0); + if (*p) + p++; + m->sync_stream_index = strtol(p, (char **)&p, 0); + } else { + m->sync_file_index = m->file_index; + m->sync_stream_index = m->stream_index; + } +} + +static void opt_map_meta_data(const char *arg) +{ + AVMetaDataMap *m; + const char *p; + + p = arg; + m = &meta_data_maps[nb_meta_data_maps++]; + + m->out_file = strtol(arg, (char **)&p, 0); + if (*p) + p++; + + m->in_file = strtol(p, (char **)&p, 0); +} + +static void opt_recording_time(const char *arg) +{ + recording_time = parse_date(arg, 1); +} + +static void opt_start_time(const char *arg) +{ + start_time = parse_date(arg, 1); +} + +static void opt_rec_timestamp(const char *arg) +{ + rec_timestamp = parse_date(arg, 0) / 1000000; +} + +static void opt_input_ts_offset(const char *arg) +{ + input_ts_offset = parse_date(arg, 1); +} + +static void opt_input_file(const char *filename) +{ + AVFormatContext *ic; + AVFormatParameters params, *ap = ¶ms; + int err, i, ret, rfps, rfps_base; + int64_t timestamp; + + if (!strcmp(filename, "-")) + filename = "pipe:"; + + using_stdin |= !strncmp(filename, "pipe:", 5) || + !strcmp( filename, "/dev/stdin" ); + + /* get default parameters from command line */ + memset(ap, 0, sizeof(*ap)); + ap->sample_rate = audio_sample_rate; + ap->channels = audio_channels; + ap->time_base.den = frame_rate; + ap->time_base.num = frame_rate_base; + ap->width = frame_width + frame_padleft + frame_padright; + ap->height = frame_height + frame_padtop + frame_padbottom; + ap->image_format = image_format; + ap->pix_fmt = frame_pix_fmt; + ap->device = grab_device; + ap->channel = video_channel; + ap->standard = video_standard; + ap->video_codec_id = video_codec_id; + ap->audio_codec_id = audio_codec_id; + if(pgmyuv_compatibility_hack) + ap->video_codec_id= CODEC_ID_PGMYUV; + + /* open the input file with generic libav function */ + err = av_open_input_file(&ic, filename, file_iformat, 0, ap); + if (err < 0) { + print_error(filename, err); + exit(1); + } + + if(genpts) + ic->flags|= AVFMT_FLAG_GENPTS; + + /* If not enough info to get the stream parameters, we decode the + first frames to get it. (used in mpeg case for example) */ + ret = av_find_stream_info(ic); + if (ret < 0 && verbose >= 0) { + fprintf(stderr, "%s: could not find codec parameters\n", filename); + exit(1); + } + + timestamp = start_time; + /* add the stream start time */ + if (ic->start_time != AV_NOPTS_VALUE) + timestamp += ic->start_time; + + /* if seeking requested, we execute it */ + if (start_time != 0) { + ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD); + if (ret < 0) { + fprintf(stderr, "%s: could not seek to position %0.3f\n", + filename, (double)timestamp / AV_TIME_BASE); + } + /* reset seek info */ + start_time = 0; + } + + /* update the current parameters so that they match the one of the input stream */ + for(i=0;inb_streams;i++) { + int j; + AVCodecContext *enc = ic->streams[i]->codec; +#if defined(HAVE_THREADS) + if(thread_count>1) + avcodec_thread_init(enc, thread_count); +#endif + enc->thread_count= thread_count; + switch(enc->codec_type) { + case CODEC_TYPE_AUDIO: + for(j=0; jflags&AV_OPT_FLAG_AUDIO_PARAM) && (opt->flags&AV_OPT_FLAG_DECODING_PARAM)) + av_set_double(enc, opt_names[j], d); + } + //fprintf(stderr, "\nInput Audio channels: %d", enc->channels); + audio_channels = enc->channels; + audio_sample_rate = enc->sample_rate; + if(audio_disable) + ic->streams[i]->discard= AVDISCARD_ALL; + break; + case CODEC_TYPE_VIDEO: + for(j=0; jflags&AV_OPT_FLAG_VIDEO_PARAM) && (opt->flags&AV_OPT_FLAG_DECODING_PARAM)) + av_set_double(enc, opt_names[j], d); + } + frame_height = enc->height; + frame_width = enc->width; + frame_aspect_ratio = av_q2d(enc->sample_aspect_ratio) * enc->width / enc->height; + frame_pix_fmt = enc->pix_fmt; + rfps = ic->streams[i]->r_frame_rate.num; + rfps_base = ic->streams[i]->r_frame_rate.den; + enc->workaround_bugs = workaround_bugs; + if(enc->lowres) enc->flags |= CODEC_FLAG_EMU_EDGE; + if(me_threshold) + enc->debug |= FF_DEBUG_MV; + + if (enc->time_base.den != rfps || enc->time_base.num != rfps_base) { + + if (verbose >= 0) + fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f (%d/%d) -> %2.2f (%d/%d)\n", + i, (float)enc->time_base.den / enc->time_base.num, enc->time_base.den, enc->time_base.num, + + (float)rfps / rfps_base, rfps, rfps_base); + } + /* update the current frame rate to match the stream frame rate */ + frame_rate = rfps; + frame_rate_base = rfps_base; + + enc->rate_emu = rate_emu; + if(video_disable) + ic->streams[i]->discard= AVDISCARD_ALL; + else if(video_discard) + ic->streams[i]->discard= video_discard; + break; + case CODEC_TYPE_DATA: + break; + case CODEC_TYPE_SUBTITLE: + break; + case CODEC_TYPE_UNKNOWN: + break; + default: + av_abort(); + } + } + + input_files[nb_input_files] = ic; + input_files_ts_offset[nb_input_files] = input_ts_offset - (copy_ts ? 0 : timestamp); + /* dump the file content */ + if (verbose >= 0) + dump_format(ic, nb_input_files, filename, 0); + + nb_input_files++; + file_iformat = NULL; + file_oformat = NULL; + image_format = NULL; + + grab_device = NULL; + video_channel = 0; + + rate_emu = 0; +} + +static void opt_grab(const char *arg) +{ + file_iformat = av_find_input_format(arg); + opt_input_file(""); +} + +static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr) +{ + int has_video, has_audio, i, j; + AVFormatContext *ic; + + has_video = 0; + has_audio = 0; + for(j=0;jnb_streams;i++) { + AVCodecContext *enc = ic->streams[i]->codec; + switch(enc->codec_type) { + case CODEC_TYPE_AUDIO: + has_audio = 1; + break; + case CODEC_TYPE_VIDEO: + has_video = 1; + break; + case CODEC_TYPE_DATA: + case CODEC_TYPE_UNKNOWN: + case CODEC_TYPE_SUBTITLE: + break; + default: + av_abort(); + } + } + } + *has_video_ptr = has_video; + *has_audio_ptr = has_audio; +} + +static void new_video_stream(AVFormatContext *oc) +{ + AVStream *st; + AVCodecContext *video_enc; + int codec_id; + + st = av_new_stream(oc, oc->nb_streams); + if (!st) { + fprintf(stderr, "Could not alloc stream\n"); + exit(1); + } +#if defined(HAVE_THREADS) + if(thread_count>1) + avcodec_thread_init(st->codec, thread_count); +#endif + + video_enc = st->codec; + + if(video_codec_tag) + video_enc->codec_tag= video_codec_tag; + + if( (video_global_header&1) + || (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))){ + video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; + avctx_opts->flags|= CODEC_FLAG_GLOBAL_HEADER; + } + if(video_global_header&2){ + video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER; + avctx_opts->flags2|= CODEC_FLAG2_LOCAL_HEADER; + } + + if (video_stream_copy) { + st->stream_copy = 1; + video_enc->codec_type = CODEC_TYPE_VIDEO; + } else { + char *p; + int i; + AVCodec *codec; + + codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO); + if (video_codec_id != CODEC_ID_NONE) + codec_id = video_codec_id; + + video_enc->codec_id = codec_id; + codec = avcodec_find_encoder(codec_id); + + for(i=0; iflags&AV_OPT_FLAG_VIDEO_PARAM) && (opt->flags&AV_OPT_FLAG_ENCODING_PARAM)) + av_set_double(video_enc, opt_names[i], d); + } + + video_enc->bit_rate = video_bit_rate; + video_enc->bit_rate_tolerance = video_bit_rate_tolerance; + video_enc->time_base.den = frame_rate; + video_enc->time_base.num = frame_rate_base; + if(codec && codec->supported_framerates){ + const AVRational *p= codec->supported_framerates; + AVRational req= (AVRational){frame_rate, frame_rate_base}; + const AVRational *best=NULL; + AVRational best_error= (AVRational){INT_MAX, 1}; + for(; p->den!=0; p++){ + AVRational error= av_sub_q(req, *p); + if(error.num <0) error.num *= -1; + if(av_cmp_q(error, best_error) < 0){ + best_error= error; + best= p; + } + } + video_enc->time_base.den= best->num; + video_enc->time_base.num= best->den; + } + + video_enc->width = frame_width + frame_padright + frame_padleft; + video_enc->height = frame_height + frame_padtop + frame_padbottom; + video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255); + video_enc->pix_fmt = frame_pix_fmt; + + if(codec && codec->pix_fmts){ + const enum PixelFormat *p= codec->pix_fmts; + for(; *p!=-1; p++){ + if(*p == video_enc->pix_fmt) + break; + } + if(*p == -1) + video_enc->pix_fmt = codec->pix_fmts[0]; + } + + if (!intra_only) + video_enc->gop_size = gop_size; + else + video_enc->gop_size = 0; + if (video_qscale || same_quality) { + video_enc->flags |= CODEC_FLAG_QSCALE; + video_enc->global_quality= + st->quality = FF_QP2LAMBDA * video_qscale; + } + + if(intra_matrix) + video_enc->intra_matrix = intra_matrix; + if(inter_matrix) + video_enc->inter_matrix = inter_matrix; + + video_enc->pre_me = pre_me; + + if (b_frames) { + video_enc->max_b_frames = b_frames; + video_enc->b_quant_factor = 2.0; + } + video_enc->qmin = video_qmin; + video_enc->qmax = video_qmax; + video_enc->lmin = video_lmin; + video_enc->lmax = video_lmax; + video_enc->rc_qsquish = video_qsquish; + video_enc->mb_lmin = video_mb_lmin; + video_enc->mb_lmax = video_mb_lmax; + video_enc->max_qdiff = video_qdiff; + video_enc->qblur = video_qblur; + video_enc->qcompress = video_qcomp; + video_enc->rc_eq = video_rc_eq; + video_enc->workaround_bugs = workaround_bugs; + video_enc->thread_count = thread_count; + p= video_rc_override_string; + for(i=0; p; i++){ + int start, end, q; + int e=sscanf(p, "%d,%d,%d", &start, &end, &q); + if(e!=3){ + fprintf(stderr, "error parsing rc_override\n"); + exit(1); + } + video_enc->rc_override= + av_realloc(video_enc->rc_override, + sizeof(RcOverride)*(i+1)); + video_enc->rc_override[i].start_frame= start; + video_enc->rc_override[i].end_frame = end; + if(q>0){ + video_enc->rc_override[i].qscale= q; + video_enc->rc_override[i].quality_factor= 1.0; + } + else{ + video_enc->rc_override[i].qscale= 0; + video_enc->rc_override[i].quality_factor= -q/100.0; + } + p= strchr(p, '/'); + if(p) p++; + } + video_enc->rc_override_count=i; + + video_enc->rc_max_rate = video_rc_max_rate; + video_enc->rc_min_rate = video_rc_min_rate; + video_enc->rc_buffer_size = video_rc_buffer_size; + video_enc->rc_initial_buffer_occupancy = video_rc_buffer_size*3/4; + video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity; + video_enc->rc_initial_cplx= video_rc_initial_cplx; + video_enc->i_quant_factor = video_i_qfactor; + video_enc->b_quant_factor = video_b_qfactor; + video_enc->i_quant_offset = video_i_qoffset; + video_enc->b_quant_offset = video_b_qoffset; + video_enc->intra_quant_bias = video_intra_quant_bias; + video_enc->inter_quant_bias = video_inter_quant_bias; + video_enc->me_threshold= me_threshold; + video_enc->mb_threshold= mb_threshold; + video_enc->intra_dc_precision= intra_dc_precision - 8; + video_enc->strict_std_compliance = strict; + video_enc->error_rate = error_rate; + video_enc->scenechange_threshold= sc_threshold; + video_enc->me_range = me_range; + video_enc->me_penalty_compensation= me_penalty_compensation; + video_enc->frame_skip_threshold= frame_skip_threshold; + video_enc->frame_skip_factor= frame_skip_factor; + video_enc->frame_skip_exp= frame_skip_exp; + + if(packet_size){ + video_enc->rtp_mode= 1; + video_enc->rtp_payload_size= packet_size; + } + + if (do_psnr) + video_enc->flags|= CODEC_FLAG_PSNR; + + video_enc->me_method = me_method; + + /* two pass mode */ + if (do_pass) { + if (do_pass == 1) { + video_enc->flags |= CODEC_FLAG_PASS1; + } else { + video_enc->flags |= CODEC_FLAG_PASS2; + } + } + } + + /* reset some key parameters */ + video_disable = 0; + video_codec_id = CODEC_ID_NONE; + video_stream_copy = 0; +} + +static void new_audio_stream(AVFormatContext *oc) +{ + AVStream *st; + AVCodecContext *audio_enc; + int codec_id, i; + + st = av_new_stream(oc, oc->nb_streams); + if (!st) { + fprintf(stderr, "Could not alloc stream\n"); + exit(1); + } +#if defined(HAVE_THREADS) + if(thread_count>1) + avcodec_thread_init(st->codec, thread_count); +#endif + + audio_enc = st->codec; + audio_enc->codec_type = CODEC_TYPE_AUDIO; + + if(audio_codec_tag) + audio_enc->codec_tag= audio_codec_tag; + + if (oc->oformat->flags & AVFMT_GLOBALHEADER) { + audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; + avctx_opts->flags|= CODEC_FLAG_GLOBAL_HEADER; + } + if (audio_stream_copy) { + st->stream_copy = 1; + audio_enc->channels = audio_channels; + } else { + codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO); + + for(i=0; iflags&AV_OPT_FLAG_AUDIO_PARAM) && (opt->flags&AV_OPT_FLAG_ENCODING_PARAM)) + av_set_double(audio_enc, opt_names[i], d); + } + + if (audio_codec_id != CODEC_ID_NONE) + codec_id = audio_codec_id; + audio_enc->codec_id = codec_id; + + audio_enc->bit_rate = audio_bit_rate; + if (audio_qscale > QSCALE_NONE) { + audio_enc->flags |= CODEC_FLAG_QSCALE; + audio_enc->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale; + } + audio_enc->strict_std_compliance = strict; + audio_enc->thread_count = thread_count; + /* For audio codecs other than AC3 or DTS we limit */ + /* the number of coded channels to stereo */ + if (audio_channels > 2 && codec_id != CODEC_ID_AC3 + && codec_id != CODEC_ID_DTS) { + audio_enc->channels = 2; + } else + audio_enc->channels = audio_channels; + } + audio_enc->sample_rate = audio_sample_rate; + audio_enc->time_base= (AVRational){1, audio_sample_rate}; + if (audio_language) { + pstrcpy(st->language, sizeof(st->language), audio_language); + av_free(audio_language); + audio_language = NULL; + } + + /* reset some key parameters */ + audio_disable = 0; + audio_codec_id = CODEC_ID_NONE; + audio_stream_copy = 0; +} + +static void opt_new_subtitle_stream(void) +{ + AVFormatContext *oc; + AVStream *st; + AVCodecContext *subtitle_enc; + int i; + + if (nb_output_files <= 0) { + fprintf(stderr, "At least one output file must be specified\n"); + exit(1); + } + oc = output_files[nb_output_files - 1]; + + st = av_new_stream(oc, oc->nb_streams); + if (!st) { + fprintf(stderr, "Could not alloc stream\n"); + exit(1); + } + + subtitle_enc = st->codec; + subtitle_enc->codec_type = CODEC_TYPE_SUBTITLE; + if (subtitle_stream_copy) { + st->stream_copy = 1; + } else { + for(i=0; iflags&AV_OPT_FLAG_SUBTITLE_PARAM) && (opt->flags&AV_OPT_FLAG_ENCODING_PARAM)) + av_set_double(subtitle_enc, opt_names[i], d); + } + subtitle_enc->codec_id = subtitle_codec_id; + } + + if (subtitle_language) { + pstrcpy(st->language, sizeof(st->language), subtitle_language); + av_free(subtitle_language); + subtitle_language = NULL; + } + + subtitle_codec_id = CODEC_ID_NONE; + subtitle_stream_copy = 0; +} + +static void opt_new_audio_stream(void) +{ + AVFormatContext *oc; + if (nb_output_files <= 0) { + fprintf(stderr, "At least one output file must be specified\n"); + exit(1); + } + oc = output_files[nb_output_files - 1]; + new_audio_stream(oc); +} + +static void opt_new_video_stream(void) +{ + AVFormatContext *oc; + if (nb_output_files <= 0) { + fprintf(stderr, "At least one output file must be specified\n"); + exit(1); + } + oc = output_files[nb_output_files - 1]; + new_video_stream(oc); +} + +static void opt_output_file(const char *filename) +{ + AVFormatContext *oc; + int use_video, use_audio, input_has_video, input_has_audio; + AVFormatParameters params, *ap = ¶ms; + + if (!strcmp(filename, "-")) + filename = "pipe:"; + + oc = av_alloc_format_context(); + + if (!file_oformat) { + file_oformat = guess_format(NULL, filename, NULL); + if (!file_oformat) { + fprintf(stderr, "Unable for find a suitable output format for '%s'\n", + filename); + exit(1); + } + } + + oc->oformat = file_oformat; + pstrcpy(oc->filename, sizeof(oc->filename), filename); + + if (!strcmp(file_oformat->name, "ffm") && + strstart(filename, "http:", NULL)) { + /* special case for files sent to ffserver: we get the stream + parameters from ffserver */ + if (read_ffserver_streams(oc, filename) < 0) { + fprintf(stderr, "Could not read stream parameters from '%s'\n", filename); + exit(1); + } + } else { + use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_id != CODEC_ID_NONE; + use_audio = file_oformat->audio_codec != CODEC_ID_NONE || audio_stream_copy || audio_codec_id != CODEC_ID_NONE; + + /* disable if no corresponding type found and at least one + input file */ + if (nb_input_files > 0) { + check_audio_video_inputs(&input_has_video, &input_has_audio); + if (!input_has_video) + use_video = 0; + if (!input_has_audio) + use_audio = 0; + } + + /* manual disable */ + if (audio_disable) { + use_audio = 0; + } + if (video_disable) { + use_video = 0; + } + + if (use_video) { + new_video_stream(oc); + } + + if (use_audio) { + new_audio_stream(oc); + } + + if (!oc->nb_streams) { + fprintf(stderr, "No audio or video streams available\n"); + exit(1); + } + + oc->timestamp = rec_timestamp; + + if (str_title) + pstrcpy(oc->title, sizeof(oc->title), str_title); + if (str_author) + pstrcpy(oc->author, sizeof(oc->author), str_author); + if (str_copyright) + pstrcpy(oc->copyright, sizeof(oc->copyright), str_copyright); + if (str_comment) + pstrcpy(oc->comment, sizeof(oc->comment), str_comment); + } + + output_files[nb_output_files++] = oc; + + /* check filename in case of an image number is expected */ + if (oc->oformat->flags & AVFMT_NEEDNUMBER) { + if (filename_number_test(oc->filename) < 0) { + print_error(oc->filename, AVERROR_NUMEXPECTED); + exit(1); + } + } + + if (!(oc->oformat->flags & AVFMT_NOFILE)) { + /* test if it already exists to avoid loosing precious files */ + if (!file_overwrite && + (strchr(filename, ':') == NULL || + strstart(filename, "file:", NULL))) { + if (url_exist(filename)) { + int c; + + if ( !using_stdin ) { + fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename); + fflush(stderr); + c = getchar(); + if (toupper(c) != 'Y') { + fprintf(stderr, "Not overwriting - exiting\n"); + exit(1); + } + } + else { + fprintf(stderr,"File '%s' already exists. Exiting.\n", filename); + exit(1); + } + } + } + + /* open the file */ + if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) { + fprintf(stderr, "Could not open '%s'\n", filename); + exit(1); + } + } + + memset(ap, 0, sizeof(*ap)); + ap->image_format = image_format; + if (av_set_parameters(oc, ap) < 0) { + fprintf(stderr, "%s: Invalid encoding parameters\n", + oc->filename); + exit(1); + } + + oc->packet_size= mux_packet_size; + oc->mux_rate= mux_rate; + oc->preload= (int)(mux_preload*AV_TIME_BASE); + oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE); + oc->loop_output = loop_output; + + /* reset some options */ + file_oformat = NULL; + file_iformat = NULL; + image_format = NULL; +} + +/* prepare dummy protocols for grab */ +static void prepare_grab(void) +{ + int has_video, has_audio, i, j; + AVFormatContext *oc; + AVFormatContext *ic; + AVFormatParameters vp1, *vp = &vp1; + AVFormatParameters ap1, *ap = &ap1; + + /* see if audio/video inputs are needed */ + has_video = 0; + has_audio = 0; + memset(ap, 0, sizeof(*ap)); + memset(vp, 0, sizeof(*vp)); + vp->time_base.num= 1; + for(j=0;jnb_streams;i++) { + AVCodecContext *enc = oc->streams[i]->codec; + switch(enc->codec_type) { + case CODEC_TYPE_AUDIO: + if (enc->sample_rate > ap->sample_rate) + ap->sample_rate = enc->sample_rate; + if (enc->channels > ap->channels) + ap->channels = enc->channels; + has_audio = 1; + break; + case CODEC_TYPE_VIDEO: + if (enc->width > vp->width) + vp->width = enc->width; + if (enc->height > vp->height) + vp->height = enc->height; + + if (vp->time_base.num*(int64_t)enc->time_base.den > enc->time_base.num*(int64_t)vp->time_base.den){ + vp->time_base = enc->time_base; + } + has_video = 1; + break; + default: + av_abort(); + } + } + } + + if (has_video == 0 && has_audio == 0) { + fprintf(stderr, "Output file must have at least one audio or video stream\n"); + exit(1); + } + + if (has_video) { + AVInputFormat *fmt1; + fmt1 = av_find_input_format(video_grab_format); + vp->device = video_device; + vp->channel = video_channel; + vp->standard = video_standard; + vp->pix_fmt = frame_pix_fmt; + if (av_open_input_file(&ic, "", fmt1, 0, vp) < 0) { + fprintf(stderr, "Could not find video grab device\n"); + exit(1); + } + /* If not enough info to get the stream parameters, we decode the + first frames to get it. */ + if ((ic->ctx_flags & AVFMTCTX_NOHEADER) && av_find_stream_info(ic) < 0) { + fprintf(stderr, "Could not find video grab parameters\n"); + exit(1); + } + /* by now video grab has one stream */ + ic->streams[0]->r_frame_rate.num = vp->time_base.den; + ic->streams[0]->r_frame_rate.den = vp->time_base.num; + input_files[nb_input_files] = ic; + + if (verbose >= 0) + dump_format(ic, nb_input_files, "", 0); + + nb_input_files++; + } + if (has_audio && audio_grab_format) { + AVInputFormat *fmt1; + fmt1 = av_find_input_format(audio_grab_format); + ap->device = audio_device; + if (av_open_input_file(&ic, "", fmt1, 0, ap) < 0) { + fprintf(stderr, "Could not find audio grab device\n"); + exit(1); + } + input_files[nb_input_files] = ic; + + if (verbose >= 0) + dump_format(ic, nb_input_files, "", 0); + + nb_input_files++; + } +} + +/* same option as mencoder */ +static void opt_pass(const char *pass_str) +{ + int pass; + pass = atoi(pass_str); + if (pass != 1 && pass != 2) { + fprintf(stderr, "pass number can be only 1 or 2\n"); + exit(1); + } + do_pass = pass; +} + +#if defined(CONFIG_WIN32) || defined(CONFIG_OS2) +static int64_t getutime(void) +{ + return av_gettime(); +} +#else +static int64_t getutime(void) +{ + struct rusage rusage; + + getrusage(RUSAGE_SELF, &rusage); + return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec; +} +#endif + +extern int ffm_nopts; + +static void show_formats(void) +{ + AVInputFormat *ifmt; + AVOutputFormat *ofmt; + AVImageFormat *image_fmt; + URLProtocol *up; + AVCodec *p, *p2; + const char **pp, *last_name; + + printf("File formats:\n"); + last_name= "000"; + for(;;){ + int decode=0; + int encode=0; + const char *name=NULL; + const char *long_name=NULL; + + for(ofmt = first_oformat; ofmt != NULL; ofmt = ofmt->next) { + if((name == NULL || strcmp(ofmt->name, name)<0) && + strcmp(ofmt->name, last_name)>0){ + name= ofmt->name; + long_name= ofmt->long_name; + encode=1; + } + } + for(ifmt = first_iformat; ifmt != NULL; ifmt = ifmt->next) { + if((name == NULL || strcmp(ifmt->name, name)<0) && + strcmp(ifmt->name, last_name)>0){ + name= ifmt->name; + long_name= ifmt->long_name; + encode=0; + } + if(name && strcmp(ifmt->name, name)==0) + decode=1; + } + if(name==NULL) + break; + last_name= name; + + printf( + " %s%s %-15s %s\n", + decode ? "D":" ", + encode ? "E":" ", + name, + long_name ? long_name:" "); + } + printf("\n"); + + printf("Image formats (filename extensions, if any, follow):\n"); + for(image_fmt = first_image_format; image_fmt != NULL; + image_fmt = image_fmt->next) { + printf( + " %s%s %-6s %s\n", + image_fmt->img_read ? "D":" ", + image_fmt->img_write ? "E":" ", + image_fmt->name, + image_fmt->extensions ? image_fmt->extensions:" "); + } + printf("\n"); + + printf("Codecs:\n"); + last_name= "000"; + for(;;){ + int decode=0; + int encode=0; + int cap=0; + const char *type_str; + + p2=NULL; + for(p = first_avcodec; p != NULL; p = p->next) { + if((p2==NULL || strcmp(p->name, p2->name)<0) && + strcmp(p->name, last_name)>0){ + p2= p; + decode= encode= cap=0; + } + if(p2 && strcmp(p->name, p2->name)==0){ + if(p->decode) decode=1; + if(p->encode) encode=1; + cap |= p->capabilities; + } + } + if(p2==NULL) + break; + last_name= p2->name; + + switch(p2->type) { + case CODEC_TYPE_VIDEO: + type_str = "V"; + break; + case CODEC_TYPE_AUDIO: + type_str = "A"; + break; + case CODEC_TYPE_SUBTITLE: + type_str = "S"; + break; + default: + type_str = "?"; + break; + } + printf( + " %s%s%s%s%s%s %s", + decode ? "D": (/*p2->decoder ? "d":*/" "), + encode ? "E":" ", + type_str, + cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ", + cap & CODEC_CAP_DR1 ? "D":" ", + cap & CODEC_CAP_TRUNCATED ? "T":" ", + p2->name); + /* if(p2->decoder && decode==0) + printf(" use %s for decoding", p2->decoder->name);*/ + printf("\n"); + } + printf("\n"); + + printf("Supported file protocols:\n"); + for(up = first_protocol; up != NULL; up = up->next) + printf(" %s:", up->name); + printf("\n"); + + printf("Frame size, frame rate abbreviations:\n ntsc pal qntsc qpal sntsc spal film ntsc-film sqcif qcif cif 4cif\n"); + printf("Motion estimation methods:\n"); + pp = motion_str; + while (*pp) { + printf(" %s", *pp); + if ((pp - motion_str + 1) == ME_ZERO) + printf("(fastest)"); + else if ((pp - motion_str + 1) == ME_FULL) + printf("(slowest)"); + else if ((pp - motion_str + 1) == ME_EPZS) + printf("(default)"); + pp++; + } + printf("\n\n"); + printf( +"Note, the names of encoders and decoders dont always match, so there are\n" +"several cases where the above table shows encoder only or decoder only entries\n" +"even though both encoding and decoding are supported for example, the h263\n" +"decoder corresponds to the h263 and h263p encoders, for file formats its even\n" +"worse\n"); + exit(1); +} + +static void parse_matrix_coeffs(uint16_t *dest, const char *str) +{ + int i; + const char *p = str; + for(i = 0;; i++) { + dest[i] = atoi(p); + if(i == 63) + break; + p = strchr(p, ','); + if(!p) { + fprintf(stderr, "Syntax error in matrix \"%s\" at coeff %d\n", str, i); + exit(1); + } + p++; + } +} + +static void opt_inter_matrix(const char *arg) +{ + inter_matrix = av_mallocz(sizeof(uint16_t) * 64); + parse_matrix_coeffs(inter_matrix, arg); +} + +static void opt_intra_matrix(const char *arg) +{ + intra_matrix = av_mallocz(sizeof(uint16_t) * 64); + parse_matrix_coeffs(intra_matrix, arg); +} + +static void opt_target(const char *arg) +{ + int norm = -1; + static const char *const frame_rates[] = {"25", "30000/1001", "24000/1001"}; + + if(!strncmp(arg, "pal-", 4)) { + norm = 0; + arg += 4; + } else if(!strncmp(arg, "ntsc-", 5)) { + norm = 1; + arg += 5; + } else if(!strncmp(arg, "film-", 5)) { + norm = 2; + arg += 5; + } else { + int fr; + /* Calculate FR via float to avoid int overflow */ + fr = (int)(frame_rate * 1000.0 / frame_rate_base); + if(fr == 25000) { + norm = 0; + } else if((fr == 29970) || (fr == 23976)) { + norm = 1; + } else { + /* Try to determine PAL/NTSC by peeking in the input files */ + if(nb_input_files) { + int i, j; + for(j = 0; j < nb_input_files; j++) { + for(i = 0; i < input_files[j]->nb_streams; i++) { + AVCodecContext *c = input_files[j]->streams[i]->codec; + if(c->codec_type != CODEC_TYPE_VIDEO) + continue; + fr = c->time_base.den * 1000 / c->time_base.num; + if(fr == 25000) { + norm = 0; + break; + } else if((fr == 29970) || (fr == 23976)) { + norm = 1; + break; + } + } + if(norm >= 0) + break; + } + } + } + if(verbose && norm >= 0) + fprintf(stderr, "Assuming %s for target.\n", norm ? "NTSC" : "PAL"); + } + + if(norm < 0) { + fprintf(stderr, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n"); + fprintf(stderr, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n"); + fprintf(stderr, "or set a framerate with \"-r xxx\".\n"); + exit(1); + } + + if(!strcmp(arg, "vcd")) { + + opt_video_codec("mpeg1video"); + opt_audio_codec("mp2"); + opt_format("vcd"); + + opt_frame_size(norm ? "352x240" : "352x288"); + opt_frame_rate(frame_rates[norm]); + opt_gop_size(norm ? "18" : "15"); + + video_bit_rate = 1150000; + video_rc_max_rate = 1150000; + video_rc_min_rate = 1150000; + video_rc_buffer_size = 40*1024*8; + + audio_bit_rate = 224000; + audio_sample_rate = 44100; + + mux_packet_size= 2324; + mux_rate= 2352 * 75 * 8; + + /* We have to offset the PTS, so that it is consistent with the SCR. + SCR starts at 36000, but the first two packs contain only padding + and the first pack from the other stream, respectively, may also have + been written before. + So the real data starts at SCR 36000+3*1200. */ + mux_preload= (36000+3*1200) / 90000.0; //0.44 + } else if(!strcmp(arg, "svcd")) { + + opt_video_codec("mpeg2video"); + opt_audio_codec("mp2"); + opt_format("svcd"); + + opt_frame_size(norm ? "480x480" : "480x576"); + opt_frame_rate(frame_rates[norm]); + opt_gop_size(norm ? "18" : "15"); + + video_bit_rate = 2040000; + video_rc_max_rate = 2516000; + video_rc_min_rate = 0; //1145000; + video_rc_buffer_size = 224*1024*8; + opt_default("flags", "+SCAN_OFFSET"); + + + audio_bit_rate = 224000; + audio_sample_rate = 44100; + + mux_packet_size= 2324; + + } else if(!strcmp(arg, "dvd")) { + + opt_video_codec("mpeg2video"); + opt_audio_codec("ac3"); + opt_format("dvd"); + + opt_frame_size(norm ? "720x480" : "720x576"); + opt_frame_rate(frame_rates[norm]); + opt_gop_size(norm ? "18" : "15"); + + video_bit_rate = 6000000; + video_rc_max_rate = 9000000; + video_rc_min_rate = 0; //1500000; + video_rc_buffer_size = 224*1024*8; + + mux_packet_size= 2048; // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack. + mux_rate = 10080000; // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8 + + audio_bit_rate = 448000; + audio_sample_rate = 48000; + + } else if(!strncmp(arg, "dv", 2)) { + + opt_format("dv"); + + opt_frame_size(norm ? "720x480" : "720x576"); + opt_frame_pix_fmt(!strncmp(arg, "dv50", 4) ? "yuv422p" : + (norm ? "yuv411p" : "yuv420p")); + opt_frame_rate(frame_rates[norm]); + + audio_sample_rate = 48000; + audio_channels = 2; + + } else { + fprintf(stderr, "Unknown target: %s\n", arg); + exit(1); + } +} + +static void show_version(void) +{ + /* TODO: add function interface to avutil and avformat */ + fprintf(stderr, "ffmpeg " FFMPEG_VERSION "\n" + "libavutil %d\n" + "libavcodec %d\n" + "libavformat %d\n", + LIBAVUTIL_BUILD, avcodec_build(), LIBAVFORMAT_BUILD); + exit(1); +} + +static int opt_default(const char *opt, const char *arg){ + AVOption *o= av_set_string(avctx_opts, opt, arg); + if(!o) + return -1; + +// av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avctx_opts, opt, NULL), (int)av_get_int(avctx_opts, opt, NULL)); + + //FIXME we should always use avctx_opts, ... for storing options so there wont be any need to keep track of whats set over this + opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1)); + opt_names[opt_name_count++]= o->name; + + /* disable generate of real time pts in ffm (need to be supressed anyway) */ + if(avctx_opts->flags & CODEC_FLAG_BITEXACT) + ffm_nopts = 1; + + if(avctx_opts->debug) + av_log_set_level(AV_LOG_DEBUG); + return 0; +} + +const OptionDef options[] = { + /* main options */ + { "L", 0, {(void*)show_license}, "show license" }, + { "h", 0, {(void*)show_help}, "show help" }, + { "version", 0, {(void*)show_version}, "show version" }, + { "formats", 0, {(void*)show_formats}, "show available formats, codecs, protocols, ..." }, + { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" }, + { "img", HAS_ARG, {(void*)opt_image_format}, "force image format", "img_fmt" }, + { "i", HAS_ARG, {(void*)opt_input_file}, "input file name", "filename" }, + { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, + { "map", HAS_ARG | OPT_EXPERT, {(void*)opt_map}, "set input stream mapping", "file:stream[:syncfile:syncstream]" }, + { "map_meta_data", HAS_ARG | OPT_EXPERT, {(void*)opt_map_meta_data}, "set meta data information of outfile from infile", "outfile:infile" }, + { "t", HAS_ARG, {(void*)opt_recording_time}, "set the recording time", "duration" }, + { "fs", HAS_ARG | OPT_INT, {(void*)&limit_filesize}, "set the limit file size", "limit_size" }, // + { "ss", HAS_ARG, {(void*)opt_start_time}, "set the start time offset", "time_off" }, + { "itsoffset", HAS_ARG, {(void*)opt_input_ts_offset}, "set the input ts offset", "time_off" }, + { "title", HAS_ARG | OPT_STRING, {(void*)&str_title}, "set the title", "string" }, + { "timestamp", HAS_ARG, {(void*)&opt_rec_timestamp}, "set the timestamp", "time" }, + { "author", HAS_ARG | OPT_STRING, {(void*)&str_author}, "set the author", "string" }, + { "copyright", HAS_ARG | OPT_STRING, {(void*)&str_copyright}, "set the copyright", "string" }, + { "comment", HAS_ARG | OPT_STRING, {(void*)&str_comment}, "set the comment", "string" }, + { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark}, + "add timings for benchmarking" }, + { "dump", OPT_BOOL | OPT_EXPERT, {(void*)&do_pkt_dump}, + "dump each input packet" }, + { "hex", OPT_BOOL | OPT_EXPERT, {(void*)&do_hex_dump}, + "when dumping packets, also dump the payload" }, + { "re", OPT_BOOL | OPT_EXPERT, {(void*)&rate_emu}, "read input at native frame rate", "" }, + { "loop_input", OPT_BOOL | OPT_EXPERT, {(void*)&loop_input}, "loop (current only works with images)" }, + { "loop_output", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&loop_output}, "number of times to loop output in formats that support looping (0 loops forever)", "" }, + { "v", HAS_ARG, {(void*)opt_verbose}, "control amount of logging", "verbose" }, + { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" }, + { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" }, + { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" }, + { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" }, + { "vglobal", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_global_header}, "video global header storage type", "" }, + { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)©_ts}, "copy timestamps" }, + { "shortest", OPT_BOOL | OPT_EXPERT, {(void*)&opt_shortest}, "finish encoding within shortest input" }, // + { "dts_delta_threshold", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&dts_delta_threshold}, "timestamp discontinuity delta threshold", "" }, + + /* video options */ + { "b", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate}, "set video bitrate (in kbit/s)", "bitrate" }, + { "vframes", OPT_INT | HAS_ARG | OPT_VIDEO, {(void*)&max_frames[CODEC_TYPE_VIDEO]}, "set the number of video frames to record", "number" }, + { "aframes", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&max_frames[CODEC_TYPE_AUDIO]}, "set the number of audio frames to record", "number" }, + { "dframes", OPT_INT | HAS_ARG, {(void*)&max_frames[CODEC_TYPE_DATA]}, "set the number of data frames to record", "number" }, + { "r", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_rate}, "set frame rate (Hz value, fraction or abbreviation)", "rate" }, + { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" }, + { "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" }, + { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format", "format" }, + { "croptop", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_top}, "set top crop band size (in pixels)", "size" }, + { "cropbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_bottom}, "set bottom crop band size (in pixels)", "size" }, + { "cropleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_left}, "set left crop band size (in pixels)", "size" }, + { "cropright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_crop_right}, "set right crop band size (in pixels)", "size" }, + { "padtop", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_top}, "set top pad band size (in pixels)", "size" }, + { "padbottom", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_bottom}, "set bottom pad band size (in pixels)", "size" }, + { "padleft", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_left}, "set left pad band size (in pixels)", "size" }, + { "padright", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_pad_right}, "set right pad band size (in pixels)", "size" }, + { "padcolor", HAS_ARG | OPT_VIDEO, {(void*)opt_pad_color}, "set color of pad bands (Hex 000000 thru FFFFFF)", "color" }, + { "g", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_gop_size}, "set the group of picture size", "gop_size" }, + { "intra", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_only}, "use only intra frames"}, + { "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" }, + { "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" }, + { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantiser scale (VBR)", "q" }, + { "qmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qmin}, "min video quantiser scale (VBR)", "q" }, + { "qmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qmax}, "max video quantiser scale (VBR)", "q" }, + { "lmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_lmin}, "min video lagrange factor (VBR)", "lambda" }, + { "lmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_lmax}, "max video lagrange factor (VBR)", "lambda" }, + { "mblmin", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_lmin}, "min macroblock quantiser scale (VBR)", "q" }, + { "mblmax", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_lmax}, "max macroblock quantiser scale (VBR)", "q" }, + { "qdiff", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qdiff}, "max difference between the quantiser scale (VBR)", "q" }, + { "qblur", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qblur}, "video quantiser scale blur (VBR)", "blur" }, + { "qsquish", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qsquish}, "how to keep quantiser between qmin and qmax (0 = clip, 1 = use differentiable function)", "squish" }, + { "qcomp", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qcomp}, "video quantiser scale compression (VBR)", "compression" }, + { "rc_init_cplx", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_rc_initial_cplx}, "initial complexity for 1-pass encoding", "complexity" }, + { "b_qfactor", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_b_qfactor}, "qp factor between p and b frames", "factor" }, + { "i_qfactor", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_i_qfactor}, "qp factor between p and i frames", "factor" }, + { "b_qoffset", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_b_qoffset}, "qp offset between p and b frames", "offset" }, + { "i_qoffset", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_i_qoffset}, "qp offset between p and i frames", "offset" }, + { "ibias", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_ibias}, "intra quant bias", "bias" }, + { "pbias", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_pbias}, "inter quant bias", "bias" }, + { "rc_eq", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_eq}, "set rate control equation", "equation" }, + { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" }, + { "bt", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_tolerance}, "set video bitrate tolerance (in kbit/s)", "tolerance" }, + { "maxrate", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_max}, "set max video bitrate tolerance (in kbit/s)", "bitrate" }, + { "minrate", HAS_ARG | OPT_VIDEO, {(void*)opt_video_bitrate_min}, "set min video bitrate tolerance (in kbit/s)", "bitrate" }, + { "bufsize", HAS_ARG | OPT_VIDEO, {(void*)opt_video_buffer_size}, "set ratecontrol buffer size (in kByte)", "size" }, + { "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" }, + { "me", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_motion_estimation}, "set motion estimation method", + "method" }, + { "me_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold", "" }, + { "mb_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_mb_threshold}, "macroblock threshold", "" }, + { "bf", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_b_frames}, "use 'frames' B frames", "frames" }, + { "preme", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_pre_me}, "pre motion estimation", "" }, + { "bug", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_workaround_bugs}, "workaround not auto detected encoder bugs", "param" }, + { "ps", HAS_ARG | OPT_EXPERT, {(void*)opt_packet_size}, "set packet size in bits", "size" }, + { "error", HAS_ARG | OPT_EXPERT, {(void*)opt_error_rate}, "error rate", "rate" }, + { "strict", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_strict}, "how strictly to follow the standards", "strictness" }, + { "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality}, + "use same video quality as source (implies VBR)" }, + { "pass", HAS_ARG | OPT_VIDEO, {(void*)&opt_pass}, "select the pass number (1 or 2)", "n" }, + { "passlogfile", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void*)&pass_logfilename}, "select two pass log file name", "file" }, + { "deinterlace", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_deinterlace}, + "deinterlace pictures" }, + { "psnr", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_psnr}, "calculate PSNR of compressed frames" }, + { "vstats", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_vstats}, "dump video coding statistics to file" }, + { "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" }, + { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" }, + { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" }, + { "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_top_field_first}, "top=1/bottom=0/auto=-1 field first", "" }, + { "sc_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_sc_threshold}, "scene change threshold", "threshold" }, + { "me_range", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_range}, "limit motion vectors range (1023 for DivX player)", "range" }, + { "dc", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_dc_precision}, "intra_dc_precision", "precision" }, + { "mepc", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&me_penalty_compensation}, "motion estimation bitrate penalty compensation", "factor (1.0 = 256)" }, + { "vtag", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_tag}, "force video tag/fourcc", "fourcc/tag" }, + { "skip_threshold", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_threshold}, "frame skip threshold", "threshold" }, + { "skip_factor", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_factor}, "frame skip factor", "factor" }, + { "skip_exp", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_exp}, "frame skip exponent", "exponent" }, + { "newvideo", OPT_VIDEO, {(void*)opt_new_video_stream}, "add a new video stream to the current output stream" }, + { "genpts", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&genpts }, "generate pts" }, + { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" }, + + /* audio options */ + { "ab", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_bitrate}, "set audio bitrate (in kbit/s)", "bitrate", }, + { "aq", OPT_FLOAT | HAS_ARG | OPT_AUDIO, {(void*)&audio_qscale}, "set audio quality (codec-specific)", "quality", }, + { "ar", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_rate}, "set audio sampling rate (in Hz)", "rate" }, + { "ac", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_channels}, "set number of audio channels", "channels" }, + { "an", OPT_BOOL | OPT_AUDIO, {(void*)&audio_disable}, "disable audio" }, + { "acodec", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" }, + { "atag", HAS_ARG | OPT_EXPERT | OPT_AUDIO, {(void*)opt_audio_tag}, "force audio tag/fourcc", "fourcc/tag" }, + { "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, // + { "newaudio", OPT_AUDIO, {(void*)opt_new_audio_stream}, "add a new audio stream to the current output stream" }, + { "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, "set the ISO 639 language code (3 letters) of the current audio stream" , "code" }, + + /* subtitle options */ + { "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" }, + { "newsubtitle", OPT_SUBTITLE, {(void*)opt_new_subtitle_stream}, "add a new subtitle stream to the current output stream" }, + { "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" }, + + /* grab options */ + { "vd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_device}, "set video grab device", "device" }, + { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" }, + { "tvstd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_standard}, "set television standard (NTSC, PAL (SECAM))", "standard" }, + { "ad", HAS_ARG | OPT_EXPERT | OPT_AUDIO | OPT_GRAB, {(void*)opt_audio_device}, "set audio device", "device" }, + + /* G.2 grab options */ + { "grab", HAS_ARG | OPT_EXPERT | OPT_GRAB, {(void*)opt_grab}, "request grabbing using", "format" }, + { "gd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_grab_device}, "set grab device", "device" }, + + /* muxer options */ + { "muxrate", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&mux_rate}, "set mux rate", "rate" }, + { "packetsize", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&mux_packet_size}, "set packet size", "size" }, + { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT, {(void*)&mux_max_delay}, "set the maximum demux-decode delay", "seconds" }, + { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT, {(void*)&mux_preload}, "set the initial demux-decode delay", "seconds" }, + { "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" }, + { NULL, }, +}; + +static void show_banner(void) +{ + fprintf(stderr, "FFmpeg version " FFMPEG_VERSION ", Copyright (c) 2000-2004 Fabrice Bellard\n"); + fprintf(stderr, " configuration: " FFMPEG_CONFIGURATION "\n"); + fprintf(stderr, " libavutil version: " AV_STRINGIFY(LIBAVUTIL_VERSION) "\n"); + fprintf(stderr, " libavcodec version: " AV_STRINGIFY(LIBAVCODEC_VERSION) "\n"); + fprintf(stderr, " libavformat version: " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\n"); + fprintf(stderr, " built on " __DATE__ " " __TIME__); +#ifdef __GNUC__ + fprintf(stderr, ", gcc: " __VERSION__ "\n"); +#else + fprintf(stderr, ", using a non-gcc compiler\n"); +#endif +} + +static void show_license(void) +{ + show_banner(); +#ifdef CONFIG_GPL + printf( + "This program is free software; you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation; either version 2 of the License, or\n" + "(at your option) any later version.\n" + "\n" + "This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n" + "\n" + "You should have received a copy of the GNU General Public License\n" + "along with this program; if not, write to the Free Software\n" + "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n" + ); +#else + printf( + "This library is free software; you can redistribute it and/or\n" + "modify it under the terms of the GNU Lesser General Public\n" + "License as published by the Free Software Foundation; either\n" + "version 2 of the License, or (at your option) any later version.\n" + "\n" + "This library is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" + "Lesser General Public License for more details.\n" + "\n" + "You should have received a copy of the GNU Lesser General Public\n" + "License along with this library; if not, write to the Free Software\n" + "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" + ); +#endif + exit(1); +} + +static void show_help(void) +{ + show_banner(); + printf("usage: ffmpeg [[infile options] -i infile]... {[outfile options] outfile}...\n" + "Hyper fast Audio and Video encoder\n"); + printf("\n"); + show_help_options(options, "Main options:\n", + OPT_EXPERT | OPT_AUDIO | OPT_VIDEO, 0); + show_help_options(options, "\nVideo options:\n", + OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, + OPT_VIDEO); + show_help_options(options, "\nAdvanced Video options:\n", + OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, + OPT_VIDEO | OPT_EXPERT); + show_help_options(options, "\nAudio options:\n", + OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, + OPT_AUDIO); + show_help_options(options, "\nAdvanced Audio options:\n", + OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, + OPT_AUDIO | OPT_EXPERT); + show_help_options(options, "\nSubtitle options:\n", + OPT_SUBTITLE | OPT_GRAB, + OPT_SUBTITLE); + show_help_options(options, "\nAudio/Video grab options:\n", + OPT_GRAB, + OPT_GRAB); + show_help_options(options, "\nAdvanced options:\n", + OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, + OPT_EXPERT); + av_opt_show(avctx_opts, NULL); + + exit(1); +} + +void parse_arg_file(const char *filename) +{ + opt_output_file(filename); +} + +int main(int argc, char **argv) +{ + int i; + int64_t ti; + + av_register_all(); + + avctx_opts= avcodec_alloc_context(); + + if (argc <= 1) + show_help(); + else + show_banner(); + + /* parse options */ + parse_options(argc, argv, options); + + /* file converter / grab */ + if (nb_output_files <= 0) { + fprintf(stderr, "Must supply at least one output file\n"); + exit(1); + } + + if (nb_input_files == 0) { + input_sync = 1; + prepare_grab(); + } + + ti = getutime(); + av_encode(output_files, nb_output_files, input_files, nb_input_files, + stream_maps, nb_stream_maps); + ti = getutime() - ti; + if (do_benchmark) { + printf("bench: utime=%0.3fs\n", ti / 1000000.0); + } + + /* close files */ + for(i=0;ioformat->flags & AVFMT_NOFILE)) + url_fclose(&s->pb); + for(j=0;jnb_streams;j++) + av_free(s->streams[j]); + av_free(s); + } + for(i=0;i +#include + +#ifdef CONFIG_WIN32 +#undef main /* We don't want SDL to override our main() */ +#endif + +#ifdef CONFIG_OS2 +#define INCL_DOS + #include + #include + + void MorphToPM() + { + PPIB pib; + PTIB tib; + + DosGetInfoBlocks(&tib, &pib); + + // Change flag from VIO to PM: + if (pib->pib_ultype==2) pib->pib_ultype = 3; + } +#endif + +#if defined(__linux__) +#define HAVE_X11 +#endif + +#ifdef HAVE_X11 +#include +#endif + +//#define DEBUG_SYNC + +#define MAX_VIDEOQ_SIZE (5 * 256 * 1024) +#define MAX_AUDIOQ_SIZE (5 * 16 * 1024) +#define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024) + +/* SDL audio buffer size, in samples. Should be small to have precise + A/V sync as SDL does not have hardware buffer fullness info. */ +#define SDL_AUDIO_BUFFER_SIZE 1024 + +/* no AV sync correction is done if below the AV sync threshold */ +#define AV_SYNC_THRESHOLD 0.01 +/* no AV correction is done if too big error */ +#define AV_NOSYNC_THRESHOLD 10.0 + +/* maximum audio speed change to get correct sync */ +#define SAMPLE_CORRECTION_PERCENT_MAX 10 + +/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */ +#define AUDIO_DIFF_AVG_NB 20 + +/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */ +#define SAMPLE_ARRAY_SIZE (2*65536) + +typedef struct PacketQueue { + AVPacketList *first_pkt, *last_pkt; + int nb_packets; + int size; + int abort_request; + SDL_mutex *mutex; + SDL_cond *cond; +} PacketQueue; + +#define VIDEO_PICTURE_QUEUE_SIZE 1 +#define SUBPICTURE_QUEUE_SIZE 4 + +typedef struct VideoPicture { + double pts; ///mutex = SDL_CreateMutex(); + q->cond = SDL_CreateCond(); +} + +static void packet_queue_flush(PacketQueue *q) +{ + AVPacketList *pkt, *pkt1; + + SDL_LockMutex(q->mutex); + for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) { + pkt1 = pkt->next; + av_free_packet(&pkt->pkt); + av_freep(&pkt); + } + q->last_pkt = NULL; + q->first_pkt = NULL; + q->nb_packets = 0; + q->size = 0; + SDL_UnlockMutex(q->mutex); +} + +static void packet_queue_end(PacketQueue *q) +{ + packet_queue_flush(q); + SDL_DestroyMutex(q->mutex); + SDL_DestroyCond(q->cond); +} + +static int packet_queue_put(PacketQueue *q, AVPacket *pkt) +{ + AVPacketList *pkt1; + + /* duplicate the packet */ + if (av_dup_packet(pkt) < 0) + return -1; + + pkt1 = av_malloc(sizeof(AVPacketList)); + if (!pkt1) + return -1; + pkt1->pkt = *pkt; + pkt1->next = NULL; + + + SDL_LockMutex(q->mutex); + + if (!q->last_pkt) + + q->first_pkt = pkt1; + else + q->last_pkt->next = pkt1; + q->last_pkt = pkt1; + q->nb_packets++; + q->size += pkt1->pkt.size; + /* XXX: should duplicate packet data in DV case */ + SDL_CondSignal(q->cond); + + SDL_UnlockMutex(q->mutex); + return 0; +} + +static void packet_queue_abort(PacketQueue *q) +{ + SDL_LockMutex(q->mutex); + + q->abort_request = 1; + + SDL_CondSignal(q->cond); + + SDL_UnlockMutex(q->mutex); +} + +/* return < 0 if aborted, 0 if no packet and > 0 if packet. */ +static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) +{ + AVPacketList *pkt1; + int ret; + + SDL_LockMutex(q->mutex); + + for(;;) { + if (q->abort_request) { + ret = -1; + break; + } + + pkt1 = q->first_pkt; + if (pkt1) { + q->first_pkt = pkt1->next; + if (!q->first_pkt) + q->last_pkt = NULL; + q->nb_packets--; + q->size -= pkt1->pkt.size; + *pkt = pkt1->pkt; + av_free(pkt1); + ret = 1; + break; + } else if (!block) { + ret = 0; + break; + } else { + SDL_CondWait(q->cond, q->mutex); + } + } + SDL_UnlockMutex(q->mutex); + return ret; +} + +static inline void fill_rectangle(SDL_Surface *screen, + int x, int y, int w, int h, int color) +{ + SDL_Rect rect; + rect.x = x; + rect.y = y; + rect.w = w; + rect.h = h; + SDL_FillRect(screen, &rect, color); +} + +#if 0 +/* draw only the border of a rectangle */ +void fill_border(VideoState *s, int x, int y, int w, int h, int color) +{ + int w1, w2, h1, h2; + + /* fill the background */ + w1 = x; + if (w1 < 0) + w1 = 0; + w2 = s->width - (x + w); + if (w2 < 0) + w2 = 0; + h1 = y; + if (h1 < 0) + h1 = 0; + h2 = s->height - (y + h); + if (h2 < 0) + h2 = 0; + fill_rectangle(screen, + s->xleft, s->ytop, + w1, s->height, + color); + fill_rectangle(screen, + s->xleft + s->width - w2, s->ytop, + w2, s->height, + color); + fill_rectangle(screen, + s->xleft + w1, s->ytop, + s->width - w1 - w2, h1, + color); + fill_rectangle(screen, + s->xleft + w1, s->ytop + s->height - h2, + s->width - w1 - w2, h2, + color); +} +#endif + + + +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<> SCALEBITS) + +#define RGB_TO_U_CCIR(r1, g1, b1, shift)\ +(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ + FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V_CCIR(r1, g1, b1, shift)\ +(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ + FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define ALPHA_BLEND(a, oldp, newp, s)\ +((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s)) + +#define RGBA_IN(r, g, b, a, s)\ +{\ + unsigned int v = ((const uint32_t *)(s))[0];\ + a = (v >> 24) & 0xff;\ + r = (v >> 16) & 0xff;\ + g = (v >> 8) & 0xff;\ + b = v & 0xff;\ +} + +#define YUVA_IN(y, u, v, a, s, pal)\ +{\ + unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)s];\ + a = (val >> 24) & 0xff;\ + y = (val >> 16) & 0xff;\ + u = (val >> 8) & 0xff;\ + v = val & 0xff;\ +} + +#define YUVA_OUT(d, y, u, v, a)\ +{\ + ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\ +} + + +#define BPP 1 + +static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect) +{ + int wrap, wrap3, width2, skip2; + int y, u, v, a, u1, v1, a1, w, h; + uint8_t *lum, *cb, *cr; + const uint8_t *p; + const uint32_t *pal; + + lum = dst->data[0] + rect->y * dst->linesize[0]; + cb = dst->data[1] + (rect->y >> 1) * dst->linesize[1]; + cr = dst->data[2] + (rect->y >> 1) * dst->linesize[2]; + + width2 = (rect->w + 1) >> 1; + skip2 = rect->x >> 1; + wrap = dst->linesize[0]; + wrap3 = rect->linesize; + p = rect->bitmap; + pal = rect->rgba_palette; /* Now in YCrCb! */ + + if (rect->y & 1) { + lum += rect->x; + cb += skip2; + cr += skip2; + + if (rect->x & 1) { + YUVA_IN(y, u, v, a, p, pal); + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0); + cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0); + cb++; + cr++; + lum++; + p += BPP; + } + for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + + YUVA_IN(y, u, v, a, p + BPP, pal); + u1 += u; + v1 += v; + a1 += a; + lum[1] = ALPHA_BLEND(a, lum[1], y, 0); + cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1); + cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1); + cb++; + cr++; + p += 2 * BPP; + lum += 2; + } + if (w) { + YUVA_IN(y, u, v, a, p, pal); + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0); + cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0); + } + p += wrap3 + (wrap3 - rect->w * BPP); + lum += wrap + (wrap - rect->w - rect->x); + cb += dst->linesize[1] - width2 - skip2; + cr += dst->linesize[2] - width2 - skip2; + } + for(h = rect->h - (rect->y & 1); h >= 2; h -= 2) { + lum += rect->x; + cb += skip2; + cr += skip2; + + if (rect->x & 1) { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + p += wrap3; + lum += wrap; + YUVA_IN(y, u, v, a, p, pal); + u1 += u; + v1 += v; + a1 += a; + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1); + cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1); + cb++; + cr++; + p += -wrap3 + BPP; + lum += -wrap + 1; + } + for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + + YUVA_IN(y, u, v, a, p, pal); + u1 += u; + v1 += v; + a1 += a; + lum[1] = ALPHA_BLEND(a, lum[1], y, 0); + p += wrap3; + lum += wrap; + + YUVA_IN(y, u, v, a, p, pal); + u1 += u; + v1 += v; + a1 += a; + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + + YUVA_IN(y, u, v, a, p, pal); + u1 += u; + v1 += v; + a1 += a; + lum[1] = ALPHA_BLEND(a, lum[1], y, 0); + + cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2); + cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2); + + cb++; + cr++; + p += -wrap3 + 2 * BPP; + lum += -wrap + 2; + } + if (w) { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + p += wrap3; + lum += wrap; + YUVA_IN(y, u, v, a, p, pal); + u1 += u; + v1 += v; + a1 += a; + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1); + cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1); + cb++; + cr++; + p += -wrap3 + BPP; + lum += -wrap + 1; + } + p += wrap3 + (wrap3 - rect->w * BPP); + lum += wrap + (wrap - rect->w - rect->x); + cb += dst->linesize[1] - width2 - skip2; + cr += dst->linesize[2] - width2 - skip2; + } + /* handle odd height */ + if (h) { + lum += rect->x; + cb += skip2; + cr += skip2; + + if (rect->x & 1) { + YUVA_IN(y, u, v, a, p, pal); + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0); + cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0); + cb++; + cr++; + lum++; + p += BPP; + } + for(w = rect->w - (rect->x & 1); w >= 2; w -= 2) { + YUVA_IN(y, u, v, a, p, pal); + u1 = u; + v1 = v; + a1 = a; + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + + YUVA_IN(y, u, v, a, p + BPP, pal); + u1 += u; + v1 += v; + a1 += a; + lum[1] = ALPHA_BLEND(a, lum[1], y, 0); + cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1); + cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1); + cb++; + cr++; + p += 2 * BPP; + lum += 2; + } + if (w) { + YUVA_IN(y, u, v, a, p, pal); + lum[0] = ALPHA_BLEND(a, lum[0], y, 0); + cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0); + cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0); + } + } +} + +static void free_subpicture(SubPicture *sp) +{ + int i; + + for (i = 0; i < sp->sub.num_rects; i++) + { + av_free(sp->sub.rects[i].bitmap); + av_free(sp->sub.rects[i].rgba_palette); + } + + av_free(sp->sub.rects); + + memset(&sp->sub, 0, sizeof(AVSubtitle)); +} + +static void video_image_display(VideoState *is) +{ + VideoPicture *vp; + SubPicture *sp; + AVPicture pict; + float aspect_ratio; + int width, height, x, y; + SDL_Rect rect; + int i; + + vp = &is->pictq[is->pictq_rindex]; + if (vp->bmp) { + /* XXX: use variable in the frame */ + if (is->video_st->codec->sample_aspect_ratio.num == 0) + aspect_ratio = 0; + else + aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio) + * is->video_st->codec->width / is->video_st->codec->height;; + if (aspect_ratio <= 0.0) + aspect_ratio = (float)is->video_st->codec->width / + (float)is->video_st->codec->height; + /* if an active format is indicated, then it overrides the + mpeg format */ +#if 0 + if (is->video_st->codec->dtg_active_format != is->dtg_active_format) { + is->dtg_active_format = is->video_st->codec->dtg_active_format; + printf("dtg_active_format=%d\n", is->dtg_active_format); + } +#endif +#if 0 + switch(is->video_st->codec->dtg_active_format) { + case FF_DTG_AFD_SAME: + default: + /* nothing to do */ + break; + case FF_DTG_AFD_4_3: + aspect_ratio = 4.0 / 3.0; + break; + case FF_DTG_AFD_16_9: + aspect_ratio = 16.0 / 9.0; + break; + case FF_DTG_AFD_14_9: + aspect_ratio = 14.0 / 9.0; + break; + case FF_DTG_AFD_4_3_SP_14_9: + aspect_ratio = 14.0 / 9.0; + break; + case FF_DTG_AFD_16_9_SP_14_9: + aspect_ratio = 14.0 / 9.0; + break; + case FF_DTG_AFD_SP_4_3: + aspect_ratio = 4.0 / 3.0; + break; + } +#endif + + if (is->subtitle_st) + { + if (is->subpq_size > 0) + { + sp = &is->subpq[is->subpq_rindex]; + + if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) + { + SDL_LockYUVOverlay (vp->bmp); + + pict.data[0] = vp->bmp->pixels[0]; + pict.data[1] = vp->bmp->pixels[2]; + pict.data[2] = vp->bmp->pixels[1]; + + pict.linesize[0] = vp->bmp->pitches[0]; + pict.linesize[1] = vp->bmp->pitches[2]; + pict.linesize[2] = vp->bmp->pitches[1]; + + for (i = 0; i < sp->sub.num_rects; i++) + blend_subrect(&pict, &sp->sub.rects[i]); + + SDL_UnlockYUVOverlay (vp->bmp); + } + } + } + + + /* XXX: we suppose the screen has a 1.0 pixel ratio */ + height = is->height; + width = ((int)rint(height * aspect_ratio)) & -3; + if (width > is->width) { + width = is->width; + height = ((int)rint(width / aspect_ratio)) & -3; + } + x = (is->width - width) / 2; + y = (is->height - height) / 2; + if (!is->no_background) { + /* fill the background */ + // fill_border(is, x, y, width, height, QERGB(0x00, 0x00, 0x00)); + } else { + is->no_background = 0; + } + rect.x = is->xleft + x; + rect.y = is->xleft + y; + rect.w = width; + rect.h = height; + SDL_DisplayYUVOverlay(vp->bmp, &rect); + } else { +#if 0 + fill_rectangle(screen, + is->xleft, is->ytop, is->width, is->height, + QERGB(0x00, 0x00, 0x00)); +#endif + } +} + +static inline int compute_mod(int a, int b) +{ + a = a % b; + if (a >= 0) + return a; + else + return a + b; +} + +static void video_audio_display(VideoState *s) +{ + int i, i_start, x, y1, y, ys, delay, n, nb_display_channels; + int ch, channels, h, h2, bgcolor, fgcolor; + int16_t time_diff; + + /* compute display index : center on currently output samples */ + channels = s->audio_st->codec->channels; + nb_display_channels = channels; + if (!s->paused) { + n = 2 * channels; + delay = audio_write_get_buf_size(s); + delay /= n; + + /* to be more precise, we take into account the time spent since + the last buffer computation */ + if (audio_callback_time) { + time_diff = av_gettime() - audio_callback_time; + delay += (time_diff * s->audio_st->codec->sample_rate) / 1000000; + } + + delay -= s->width / 2; + if (delay < s->width) + delay = s->width; + i_start = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE); + s->last_i_start = i_start; + } else { + i_start = s->last_i_start; + } + + bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); + fill_rectangle(screen, + s->xleft, s->ytop, s->width, s->height, + bgcolor); + + fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff); + + /* total height for one channel */ + h = s->height / nb_display_channels; + /* graph height / 2 */ + h2 = (h * 9) / 20; + for(ch = 0;ch < nb_display_channels; ch++) { + i = i_start + ch; + y1 = s->ytop + ch * h + (h / 2); /* position of center line */ + for(x = 0; x < s->width; x++) { + y = (s->sample_array[i] * h2) >> 15; + if (y < 0) { + y = -y; + ys = y1 - y; + } else { + ys = y1; + } + fill_rectangle(screen, + s->xleft + x, ys, 1, y, + fgcolor); + i += channels; + if (i >= SAMPLE_ARRAY_SIZE) + i -= SAMPLE_ARRAY_SIZE; + } + } + + fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff); + + for(ch = 1;ch < nb_display_channels; ch++) { + y = s->ytop + ch * h; + fill_rectangle(screen, + s->xleft, y, s->width, 1, + fgcolor); + } + SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height); +} + +/* display the current picture, if any */ +static void video_display(VideoState *is) +{ + if (is->audio_st && is->show_audio) + video_audio_display(is); + else if (is->video_st) + video_image_display(is); +} + +static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque) +{ + SDL_Event event; + event.type = FF_REFRESH_EVENT; + event.user.data1 = opaque; + SDL_PushEvent(&event); + return 0; /* 0 means stop timer */ +} + +/* schedule a video refresh in 'delay' ms */ +static void schedule_refresh(VideoState *is, int delay) +{ + SDL_AddTimer(delay, sdl_refresh_timer_cb, is); +} + +/* get the current audio clock value */ +static double get_audio_clock(VideoState *is) +{ + double pts; + int hw_buf_size, bytes_per_sec; + pts = is->audio_clock; + hw_buf_size = audio_write_get_buf_size(is); + bytes_per_sec = 0; + if (is->audio_st) { + bytes_per_sec = is->audio_st->codec->sample_rate * + 2 * is->audio_st->codec->channels; + } + if (bytes_per_sec) + pts -= (double)hw_buf_size / bytes_per_sec; + return pts; +} + +/* get the current video clock value */ +static double get_video_clock(VideoState *is) +{ + double delta; + if (is->paused) { + delta = 0; + } else { + delta = (av_gettime() - is->video_current_pts_time) / 1000000.0; + } + return is->video_current_pts + delta; +} + +/* get the current external clock value */ +static double get_external_clock(VideoState *is) +{ + int64_t ti; + ti = av_gettime(); + return is->external_clock + ((ti - is->external_clock_time) * 1e-6); +} + +/* get the current master clock value */ +static double get_master_clock(VideoState *is) +{ + double val; + + if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) { + if (is->video_st) + val = get_video_clock(is); + else + val = get_audio_clock(is); + } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) { + if (is->audio_st) + val = get_audio_clock(is); + else + val = get_video_clock(is); + } else { + val = get_external_clock(is); + } + return val; +} + +/* seek in the stream */ +static void stream_seek(VideoState *is, int64_t pos, int rel) +{ + if (!is->seek_req) { + is->seek_pos = pos; + is->seek_flags = rel < 0 ? AVSEEK_FLAG_BACKWARD : 0; + is->seek_req = 1; + } +} + +/* pause or resume the video */ +static void stream_pause(VideoState *is) +{ + is->paused = !is->paused; + if (is->paused) { + is->video_current_pts = get_video_clock(is); + } +} + +/* called to display each frame */ +static void video_refresh_timer(void *opaque) +{ + VideoState *is = opaque; + VideoPicture *vp; + double actual_delay, delay, sync_threshold, ref_clock, diff; + + SubPicture *sp, *sp2; + + if (is->video_st) { + if (is->pictq_size == 0) { + /* if no picture, need to wait */ + schedule_refresh(is, 1); + } else { + /* dequeue the picture */ + vp = &is->pictq[is->pictq_rindex]; + + /* update current video pts */ + is->video_current_pts = vp->pts; + is->video_current_pts_time = av_gettime(); + + /* compute nominal delay */ + delay = vp->pts - is->frame_last_pts; + if (delay <= 0 || delay >= 1.0) { + /* if incorrect delay, use previous one */ + delay = is->frame_last_delay; + } + is->frame_last_delay = delay; + is->frame_last_pts = vp->pts; + + /* update delay to follow master synchronisation source */ + if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) || + is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) { + /* if video is slave, we try to correct big delays by + duplicating or deleting a frame */ + ref_clock = get_master_clock(is); + diff = vp->pts - ref_clock; + + /* skip or repeat frame. We take into account the + delay to compute the threshold. I still don't know + if it is the best guess */ + sync_threshold = AV_SYNC_THRESHOLD; + if (delay > sync_threshold) + sync_threshold = delay; + if (fabs(diff) < AV_NOSYNC_THRESHOLD) { + if (diff <= -sync_threshold) + delay = 0; + else if (diff >= sync_threshold) + delay = 2 * delay; + } + } + + is->frame_timer += delay; + /* compute the REAL delay (we need to do that to avoid + long term errors */ + actual_delay = is->frame_timer - (av_gettime() / 1000000.0); + if (actual_delay < 0.010) { + /* XXX: should skip picture */ + actual_delay = 0.010; + } + /* launch timer for next picture */ + schedule_refresh(is, (int)(actual_delay * 1000 + 0.5)); + +#if defined(DEBUG_SYNC) + printf("video: delay=%0.3f actual_delay=%0.3f pts=%0.3f A-V=%f\n", + delay, actual_delay, vp->pts, -diff); +#endif + + if(is->subtitle_st) { + if (is->subtitle_stream_changed) { + SDL_LockMutex(is->subpq_mutex); + + while (is->subpq_size) { + free_subpicture(&is->subpq[is->subpq_rindex]); + + /* update queue size and signal for next picture */ + if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE) + is->subpq_rindex = 0; + + is->subpq_size--; + } + is->subtitle_stream_changed = 0; + + SDL_CondSignal(is->subpq_cond); + SDL_UnlockMutex(is->subpq_mutex); + } else { + if (is->subpq_size > 0) { + sp = &is->subpq[is->subpq_rindex]; + + if (is->subpq_size > 1) + sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE]; + else + sp2 = NULL; + + if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000))) + || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000)))) + { + free_subpicture(sp); + + /* update queue size and signal for next picture */ + if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE) + is->subpq_rindex = 0; + + SDL_LockMutex(is->subpq_mutex); + is->subpq_size--; + SDL_CondSignal(is->subpq_cond); + SDL_UnlockMutex(is->subpq_mutex); + } + } + } + } + + /* display picture */ + video_display(is); + + /* update queue size and signal for next picture */ + if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE) + is->pictq_rindex = 0; + + SDL_LockMutex(is->pictq_mutex); + is->pictq_size--; + SDL_CondSignal(is->pictq_cond); + SDL_UnlockMutex(is->pictq_mutex); + } + } else if (is->audio_st) { + /* draw the next audio frame */ + + schedule_refresh(is, 40); + + /* if only audio stream, then display the audio bars (better + than nothing, just to test the implementation */ + + /* display picture */ + video_display(is); + } else { + schedule_refresh(is, 100); + } + if (show_status) { + static int64_t last_time; + int64_t cur_time; + int aqsize, vqsize, sqsize; + double av_diff; + + cur_time = av_gettime(); + if (!last_time || (cur_time - last_time) >= 500 * 1000) { + aqsize = 0; + vqsize = 0; + sqsize = 0; + if (is->audio_st) + aqsize = is->audioq.size; + if (is->video_st) + vqsize = is->videoq.size; + if (is->subtitle_st) + sqsize = is->subtitleq.size; + av_diff = 0; + if (is->audio_st && is->video_st) + av_diff = get_audio_clock(is) - get_video_clock(is); + printf("%7.2f A-V:%7.3f aq=%5dKB vq=%5dKB sq=%5dB \r", + get_master_clock(is), av_diff, aqsize / 1024, vqsize / 1024, sqsize); + fflush(stdout); + last_time = cur_time; + } + } +} + +/* allocate a picture (needs to do that in main thread to avoid + potential locking problems */ +static void alloc_picture(void *opaque) +{ + VideoState *is = opaque; + VideoPicture *vp; + + vp = &is->pictq[is->pictq_windex]; + + if (vp->bmp) + SDL_FreeYUVOverlay(vp->bmp); + +#if 0 + /* XXX: use generic function */ + /* XXX: disable overlay if no hardware acceleration or if RGB format */ + switch(is->video_st->codec->pix_fmt) { + case PIX_FMT_YUV420P: + case PIX_FMT_YUV422P: + case PIX_FMT_YUV444P: + case PIX_FMT_YUV422: + case PIX_FMT_YUV410P: + case PIX_FMT_YUV411P: + is_yuv = 1; + break; + default: + is_yuv = 0; + break; + } +#endif + vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width, + is->video_st->codec->height, + SDL_YV12_OVERLAY, + screen); + vp->width = is->video_st->codec->width; + vp->height = is->video_st->codec->height; + + SDL_LockMutex(is->pictq_mutex); + vp->allocated = 1; + SDL_CondSignal(is->pictq_cond); + SDL_UnlockMutex(is->pictq_mutex); +} + +/** + * + * @param pts the dts of the pkt / pts of the frame and guessed if not known + */ +static int queue_picture(VideoState *is, AVFrame *src_frame, double pts) +{ + VideoPicture *vp; + int dst_pix_fmt; + AVPicture pict; + + /* wait until we have space to put a new picture */ + SDL_LockMutex(is->pictq_mutex); + while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE && + !is->videoq.abort_request) { + SDL_CondWait(is->pictq_cond, is->pictq_mutex); + } + SDL_UnlockMutex(is->pictq_mutex); + + if (is->videoq.abort_request) + return -1; + + vp = &is->pictq[is->pictq_windex]; + + /* alloc or resize hardware picture buffer */ + if (!vp->bmp || + vp->width != is->video_st->codec->width || + vp->height != is->video_st->codec->height) { + SDL_Event event; + + vp->allocated = 0; + + /* the allocation must be done in the main thread to avoid + locking problems */ + event.type = FF_ALLOC_EVENT; + event.user.data1 = is; + SDL_PushEvent(&event); + + /* wait until the picture is allocated */ + SDL_LockMutex(is->pictq_mutex); + while (!vp->allocated && !is->videoq.abort_request) { + SDL_CondWait(is->pictq_cond, is->pictq_mutex); + } + SDL_UnlockMutex(is->pictq_mutex); + + if (is->videoq.abort_request) + return -1; + } + + /* if the frame is not skipped, then display it */ + if (vp->bmp) { + /* get a pointer on the bitmap */ + SDL_LockYUVOverlay (vp->bmp); + + dst_pix_fmt = PIX_FMT_YUV420P; + pict.data[0] = vp->bmp->pixels[0]; + pict.data[1] = vp->bmp->pixels[2]; + pict.data[2] = vp->bmp->pixels[1]; + + pict.linesize[0] = vp->bmp->pitches[0]; + pict.linesize[1] = vp->bmp->pitches[2]; + pict.linesize[2] = vp->bmp->pitches[1]; + img_convert(&pict, dst_pix_fmt, + (AVPicture *)src_frame, is->video_st->codec->pix_fmt, + is->video_st->codec->width, is->video_st->codec->height); + /* update the bitmap content */ + SDL_UnlockYUVOverlay(vp->bmp); + + vp->pts = pts; + + /* now we can update the picture count */ + if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE) + is->pictq_windex = 0; + SDL_LockMutex(is->pictq_mutex); + is->pictq_size++; + SDL_UnlockMutex(is->pictq_mutex); + } + return 0; +} + +/** + * compute the exact PTS for the picture if it is omitted in the stream + * @param pts1 the dts of the pkt / pts of the frame + */ +static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1) +{ + double frame_delay, pts; + + pts = pts1; + + if (pts != 0) { + /* update video clock with pts, if present */ + is->video_clock = pts; + } else { + pts = is->video_clock; + } + /* update video clock for next frame */ + frame_delay = av_q2d(is->video_st->codec->time_base); + /* for MPEG2, the frame can be repeated, so we update the + clock accordingly */ + frame_delay += src_frame->repeat_pict * (frame_delay * 0.5); + is->video_clock += frame_delay; + +#if defined(DEBUG_SYNC) && 0 + { + int ftype; + if (src_frame->pict_type == FF_B_TYPE) + ftype = 'B'; + else if (src_frame->pict_type == FF_I_TYPE) + ftype = 'I'; + else + ftype = 'P'; + printf("frame_type=%c clock=%0.3f pts=%0.3f\n", + ftype, pts, pts1); + } +#endif + return queue_picture(is, src_frame, pts); +} + +static int video_thread(void *arg) +{ + VideoState *is = arg; + AVPacket pkt1, *pkt = &pkt1; + int len1, got_picture; + AVFrame *frame= avcodec_alloc_frame(); + double pts; + + for(;;) { + while (is->paused && !is->videoq.abort_request) { + SDL_Delay(10); + } + if (packet_queue_get(&is->videoq, pkt, 1) < 0) + break; + /* NOTE: ipts is the PTS of the _first_ picture beginning in + this packet, if any */ + pts = 0; + if (pkt->dts != AV_NOPTS_VALUE) + pts = av_q2d(is->video_st->time_base)*pkt->dts; + + SDL_LockMutex(is->video_decoder_mutex); + len1 = avcodec_decode_video(is->video_st->codec, + frame, &got_picture, + pkt->data, pkt->size); + SDL_UnlockMutex(is->video_decoder_mutex); +// if (len1 < 0) +// break; + if (got_picture) { + if (output_picture2(is, frame, pts) < 0) + goto the_end; + } + av_free_packet(pkt); + if (step) + if (cur_stream) + stream_pause(cur_stream); + } + the_end: + av_free(frame); + return 0; +} + +static int subtitle_thread(void *arg) +{ + VideoState *is = arg; + SubPicture *sp; + AVPacket pkt1, *pkt = &pkt1; + int len1, got_subtitle; + double pts; + int i, j; + int r, g, b, y, u, v, a; + + for(;;) { + while (is->paused && !is->subtitleq.abort_request) { + SDL_Delay(10); + } + if (packet_queue_get(&is->subtitleq, pkt, 1) < 0) + break; + + SDL_LockMutex(is->subpq_mutex); + while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE && + !is->subtitleq.abort_request) { + SDL_CondWait(is->subpq_cond, is->subpq_mutex); + } + SDL_UnlockMutex(is->subpq_mutex); + + if (is->subtitleq.abort_request) + goto the_end; + + sp = &is->subpq[is->subpq_windex]; + + /* NOTE: ipts is the PTS of the _first_ picture beginning in + this packet, if any */ + pts = 0; + if (pkt->pts != AV_NOPTS_VALUE) + pts = av_q2d(is->subtitle_st->time_base)*pkt->pts; + + SDL_LockMutex(is->subtitle_decoder_mutex); + len1 = avcodec_decode_subtitle(is->subtitle_st->codec, + &sp->sub, &got_subtitle, + pkt->data, pkt->size); + SDL_UnlockMutex(is->subtitle_decoder_mutex); +// if (len1 < 0) +// break; + if (got_subtitle && sp->sub.format == 0) { + sp->pts = pts; + + for (i = 0; i < sp->sub.num_rects; i++) + { + for (j = 0; j < sp->sub.rects[i].nb_colors; j++) + { + RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j); + y = RGB_TO_Y_CCIR(r, g, b); + u = RGB_TO_U_CCIR(r, g, b, 0); + v = RGB_TO_V_CCIR(r, g, b, 0); + YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a); + } + } + + /* now we can update the picture count */ + if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE) + is->subpq_windex = 0; + SDL_LockMutex(is->subpq_mutex); + is->subpq_size++; + SDL_UnlockMutex(is->subpq_mutex); + } + av_free_packet(pkt); +// if (step) +// if (cur_stream) +// stream_pause(cur_stream); + } + the_end: + return 0; +} + +/* copy samples for viewing in editor window */ +static void update_sample_display(VideoState *is, short *samples, int samples_size) +{ + int size, len, channels; + + channels = is->audio_st->codec->channels; + + size = samples_size / sizeof(short); + while (size > 0) { + len = SAMPLE_ARRAY_SIZE - is->sample_array_index; + if (len > size) + len = size; + memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short)); + samples += len; + is->sample_array_index += len; + if (is->sample_array_index >= SAMPLE_ARRAY_SIZE) + is->sample_array_index = 0; + size -= len; + } +} + +/* return the new audio buffer size (samples can be added or deleted + to get better sync if video or external master clock) */ +static int synchronize_audio(VideoState *is, short *samples, + int samples_size1, double pts) +{ + int n, samples_size; + double ref_clock; + + n = 2 * is->audio_st->codec->channels; + samples_size = samples_size1; + + /* if not master, then we try to remove or add samples to correct the clock */ + if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) || + is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) { + double diff, avg_diff; + int wanted_size, min_size, max_size, nb_samples; + + ref_clock = get_master_clock(is); + diff = get_audio_clock(is) - ref_clock; + + if (diff < AV_NOSYNC_THRESHOLD) { + is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum; + if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) { + /* not enough measures to have a correct estimate */ + is->audio_diff_avg_count++; + } else { + /* estimate the A-V difference */ + avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef); + + if (fabs(avg_diff) >= is->audio_diff_threshold) { + wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n); + nb_samples = samples_size / n; + + min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n; + max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n; + if (wanted_size < min_size) + wanted_size = min_size; + else if (wanted_size > max_size) + wanted_size = max_size; + + /* add or remove samples to correction the synchro */ + if (wanted_size < samples_size) { + /* remove samples */ + samples_size = wanted_size; + } else if (wanted_size > samples_size) { + uint8_t *samples_end, *q; + int nb; + + /* add samples */ + nb = (samples_size - wanted_size); + samples_end = (uint8_t *)samples + samples_size - n; + q = samples_end + n; + while (nb > 0) { + memcpy(q, samples_end, n); + q += n; + nb -= n; + } + samples_size = wanted_size; + } + } +#if 0 + printf("diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n", + diff, avg_diff, samples_size - samples_size1, + is->audio_clock, is->video_clock, is->audio_diff_threshold); +#endif + } + } else { + /* too big difference : may be initial PTS errors, so + reset A-V filter */ + is->audio_diff_avg_count = 0; + is->audio_diff_cum = 0; + } + } + + return samples_size; +} + +/* decode one audio frame and returns its uncompressed size */ +static int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr) +{ + AVPacket *pkt = &is->audio_pkt; + int n, len1, data_size; + double pts; + + for(;;) { + /* NOTE: the audio packet can contain several frames */ + while (is->audio_pkt_size > 0) { + SDL_LockMutex(is->audio_decoder_mutex); + len1 = avcodec_decode_audio(is->audio_st->codec, + (int16_t *)audio_buf, &data_size, + is->audio_pkt_data, is->audio_pkt_size); + SDL_UnlockMutex(is->audio_decoder_mutex); + if (len1 < 0) { + /* if error, we skip the frame */ + is->audio_pkt_size = 0; + break; + } + + is->audio_pkt_data += len1; + is->audio_pkt_size -= len1; + if (data_size <= 0) + continue; + /* if no pts, then compute it */ + pts = is->audio_clock; + *pts_ptr = pts; + n = 2 * is->audio_st->codec->channels; + is->audio_clock += (double)data_size / + (double)(n * is->audio_st->codec->sample_rate); +#if defined(DEBUG_SYNC) + { + static double last_clock; + printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n", + is->audio_clock - last_clock, + is->audio_clock, pts); + last_clock = is->audio_clock; + } +#endif + return data_size; + } + + /* free the current packet */ + if (pkt->data) + av_free_packet(pkt); + + if (is->paused || is->audioq.abort_request) { + return -1; + } + + /* read next packet */ + if (packet_queue_get(&is->audioq, pkt, 1) < 0) + return -1; + is->audio_pkt_data = pkt->data; + is->audio_pkt_size = pkt->size; + + /* if update the audio clock with the pts */ + if (pkt->pts != AV_NOPTS_VALUE) { + is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts; + } + } +} + +/* get the current audio output buffer size, in samples. With SDL, we + cannot have a precise information */ +static int audio_write_get_buf_size(VideoState *is) +{ + return is->audio_hw_buf_size - is->audio_buf_index; +} + + +/* prepare a new audio buffer */ +void sdl_audio_callback(void *opaque, Uint8 *stream, int len) +{ + VideoState *is = opaque; + int audio_size, len1; + double pts; + + audio_callback_time = av_gettime(); + + while (len > 0) { + if (is->audio_buf_index >= is->audio_buf_size) { + audio_size = audio_decode_frame(is, is->audio_buf, &pts); + if (audio_size < 0) { + /* if error, just output silence */ + is->audio_buf_size = 1024; + memset(is->audio_buf, 0, is->audio_buf_size); + } else { + if (is->show_audio) + update_sample_display(is, (int16_t *)is->audio_buf, audio_size); + audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size, + pts); + is->audio_buf_size = audio_size; + } + is->audio_buf_index = 0; + } + len1 = is->audio_buf_size - is->audio_buf_index; + if (len1 > len) + len1 = len; + memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1); + len -= len1; + stream += len1; + is->audio_buf_index += len1; + } +} + + +/* open a given stream. Return 0 if OK */ +static int stream_component_open(VideoState *is, int stream_index) +{ + AVFormatContext *ic = is->ic; + AVCodecContext *enc; + AVCodec *codec; + SDL_AudioSpec wanted_spec, spec; + + if (stream_index < 0 || stream_index >= ic->nb_streams) + return -1; + enc = ic->streams[stream_index]->codec; + + /* prepare audio output */ + if (enc->codec_type == CODEC_TYPE_AUDIO) { + wanted_spec.freq = enc->sample_rate; + wanted_spec.format = AUDIO_S16SYS; + /* hack for AC3. XXX: suppress that */ + if (enc->channels > 2) + enc->channels = 2; + wanted_spec.channels = enc->channels; + wanted_spec.silence = 0; + wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE; + wanted_spec.callback = sdl_audio_callback; + wanted_spec.userdata = is; + if (SDL_OpenAudio(&wanted_spec, &spec) < 0) { + fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError()); + return -1; + } + is->audio_hw_buf_size = spec.size; + } + + codec = avcodec_find_decoder(enc->codec_id); + enc->debug_mv = debug_mv; + enc->debug = debug; + if(debug) + av_log_set_level(AV_LOG_DEBUG); + enc->workaround_bugs = workaround_bugs; + enc->lowres = lowres; + if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE; + enc->idct_algo= idct; + if(fast) enc->flags2 |= CODEC_FLAG2_FAST; + enc->skip_frame= skip_frame; + enc->skip_idct= skip_idct; + enc->skip_loop_filter= skip_loop_filter; + enc->error_resilience= error_resilience; + enc->error_concealment= error_concealment; + if (!codec || + avcodec_open(enc, codec) < 0) + return -1; +#if defined(HAVE_THREADS) + if(thread_count>1) + avcodec_thread_init(enc, thread_count); +#endif + enc->thread_count= thread_count; + switch(enc->codec_type) { + case CODEC_TYPE_AUDIO: + is->audio_stream = stream_index; + is->audio_st = ic->streams[stream_index]; + is->audio_buf_size = 0; + is->audio_buf_index = 0; + + /* init averaging filter */ + is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB); + is->audio_diff_avg_count = 0; + /* since we do not have a precise anough audio fifo fullness, + we correct audio sync only if larger than this threshold */ + is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate; + + memset(&is->audio_pkt, 0, sizeof(is->audio_pkt)); + packet_queue_init(&is->audioq); + SDL_PauseAudio(0); + break; + case CODEC_TYPE_VIDEO: + is->video_stream = stream_index; + is->video_st = ic->streams[stream_index]; + + is->frame_last_delay = 40e-3; + is->frame_timer = (double)av_gettime() / 1000000.0; + is->video_current_pts_time = av_gettime(); + + packet_queue_init(&is->videoq); + is->video_tid = SDL_CreateThread(video_thread, is); + break; + case CODEC_TYPE_SUBTITLE: + is->subtitle_stream = stream_index; + is->subtitle_st = ic->streams[stream_index]; + packet_queue_init(&is->subtitleq); + + is->subtitle_tid = SDL_CreateThread(subtitle_thread, is); + break; + default: + break; + } + return 0; +} + +static void stream_component_close(VideoState *is, int stream_index) +{ + AVFormatContext *ic = is->ic; + AVCodecContext *enc; + + if (stream_index < 0 || stream_index >= ic->nb_streams) + return; + enc = ic->streams[stream_index]->codec; + + switch(enc->codec_type) { + case CODEC_TYPE_AUDIO: + packet_queue_abort(&is->audioq); + + SDL_CloseAudio(); + + packet_queue_end(&is->audioq); + break; + case CODEC_TYPE_VIDEO: + packet_queue_abort(&is->videoq); + + /* note: we also signal this mutex to make sure we deblock the + video thread in all cases */ + SDL_LockMutex(is->pictq_mutex); + SDL_CondSignal(is->pictq_cond); + SDL_UnlockMutex(is->pictq_mutex); + + SDL_WaitThread(is->video_tid, NULL); + + packet_queue_end(&is->videoq); + break; + case CODEC_TYPE_SUBTITLE: + packet_queue_abort(&is->subtitleq); + + /* note: we also signal this mutex to make sure we deblock the + video thread in all cases */ + SDL_LockMutex(is->subpq_mutex); + is->subtitle_stream_changed = 1; + + SDL_CondSignal(is->subpq_cond); + SDL_UnlockMutex(is->subpq_mutex); + + SDL_WaitThread(is->subtitle_tid, NULL); + + packet_queue_end(&is->subtitleq); + break; + default: + break; + } + + avcodec_close(enc); + switch(enc->codec_type) { + case CODEC_TYPE_AUDIO: + is->audio_st = NULL; + is->audio_stream = -1; + break; + case CODEC_TYPE_VIDEO: + is->video_st = NULL; + is->video_stream = -1; + break; + case CODEC_TYPE_SUBTITLE: + is->subtitle_st = NULL; + is->subtitle_stream = -1; + break; + default: + break; + } +} + +void dump_stream_info(AVFormatContext *s) +{ + if (s->track != 0) + fprintf(stderr, "Track: %d\n", s->track); + if (s->title[0] != '\0') + fprintf(stderr, "Title: %s\n", s->title); + if (s->author[0] != '\0') + fprintf(stderr, "Author: %s\n", s->author); + if (s->album[0] != '\0') + fprintf(stderr, "Album: %s\n", s->album); + if (s->year != 0) + fprintf(stderr, "Year: %d\n", s->year); + if (s->genre[0] != '\0') + fprintf(stderr, "Genre: %s\n", s->genre); +} + +/* since we have only one decoding thread, we can use a global + variable instead of a thread local variable */ +static VideoState *global_video_state; + +static int decode_interrupt_cb(void) +{ + return (global_video_state && global_video_state->abort_request); +} + +/* this thread gets the stream from the disk or the network */ +static int decode_thread(void *arg) +{ + VideoState *is = arg; + AVFormatContext *ic; + int err, i, ret, video_index, audio_index, use_play; + AVPacket pkt1, *pkt = &pkt1; + AVFormatParameters params, *ap = ¶ms; + + video_index = -1; + audio_index = -1; + is->video_stream = -1; + is->audio_stream = -1; + is->subtitle_stream = -1; + + global_video_state = is; + url_set_interrupt_cb(decode_interrupt_cb); + + memset(ap, 0, sizeof(*ap)); + ap->image_format = image_format; + ap->initial_pause = 1; /* we force a pause when starting an RTSP + stream */ + + err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap); + if (err < 0) { + print_error(is->filename, err); + ret = -1; + goto fail; + } + is->ic = ic; +#ifdef CONFIG_NETWORK + use_play = (ic->iformat == &rtsp_demux); +#else + use_play = 0; +#endif + + if(genpts) + ic->flags |= AVFMT_FLAG_GENPTS; + + if (!use_play) { + err = av_find_stream_info(ic); + if (err < 0) { + fprintf(stderr, "%s: could not find codec parameters\n", is->filename); + ret = -1; + goto fail; + } + ic->pb.eof_reached= 0; //FIXME hack, ffplay maybe shouldnt use url_feof() to test for the end + } + + /* if seeking requested, we execute it */ + if (start_time != AV_NOPTS_VALUE) { + int64_t timestamp; + + timestamp = start_time; + /* add the stream start time */ + if (ic->start_time != AV_NOPTS_VALUE) + timestamp += ic->start_time; + ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD); + if (ret < 0) { + fprintf(stderr, "%s: could not seek to position %0.3f\n", + is->filename, (double)timestamp / AV_TIME_BASE); + } + } + + /* now we can begin to play (RTSP stream only) */ + av_read_play(ic); + + if (use_play) { + err = av_find_stream_info(ic); + if (err < 0) { + fprintf(stderr, "%s: could not find codec parameters\n", is->filename); + ret = -1; + goto fail; + } + } + + for(i = 0; i < ic->nb_streams; i++) { + AVCodecContext *enc = ic->streams[i]->codec; + switch(enc->codec_type) { + case CODEC_TYPE_AUDIO: + if (audio_index < 0 && !audio_disable) + audio_index = i; + break; + case CODEC_TYPE_VIDEO: + if (video_index < 0 && !video_disable) + video_index = i; + break; + default: + break; + } + } + if (show_status) { + dump_format(ic, 0, is->filename, 0); + dump_stream_info(ic); + } + + /* open the streams */ + if (audio_index >= 0) { + stream_component_open(is, audio_index); + } + + if (video_index >= 0) { + stream_component_open(is, video_index); + } else { + if (!display_disable) + is->show_audio = 1; + } + + if (is->video_stream < 0 && is->audio_stream < 0) { + fprintf(stderr, "%s: could not open codecs\n", is->filename); + ret = -1; + goto fail; + } + + for(;;) { + if (is->abort_request) + break; +#ifdef CONFIG_NETWORK + if (is->paused != is->last_paused) { + is->last_paused = is->paused; + if (is->paused) + av_read_pause(ic); + else + av_read_play(ic); + } + if (is->paused && ic->iformat == &rtsp_demux) { + /* wait 10 ms to avoid trying to get another packet */ + /* XXX: horrible */ + SDL_Delay(10); + continue; + } +#endif + if (is->seek_req) { + /* XXX: must lock decoder threads */ + SDL_LockMutex(is->video_decoder_mutex); + SDL_LockMutex(is->audio_decoder_mutex); + SDL_LockMutex(is->subtitle_decoder_mutex); + ret = av_seek_frame(is->ic, -1, is->seek_pos, is->seek_flags); + if (ret < 0) { + fprintf(stderr, "%s: error while seeking\n", is->ic->filename); + }else{ + if (is->audio_stream >= 0) { + packet_queue_flush(&is->audioq); + } + if (is->subtitle_stream >= 0) { + packet_queue_flush(&is->subtitleq); + } + if (is->video_stream >= 0) { + packet_queue_flush(&is->videoq); + avcodec_flush_buffers(ic->streams[video_index]->codec); + } + } + SDL_UnlockMutex(is->subtitle_decoder_mutex); + SDL_UnlockMutex(is->audio_decoder_mutex); + SDL_UnlockMutex(is->video_decoder_mutex); + is->seek_req = 0; + } + + /* if the queue are full, no need to read more */ + if (is->audioq.size > MAX_AUDIOQ_SIZE || + is->videoq.size > MAX_VIDEOQ_SIZE || + is->subtitleq.size > MAX_SUBTITLEQ_SIZE || + url_feof(&ic->pb)) { + /* wait 10 ms */ + SDL_Delay(10); + continue; + } + ret = av_read_frame(ic, pkt); + if (ret < 0) { + if (url_ferror(&ic->pb) == 0) { + SDL_Delay(100); /* wait for user event */ + continue; + } else + break; + } + if (pkt->stream_index == is->audio_stream) { + packet_queue_put(&is->audioq, pkt); + } else if (pkt->stream_index == is->video_stream) { + packet_queue_put(&is->videoq, pkt); + } else if (pkt->stream_index == is->subtitle_stream) { + packet_queue_put(&is->subtitleq, pkt); + } else { + av_free_packet(pkt); + } + } + /* wait until the end */ + while (!is->abort_request) { + SDL_Delay(100); + } + + ret = 0; + fail: + /* disable interrupting */ + global_video_state = NULL; + + /* close each stream */ + if (is->audio_stream >= 0) + stream_component_close(is, is->audio_stream); + if (is->video_stream >= 0) + stream_component_close(is, is->video_stream); + if (is->subtitle_stream >= 0) + stream_component_close(is, is->subtitle_stream); + if (is->ic) { + av_close_input_file(is->ic); + is->ic = NULL; /* safety */ + } + url_set_interrupt_cb(NULL); + + if (ret != 0) { + SDL_Event event; + + event.type = FF_QUIT_EVENT; + event.user.data1 = is; + SDL_PushEvent(&event); + } + return 0; +} + +static VideoState *stream_open(const char *filename, AVInputFormat *iformat) +{ + VideoState *is; + + is = av_mallocz(sizeof(VideoState)); + if (!is) + return NULL; + pstrcpy(is->filename, sizeof(is->filename), filename); + is->iformat = iformat; + if (screen) { + is->width = screen->w; + is->height = screen->h; + } + is->ytop = 0; + is->xleft = 0; + + /* start video display */ + is->pictq_mutex = SDL_CreateMutex(); + is->pictq_cond = SDL_CreateCond(); + + is->subpq_mutex = SDL_CreateMutex(); + is->subpq_cond = SDL_CreateCond(); + + is->subtitle_decoder_mutex = SDL_CreateMutex(); + is->audio_decoder_mutex = SDL_CreateMutex(); + is->video_decoder_mutex = SDL_CreateMutex(); + + /* add the refresh timer to draw the picture */ + schedule_refresh(is, 40); + + is->av_sync_type = av_sync_type; + is->parse_tid = SDL_CreateThread(decode_thread, is); + if (!is->parse_tid) { + av_free(is); + return NULL; + } + return is; +} + +static void stream_close(VideoState *is) +{ + VideoPicture *vp; + int i; + /* XXX: use a special url_shutdown call to abort parse cleanly */ + is->abort_request = 1; + SDL_WaitThread(is->parse_tid, NULL); + + /* free all pictures */ + for(i=0;ipictq[i]; + if (vp->bmp) { + SDL_FreeYUVOverlay(vp->bmp); + vp->bmp = NULL; + } + } + SDL_DestroyMutex(is->pictq_mutex); + SDL_DestroyCond(is->pictq_cond); + SDL_DestroyMutex(is->subpq_mutex); + SDL_DestroyCond(is->subpq_cond); + SDL_DestroyMutex(is->subtitle_decoder_mutex); + SDL_DestroyMutex(is->audio_decoder_mutex); + SDL_DestroyMutex(is->video_decoder_mutex); +} + +void stream_cycle_channel(VideoState *is, int codec_type) +{ + AVFormatContext *ic = is->ic; + int start_index, stream_index; + AVStream *st; + + if (codec_type == CODEC_TYPE_VIDEO) + start_index = is->video_stream; + else if (codec_type == CODEC_TYPE_AUDIO) + start_index = is->audio_stream; + else + start_index = is->subtitle_stream; + if (start_index < (codec_type == CODEC_TYPE_SUBTITLE ? -1 : 0)) + return; + stream_index = start_index; + for(;;) { + if (++stream_index >= is->ic->nb_streams) + { + if (codec_type == CODEC_TYPE_SUBTITLE) + { + stream_index = -1; + goto the_end; + } else + stream_index = 0; + } + if (stream_index == start_index) + return; + st = ic->streams[stream_index]; + if (st->codec->codec_type == codec_type) { + /* check that parameters are OK */ + switch(codec_type) { + case CODEC_TYPE_AUDIO: + if (st->codec->sample_rate != 0 && + st->codec->channels != 0) + goto the_end; + break; + case CODEC_TYPE_VIDEO: + case CODEC_TYPE_SUBTITLE: + goto the_end; + default: + break; + } + } + } + the_end: + stream_component_close(is, start_index); + stream_component_open(is, stream_index); +} + + +void toggle_full_screen(void) +{ + int w, h, flags; + is_full_screen = !is_full_screen; + if (!fs_screen_width) { + /* use default SDL method */ + SDL_WM_ToggleFullScreen(screen); + } else { + /* use the recorded resolution */ + flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL; + if (is_full_screen) { + w = fs_screen_width; + h = fs_screen_height; + flags |= SDL_FULLSCREEN; + } else { + w = screen_width; + h = screen_height; + flags |= SDL_RESIZABLE; + } + screen = SDL_SetVideoMode(w, h, 0, flags); + cur_stream->width = w; + cur_stream->height = h; + } +} + +void toggle_pause(void) +{ + if (cur_stream) + stream_pause(cur_stream); + step = 0; +} + +void step_to_next_frame(void) +{ + if (cur_stream) { + if (cur_stream->paused) + cur_stream->paused=0; + cur_stream->video_current_pts = get_video_clock(cur_stream); + } + step = 1; +} + +void do_exit(void) +{ + if (cur_stream) { + stream_close(cur_stream); + cur_stream = NULL; + } + if (show_status) + printf("\n"); + SDL_Quit(); + exit(0); +} + +void toggle_audio_display(void) +{ + if (cur_stream) { + cur_stream->show_audio = !cur_stream->show_audio; + } +} + +/* handle an event sent by the GUI */ +void event_loop(void) +{ + SDL_Event event; + double incr, pos, frac; + + for(;;) { + SDL_WaitEvent(&event); + switch(event.type) { + case SDL_KEYDOWN: + switch(event.key.keysym.sym) { + case SDLK_ESCAPE: + case SDLK_q: + do_exit(); + break; + case SDLK_f: + toggle_full_screen(); + break; + case SDLK_p: + case SDLK_SPACE: + toggle_pause(); + break; + case SDLK_s: //S: Step to next frame + step_to_next_frame(); + break; + case SDLK_a: + if (cur_stream) + stream_cycle_channel(cur_stream, CODEC_TYPE_AUDIO); + break; + case SDLK_v: + if (cur_stream) + stream_cycle_channel(cur_stream, CODEC_TYPE_VIDEO); + break; + case SDLK_t: + if (cur_stream) + stream_cycle_channel(cur_stream, CODEC_TYPE_SUBTITLE); + break; + case SDLK_w: + toggle_audio_display(); + break; + case SDLK_LEFT: + incr = -10.0; + goto do_seek; + case SDLK_RIGHT: + incr = 10.0; + goto do_seek; + case SDLK_UP: + incr = 60.0; + goto do_seek; + case SDLK_DOWN: + incr = -60.0; + do_seek: + if (cur_stream) { + pos = get_master_clock(cur_stream); + pos += incr; + stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), incr); + } + break; + default: + break; + } + break; + case SDL_MOUSEBUTTONDOWN: + if (cur_stream) { + int ns, hh, mm, ss; + int tns, thh, tmm, tss; + tns = cur_stream->ic->duration/1000000LL; + thh = tns/3600; + tmm = (tns%3600)/60; + tss = (tns%60); + frac = (double)event.button.x/(double)cur_stream->width; + ns = frac*tns; + hh = ns/3600; + mm = (ns%3600)/60; + ss = (ns%60); + fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100, + hh, mm, ss, thh, tmm, tss); + stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0); + } + break; + case SDL_VIDEORESIZE: + if (cur_stream) { + screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0, + SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL); + cur_stream->width = event.resize.w; + cur_stream->height = event.resize.h; + } + break; + case SDL_QUIT: + case FF_QUIT_EVENT: + do_exit(); + break; + case FF_ALLOC_EVENT: + alloc_picture(event.user.data1); + break; + case FF_REFRESH_EVENT: + video_refresh_timer(event.user.data1); + break; + default: + break; + } + } +} + +void opt_width(const char *arg) +{ + screen_width = atoi(arg); +} + +void opt_height(const char *arg) +{ + screen_height = atoi(arg); +} + +static void opt_format(const char *arg) +{ + file_iformat = av_find_input_format(arg); + if (!file_iformat) { + fprintf(stderr, "Unknown input format: %s\n", arg); + exit(1); + } +} + +static void opt_image_format(const char *arg) +{ + AVImageFormat *f; + + for(f = first_image_format; f != NULL; f = f->next) { + if (!strcmp(arg, f->name)) + break; + } + if (!f) { + fprintf(stderr, "Unknown image format: '%s'\n", arg); + exit(1); + } + image_format = f; +} + +#ifdef CONFIG_NETWORK +void opt_rtp_tcp(void) +{ + /* only tcp protocol */ + rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP); +} +#endif + +void opt_sync(const char *arg) +{ + if (!strcmp(arg, "audio")) + av_sync_type = AV_SYNC_AUDIO_MASTER; + else if (!strcmp(arg, "video")) + av_sync_type = AV_SYNC_VIDEO_MASTER; + else if (!strcmp(arg, "ext")) + av_sync_type = AV_SYNC_EXTERNAL_CLOCK; + else + show_help(); +} + +void opt_seek(const char *arg) +{ + start_time = parse_date(arg, 1); +} + +static void opt_debug(const char *arg) +{ + debug = atoi(arg); +} + +static void opt_vismv(const char *arg) +{ + debug_mv = atoi(arg); +} + +static void opt_thread_count(const char *arg) +{ + thread_count= atoi(arg); +#if !defined(HAVE_THREADS) + fprintf(stderr, "Warning: not compiled with thread support, using thread emulation\n"); +#endif +} + +const OptionDef options[] = { + { "h", 0, {(void*)show_help}, "show help" }, + { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" }, + { "y", HAS_ARG, {(void*)opt_height}, "force displayed height", "height" }, +#if 0 + /* disabled as SDL/X11 does not support it correctly on application launch */ + { "fs", OPT_BOOL, {(void*)&is_full_screen}, "force full screen" }, +#endif + { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" }, + { "vn", OPT_BOOL, {(void*)&video_disable}, "disable video" }, + { "ss", HAS_ARG, {(void*)&opt_seek}, "seek to a given position in seconds", "pos" }, + { "nodisp", OPT_BOOL, {(void*)&display_disable}, "disable graphical display" }, + { "f", HAS_ARG, {(void*)opt_format}, "force format", "fmt" }, + { "img", HAS_ARG, {(void*)opt_image_format}, "force image format", "img_fmt" }, + { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" }, + { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" }, + { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&workaround_bugs}, "workaround bugs", "" }, + { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" }, + { "fast", OPT_BOOL | OPT_EXPERT, {(void*)&fast}, "non spec compliant optimizations", "" }, + { "genpts", OPT_BOOL | OPT_EXPERT, {(void*)&genpts}, "generate pts", "" }, + { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&lowres}, "", "" }, + { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_loop_filter}, "", "" }, + { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_frame}, "", "" }, + { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&skip_idct}, "", "" }, + { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&idct}, "set idct algo", "algo" }, + { "er", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_resilience}, "set error detection threshold (0-4)", "threshold" }, + { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" }, +#ifdef CONFIG_NETWORK + { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" }, +#endif + { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" }, + { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" }, + { NULL, }, +}; + +void show_help(void) +{ + printf("ffplay version " FFMPEG_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" + "usage: ffplay [options] input_file\n" + "Simple media player\n"); + printf("\n"); + show_help_options(options, "Main options:\n", + OPT_EXPERT, 0); + show_help_options(options, "\nAdvanced options:\n", + OPT_EXPERT, OPT_EXPERT); + printf("\nWhile playing:\n" + "q, ESC quit\n" + "f toggle full screen\n" + "p, SPC pause\n" + "a cycle audio channel\n" + "v cycle video channel\n" + "t cycle subtitle channel\n" + "w show audio waves\n" + "left/right seek backward/forward 10 seconds\n" + "down/up seek backward/forward 1 minute\n" + "mouse click seek to percentage in file corresponding to fraction of width\n" + ); + exit(1); +} + +void parse_arg_file(const char *filename) +{ + if (!strcmp(filename, "-")) + filename = "pipe:"; + input_filename = filename; +} + +/* Called from the main */ +int main(int argc, char **argv) +{ + int flags, w, h; + + /* register all codecs, demux and protocols */ + av_register_all(); + + #ifdef CONFIG_OS2 + MorphToPM(); // Morph the VIO application to a PM one to be able to use Win* functions + + // Make stdout and stderr unbuffered + setbuf( stdout, NULL ); + setbuf( stderr, NULL ); + #endif + + parse_options(argc, argv, options); + + if (!input_filename) + show_help(); + + if (display_disable) { + video_disable = 1; + } + flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER; +#ifndef CONFIG_WIN32 + flags |= SDL_INIT_EVENTTHREAD; /* Not supported on win32 */ +#endif + if (SDL_Init (flags)) { + fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); + exit(1); + } + + if (!display_disable) { +#ifdef HAVE_X11 + /* save the screen resolution... SDL should allow full screen + by resizing the window */ + { + Display *dpy; + dpy = XOpenDisplay(NULL); + if (dpy) { + fs_screen_width = DisplayWidth(dpy, DefaultScreen(dpy)); + fs_screen_height = DisplayHeight(dpy, DefaultScreen(dpy)); + XCloseDisplay(dpy); + } + } +#endif + flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL; + if (is_full_screen && fs_screen_width) { + w = fs_screen_width; + h = fs_screen_height; + flags |= SDL_FULLSCREEN; + } else { + w = screen_width; + h = screen_height; + flags |= SDL_RESIZABLE; + } + screen = SDL_SetVideoMode(w, h, 0, flags); + if (!screen) { + fprintf(stderr, "SDL: could not set video mode - exiting\n"); + exit(1); + } + SDL_WM_SetCaption("FFplay", "FFplay"); + } + + SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); + SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); + SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); + SDL_EventState(SDL_USEREVENT, SDL_IGNORE); + + cur_stream = stream_open(input_filename, file_iformat); + + event_loop(); + + /* never returns */ + + return 0; +} diff --git a/mpeg4/src/ffserver.c b/mpeg4/src/ffserver.c new file mode 100644 index 00000000..e31a0270 --- /dev/null +++ b/mpeg4/src/ffserver.c @@ -0,0 +1,4599 @@ +/* + * Multiple format streaming server + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#define HAVE_AV_CONFIG_H +#include "avformat.h" + +#include +#include +#include +#include +#include +#include +#include +#undef time //needed because HAVE_AV_CONFIG_H is defined on top +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAVE_DLFCN +#include +#endif + +#include "ffserver.h" + +/* maximum number of simultaneous HTTP connections */ +#define HTTP_MAX_CONNECTIONS 2000 + +enum HTTPState { + HTTPSTATE_WAIT_REQUEST, + HTTPSTATE_SEND_HEADER, + HTTPSTATE_SEND_DATA_HEADER, + HTTPSTATE_SEND_DATA, /* sending TCP or UDP data */ + HTTPSTATE_SEND_DATA_TRAILER, + HTTPSTATE_RECEIVE_DATA, + HTTPSTATE_WAIT_FEED, /* wait for data from the feed */ + HTTPSTATE_READY, + + RTSPSTATE_WAIT_REQUEST, + RTSPSTATE_SEND_REPLY, + RTSPSTATE_SEND_PACKET, +}; + +const char *http_state[] = { + "HTTP_WAIT_REQUEST", + "HTTP_SEND_HEADER", + + "SEND_DATA_HEADER", + "SEND_DATA", + "SEND_DATA_TRAILER", + "RECEIVE_DATA", + "WAIT_FEED", + "READY", + + "RTSP_WAIT_REQUEST", + "RTSP_SEND_REPLY", + "RTSP_SEND_PACKET", +}; + +#define IOBUFFER_INIT_SIZE 8192 + +/* coef for exponential mean for bitrate estimation in statistics */ +#define AVG_COEF 0.9 + +/* timeouts are in ms */ +#define HTTP_REQUEST_TIMEOUT (15 * 1000) +#define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000) + +#define SYNC_TIMEOUT (10 * 1000) + +typedef struct { + int64_t count1, count2; + long time1, time2; +} DataRateData; + +/* context associated with one connection */ +typedef struct HTTPContext { + enum HTTPState state; + int fd; /* socket file descriptor */ + struct sockaddr_in from_addr; /* origin */ + struct pollfd *poll_entry; /* used when polling */ + long timeout; + uint8_t *buffer_ptr, *buffer_end; + int http_error; + int post; + struct HTTPContext *next; + int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */ + int64_t data_count; + /* feed input */ + int feed_fd; + /* input format handling */ + AVFormatContext *fmt_in; + long start_time; /* In milliseconds - this wraps fairly often */ + int64_t first_pts; /* initial pts value */ + int64_t cur_pts; /* current pts value from the stream in us */ + int64_t cur_frame_duration; /* duration of the current frame in us */ + int cur_frame_bytes; /* output frame size, needed to compute + the time at which we send each + packet */ + int pts_stream_index; /* stream we choose as clock reference */ + int64_t cur_clock; /* current clock reference value in us */ + /* output format handling */ + struct FFStream *stream; + /* -1 is invalid stream */ + int feed_streams[MAX_STREAMS]; /* index of streams in the feed */ + int switch_feed_streams[MAX_STREAMS]; /* index of streams in the feed */ + int switch_pending; + AVFormatContext fmt_ctx; /* instance of FFStream for one user */ + int last_packet_sent; /* true if last data packet was sent */ + int suppress_log; + DataRateData datarate; + int wmp_client_id; + char protocol[16]; + char method[16]; + char url[128]; + int buffer_size; + uint8_t *buffer; + int is_packetized; /* if true, the stream is packetized */ + int packet_stream_index; /* current stream for output in state machine */ + + /* RTSP state specific */ + uint8_t *pb_buffer; /* XXX: use that in all the code */ + ByteIOContext *pb; + int seq; /* RTSP sequence number */ + + /* RTP state specific */ + enum RTSPProtocol rtp_protocol; + char session_id[32]; /* session id */ + AVFormatContext *rtp_ctx[MAX_STREAMS]; + + /* RTP/UDP specific */ + URLContext *rtp_handles[MAX_STREAMS]; + + /* RTP/TCP specific */ + struct HTTPContext *rtsp_c; + uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end; +} HTTPContext; + +static AVFrame dummy_frame; + +/* each generated stream is described here */ +enum StreamType { + STREAM_TYPE_LIVE, + STREAM_TYPE_STATUS, + STREAM_TYPE_REDIRECT, +}; + +enum IPAddressAction { + IP_ALLOW = 1, + IP_DENY, +}; + +typedef struct IPAddressACL { + struct IPAddressACL *next; + enum IPAddressAction action; + /* These are in host order */ + struct in_addr first; + struct in_addr last; +} IPAddressACL; + +/* description of each stream of the ffserver.conf file */ +typedef struct FFStream { + enum StreamType stream_type; + char filename[1024]; /* stream filename */ + struct FFStream *feed; /* feed we are using (can be null if + coming from file) */ + AVFormatParameters *ap_in; /* input parameters */ + AVInputFormat *ifmt; /* if non NULL, force input format */ + AVOutputFormat *fmt; + IPAddressACL *acl; + int nb_streams; + int prebuffer; /* Number of millseconds early to start */ + long max_time; /* Number of milliseconds to run */ + int send_on_key; + AVStream *streams[MAX_STREAMS]; + int feed_streams[MAX_STREAMS]; /* index of streams in the feed */ + char feed_filename[1024]; /* file name of the feed storage, or + input file name for a stream */ + char author[512]; + char title[512]; + char copyright[512]; + char comment[512]; + pid_t pid; /* Of ffmpeg process */ + time_t pid_start; /* Of ffmpeg process */ + char **child_argv; + struct FFStream *next; + int bandwidth; /* bandwidth, in kbits/s */ + /* RTSP options */ + char *rtsp_option; + /* multicast specific */ + int is_multicast; + struct in_addr multicast_ip; + int multicast_port; /* first port used for multicast */ + int multicast_ttl; + int loop; /* if true, send the stream in loops (only meaningful if file) */ + + /* feed specific */ + int feed_opened; /* true if someone is writing to the feed */ + int is_feed; /* true if it is a feed */ + int readonly; /* True if writing is prohibited to the file */ + int conns_served; + int64_t bytes_served; + int64_t feed_max_size; /* maximum storage size, zero means unlimited */ + int64_t feed_write_index; /* current write position in feed (it wraps round) */ + int64_t feed_size; /* current size of feed */ + struct FFStream *next_feed; +} FFStream; + +typedef struct FeedData { + long long data_count; + float avg_frame_size; /* frame size averraged over last frames with exponential mean */ +} FeedData; + +struct sockaddr_in my_http_addr; +struct sockaddr_in my_rtsp_addr; + +static char logfilename[1024]; +static HTTPContext *first_http_ctx; +static FFStream *first_feed; /* contains only feeds */ +static FFStream *first_stream; /* contains all streams, including feeds */ + +static void new_connection(int server_fd, int is_rtsp); +static void close_connection(HTTPContext *c); + +/* HTTP handling */ +static int handle_connection(HTTPContext *c); +static int http_parse_request(HTTPContext *c); +static int http_send_data(HTTPContext *c); +static void compute_stats(HTTPContext *c); +static int open_input_stream(HTTPContext *c, const char *info); +static int http_start_receive_data(HTTPContext *c); +static int http_receive_data(HTTPContext *c); + +/* RTSP handling */ +static int rtsp_parse_request(HTTPContext *c); +static void rtsp_cmd_describe(HTTPContext *c, const char *url); +static void rtsp_cmd_options(HTTPContext *c, const char *url); +static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPHeader *h); +static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPHeader *h); +static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPHeader *h); +static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPHeader *h); + +/* SDP handling */ +static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, + struct in_addr my_ip); + +/* RTP handling */ +static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr, + FFStream *stream, const char *session_id, + enum RTSPProtocol rtp_protocol); +static int rtp_new_av_stream(HTTPContext *c, + int stream_index, struct sockaddr_in *dest_addr, + HTTPContext *rtsp_c); + +static const char *my_program_name; +static const char *my_program_dir; + +static int ffserver_debug; +static int ffserver_daemon; +static int no_launch; +static int need_to_start_children; + +static int nb_max_connections; +static int nb_connections; + +static int max_bandwidth; +static int current_bandwidth; + +static long cur_time; // Making this global saves on passing it around everywhere + +static long gettime_ms(void) +{ + struct timeval tv; + + gettimeofday(&tv,NULL); + return (long long)tv.tv_sec * 1000 + (tv.tv_usec / 1000); +} + +static FILE *logfile = NULL; + +static void __attribute__ ((format (printf, 1, 2))) http_log(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + if (logfile) { + vfprintf(logfile, fmt, ap); + fflush(logfile); + } + va_end(ap); +} + +static char *ctime1(char *buf2) +{ + time_t ti; + char *p; + + ti = time(NULL); + p = ctime(&ti); + strcpy(buf2, p); + p = buf2 + strlen(p) - 1; + if (*p == '\n') + *p = '\0'; + return buf2; +} + +static void log_connection(HTTPContext *c) +{ + char buf2[32]; + + if (c->suppress_log) + return; + + http_log("%s - - [%s] \"%s %s %s\" %d %"PRId64"\n", + inet_ntoa(c->from_addr.sin_addr), + ctime1(buf2), c->method, c->url, + c->protocol, (c->http_error ? c->http_error : 200), c->data_count); +} + +static void update_datarate(DataRateData *drd, int64_t count) +{ + if (!drd->time1 && !drd->count1) { + drd->time1 = drd->time2 = cur_time; + drd->count1 = drd->count2 = count; + } else { + if (cur_time - drd->time2 > 5000) { + drd->time1 = drd->time2; + drd->count1 = drd->count2; + drd->time2 = cur_time; + drd->count2 = count; + } + } +} + +/* In bytes per second */ +static int compute_datarate(DataRateData *drd, int64_t count) +{ + if (cur_time == drd->time1) + return 0; + + return ((count - drd->count1) * 1000) / (cur_time - drd->time1); +} + + +static void start_children(FFStream *feed) +{ + if (no_launch) + return; + + for (; feed; feed = feed->next) { + if (feed->child_argv && !feed->pid) { + feed->pid_start = time(0); + + feed->pid = fork(); + + if (feed->pid < 0) { + fprintf(stderr, "Unable to create children\n"); + exit(1); + } + if (!feed->pid) { + /* In child */ + char pathname[1024]; + char *slash; + int i; + + for (i = 3; i < 256; i++) { + close(i); + } + + if (!ffserver_debug) { + i = open("/dev/null", O_RDWR); + if (i) + dup2(i, 0); + dup2(i, 1); + dup2(i, 2); + if (i) + close(i); + } + + pstrcpy(pathname, sizeof(pathname), my_program_name); + + slash = strrchr(pathname, '/'); + if (!slash) { + slash = pathname; + } else { + slash++; + } + strcpy(slash, "ffmpeg"); + + /* This is needed to make relative pathnames work */ + chdir(my_program_dir); + + signal(SIGPIPE, SIG_DFL); + + execvp(pathname, feed->child_argv); + + _exit(1); + } + } + } +} + +/* open a listening socket */ +static int socket_open_listen(struct sockaddr_in *my_addr) +{ + int server_fd, tmp; + + server_fd = socket(AF_INET,SOCK_STREAM,0); + if (server_fd < 0) { + perror ("socket"); + return -1; + } + + tmp = 1; + setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)); + + if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) { + char bindmsg[32]; + snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port)); + perror (bindmsg); + close(server_fd); + return -1; + } + + if (listen (server_fd, 5) < 0) { + perror ("listen"); + close(server_fd); + return -1; + } + fcntl(server_fd, F_SETFL, O_NONBLOCK); + + return server_fd; +} + +/* start all multicast streams */ +static void start_multicast(void) +{ + FFStream *stream; + char session_id[32]; + HTTPContext *rtp_c; + struct sockaddr_in dest_addr; + int default_port, stream_index; + + default_port = 6000; + for(stream = first_stream; stream != NULL; stream = stream->next) { + if (stream->is_multicast) { + /* open the RTP connection */ + snprintf(session_id, sizeof(session_id), + "%08x%08x", (int)random(), (int)random()); + + /* choose a port if none given */ + if (stream->multicast_port == 0) { + stream->multicast_port = default_port; + default_port += 100; + } + + dest_addr.sin_family = AF_INET; + dest_addr.sin_addr = stream->multicast_ip; + dest_addr.sin_port = htons(stream->multicast_port); + + rtp_c = rtp_new_connection(&dest_addr, stream, session_id, + RTSP_PROTOCOL_RTP_UDP_MULTICAST); + if (!rtp_c) { + continue; + } + if (open_input_stream(rtp_c, "") < 0) { + fprintf(stderr, "Could not open input stream for stream '%s'\n", + stream->filename); + continue; + } + + /* open each RTP stream */ + for(stream_index = 0; stream_index < stream->nb_streams; + stream_index++) { + dest_addr.sin_port = htons(stream->multicast_port + + 2 * stream_index); + if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) { + fprintf(stderr, "Could not open output stream '%s/streamid=%d'\n", + stream->filename, stream_index); + exit(1); + } + } + + /* change state to send data */ + rtp_c->state = HTTPSTATE_SEND_DATA; + } + } +} + +/* main loop of the http server */ +static int http_server(void) +{ + int server_fd, ret, rtsp_server_fd, delay, delay1; + struct pollfd poll_table[HTTP_MAX_CONNECTIONS + 2], *poll_entry; + HTTPContext *c, *c_next; + + server_fd = socket_open_listen(&my_http_addr); + if (server_fd < 0) + return -1; + + rtsp_server_fd = socket_open_listen(&my_rtsp_addr); + if (rtsp_server_fd < 0) + return -1; + + http_log("ffserver started.\n"); + + start_children(first_feed); + + first_http_ctx = NULL; + nb_connections = 0; + + start_multicast(); + + for(;;) { + poll_entry = poll_table; + poll_entry->fd = server_fd; + poll_entry->events = POLLIN; + poll_entry++; + + poll_entry->fd = rtsp_server_fd; + poll_entry->events = POLLIN; + poll_entry++; + + /* wait for events on each HTTP handle */ + c = first_http_ctx; + delay = 1000; + while (c != NULL) { + int fd; + fd = c->fd; + switch(c->state) { + case HTTPSTATE_SEND_HEADER: + case RTSPSTATE_SEND_REPLY: + case RTSPSTATE_SEND_PACKET: + c->poll_entry = poll_entry; + poll_entry->fd = fd; + poll_entry->events = POLLOUT; + poll_entry++; + break; + case HTTPSTATE_SEND_DATA_HEADER: + case HTTPSTATE_SEND_DATA: + case HTTPSTATE_SEND_DATA_TRAILER: + if (!c->is_packetized) { + /* for TCP, we output as much as we can (may need to put a limit) */ + c->poll_entry = poll_entry; + poll_entry->fd = fd; + poll_entry->events = POLLOUT; + poll_entry++; + } else { + /* when ffserver is doing the timing, we work by + looking at which packet need to be sent every + 10 ms */ + delay1 = 10; /* one tick wait XXX: 10 ms assumed */ + if (delay1 < delay) + delay = delay1; + } + break; + case HTTPSTATE_WAIT_REQUEST: + case HTTPSTATE_RECEIVE_DATA: + case HTTPSTATE_WAIT_FEED: + case RTSPSTATE_WAIT_REQUEST: + /* need to catch errors */ + c->poll_entry = poll_entry; + poll_entry->fd = fd; + poll_entry->events = POLLIN;/* Maybe this will work */ + poll_entry++; + break; + default: + c->poll_entry = NULL; + break; + } + c = c->next; + } + + /* wait for an event on one connection. We poll at least every + second to handle timeouts */ + do { + ret = poll(poll_table, poll_entry - poll_table, delay); + if (ret < 0 && errno != EAGAIN && errno != EINTR) + return -1; + } while (ret <= 0); + + cur_time = gettime_ms(); + + if (need_to_start_children) { + need_to_start_children = 0; + start_children(first_feed); + } + + /* now handle the events */ + for(c = first_http_ctx; c != NULL; c = c_next) { + c_next = c->next; + if (handle_connection(c) < 0) { + /* close and free the connection */ + log_connection(c); + close_connection(c); + } + } + + poll_entry = poll_table; + /* new HTTP connection request ? */ + if (poll_entry->revents & POLLIN) { + new_connection(server_fd, 0); + } + poll_entry++; + /* new RTSP connection request ? */ + if (poll_entry->revents & POLLIN) { + new_connection(rtsp_server_fd, 1); + } + } +} + +/* start waiting for a new HTTP/RTSP request */ +static void start_wait_request(HTTPContext *c, int is_rtsp) +{ + c->buffer_ptr = c->buffer; + c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */ + + if (is_rtsp) { + c->timeout = cur_time + RTSP_REQUEST_TIMEOUT; + c->state = RTSPSTATE_WAIT_REQUEST; + } else { + c->timeout = cur_time + HTTP_REQUEST_TIMEOUT; + c->state = HTTPSTATE_WAIT_REQUEST; + } +} + +static void new_connection(int server_fd, int is_rtsp) +{ + struct sockaddr_in from_addr; + int fd, len; + HTTPContext *c = NULL; + + len = sizeof(from_addr); + fd = accept(server_fd, (struct sockaddr *)&from_addr, + &len); + if (fd < 0) + return; + fcntl(fd, F_SETFL, O_NONBLOCK); + + /* XXX: should output a warning page when coming + close to the connection limit */ + if (nb_connections >= nb_max_connections) + goto fail; + + /* add a new connection */ + c = av_mallocz(sizeof(HTTPContext)); + if (!c) + goto fail; + + c->fd = fd; + c->poll_entry = NULL; + c->from_addr = from_addr; + c->buffer_size = IOBUFFER_INIT_SIZE; + c->buffer = av_malloc(c->buffer_size); + if (!c->buffer) + goto fail; + + c->next = first_http_ctx; + first_http_ctx = c; + nb_connections++; + + start_wait_request(c, is_rtsp); + + return; + + fail: + if (c) { + av_free(c->buffer); + av_free(c); + } + close(fd); +} + +static void close_connection(HTTPContext *c) +{ + HTTPContext **cp, *c1; + int i, nb_streams; + AVFormatContext *ctx; + URLContext *h; + AVStream *st; + + /* remove connection from list */ + cp = &first_http_ctx; + while ((*cp) != NULL) { + c1 = *cp; + if (c1 == c) { + *cp = c->next; + } else { + cp = &c1->next; + } + } + + /* remove references, if any (XXX: do it faster) */ + for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) { + if (c1->rtsp_c == c) + c1->rtsp_c = NULL; + } + + /* remove connection associated resources */ + if (c->fd >= 0) + close(c->fd); + if (c->fmt_in) { + /* close each frame parser */ + for(i=0;ifmt_in->nb_streams;i++) { + st = c->fmt_in->streams[i]; + if (st->codec->codec) { + avcodec_close(st->codec); + } + } + av_close_input_file(c->fmt_in); + } + + /* free RTP output streams if any */ + nb_streams = 0; + if (c->stream) + nb_streams = c->stream->nb_streams; + + for(i=0;irtp_ctx[i]; + if (ctx) { + av_write_trailer(ctx); + av_free(ctx); + } + h = c->rtp_handles[i]; + if (h) { + url_close(h); + } + } + + ctx = &c->fmt_ctx; + + if (!c->last_packet_sent) { + if (ctx->oformat) { + /* prepare header */ + if (url_open_dyn_buf(&ctx->pb) >= 0) { + av_write_trailer(ctx); + url_close_dyn_buf(&ctx->pb, &c->pb_buffer); + } + } + } + + for(i=0; inb_streams; i++) + av_free(ctx->streams[i]) ; + + if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE) + current_bandwidth -= c->stream->bandwidth; + av_freep(&c->pb_buffer); + av_freep(&c->packet_buffer); + av_free(c->buffer); + av_free(c); + nb_connections--; +} + +static int handle_connection(HTTPContext *c) +{ + int len, ret; + + switch(c->state) { + case HTTPSTATE_WAIT_REQUEST: + case RTSPSTATE_WAIT_REQUEST: + /* timeout ? */ + if ((c->timeout - cur_time) < 0) + return -1; + if (c->poll_entry->revents & (POLLERR | POLLHUP)) + return -1; + + /* no need to read if no events */ + if (!(c->poll_entry->revents & POLLIN)) + return 0; + /* read the data */ + read_loop: + len = read(c->fd, c->buffer_ptr, 1); + if (len < 0) { + if (errno != EAGAIN && errno != EINTR) + return -1; + } else if (len == 0) { + return -1; + } else { + /* search for end of request. */ + uint8_t *ptr; + c->buffer_ptr += len; + ptr = c->buffer_ptr; + if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) || + (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) { + /* request found : parse it and reply */ + if (c->state == HTTPSTATE_WAIT_REQUEST) { + ret = http_parse_request(c); + } else { + ret = rtsp_parse_request(c); + } + if (ret < 0) + return -1; + } else if (ptr >= c->buffer_end) { + /* request too long: cannot do anything */ + return -1; + } else goto read_loop; + } + break; + + case HTTPSTATE_SEND_HEADER: + if (c->poll_entry->revents & (POLLERR | POLLHUP)) + return -1; + + /* no need to write if no events */ + if (!(c->poll_entry->revents & POLLOUT)) + return 0; + len = write(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr); + if (len < 0) { + if (errno != EAGAIN && errno != EINTR) { + /* error : close connection */ + av_freep(&c->pb_buffer); + return -1; + } + } else { + c->buffer_ptr += len; + if (c->stream) + c->stream->bytes_served += len; + c->data_count += len; + if (c->buffer_ptr >= c->buffer_end) { + av_freep(&c->pb_buffer); + /* if error, exit */ + if (c->http_error) { + return -1; + } + /* all the buffer was sent : synchronize to the incoming stream */ + c->state = HTTPSTATE_SEND_DATA_HEADER; + c->buffer_ptr = c->buffer_end = c->buffer; + } + } + break; + + case HTTPSTATE_SEND_DATA: + case HTTPSTATE_SEND_DATA_HEADER: + case HTTPSTATE_SEND_DATA_TRAILER: + /* for packetized output, we consider we can always write (the + input streams sets the speed). It may be better to verify + that we do not rely too much on the kernel queues */ + if (!c->is_packetized) { + if (c->poll_entry->revents & (POLLERR | POLLHUP)) + return -1; + + /* no need to read if no events */ + if (!(c->poll_entry->revents & POLLOUT)) + return 0; + } + if (http_send_data(c) < 0) + return -1; + break; + case HTTPSTATE_RECEIVE_DATA: + /* no need to read if no events */ + if (c->poll_entry->revents & (POLLERR | POLLHUP)) + return -1; + if (!(c->poll_entry->revents & POLLIN)) + return 0; + if (http_receive_data(c) < 0) + return -1; + break; + case HTTPSTATE_WAIT_FEED: + /* no need to read if no events */ + if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP)) + return -1; + + /* nothing to do, we'll be waken up by incoming feed packets */ + break; + + case RTSPSTATE_SEND_REPLY: + if (c->poll_entry->revents & (POLLERR | POLLHUP)) { + av_freep(&c->pb_buffer); + return -1; + } + /* no need to write if no events */ + if (!(c->poll_entry->revents & POLLOUT)) + return 0; + len = write(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr); + if (len < 0) { + if (errno != EAGAIN && errno != EINTR) { + /* error : close connection */ + av_freep(&c->pb_buffer); + return -1; + } + } else { + c->buffer_ptr += len; + c->data_count += len; + if (c->buffer_ptr >= c->buffer_end) { + /* all the buffer was sent : wait for a new request */ + av_freep(&c->pb_buffer); + start_wait_request(c, 1); + } + } + break; + case RTSPSTATE_SEND_PACKET: + if (c->poll_entry->revents & (POLLERR | POLLHUP)) { + av_freep(&c->packet_buffer); + return -1; + } + /* no need to write if no events */ + if (!(c->poll_entry->revents & POLLOUT)) + return 0; + len = write(c->fd, c->packet_buffer_ptr, + c->packet_buffer_end - c->packet_buffer_ptr); + if (len < 0) { + if (errno != EAGAIN && errno != EINTR) { + /* error : close connection */ + av_freep(&c->packet_buffer); + return -1; + } + } else { + c->packet_buffer_ptr += len; + if (c->packet_buffer_ptr >= c->packet_buffer_end) { + /* all the buffer was sent : wait for a new request */ + av_freep(&c->packet_buffer); + c->state = RTSPSTATE_WAIT_REQUEST; + } + } + break; + case HTTPSTATE_READY: + /* nothing to do */ + break; + default: + return -1; + } + return 0; +} + +static int extract_rates(char *rates, int ratelen, const char *request) +{ + const char *p; + + for (p = request; *p && *p != '\r' && *p != '\n'; ) { + if (strncasecmp(p, "Pragma:", 7) == 0) { + const char *q = p + 7; + + while (*q && *q != '\n' && isspace(*q)) + q++; + + if (strncasecmp(q, "stream-switch-entry=", 20) == 0) { + int stream_no; + int rate_no; + + q += 20; + + memset(rates, 0xff, ratelen); + + while (1) { + while (*q && *q != '\n' && *q != ':') + q++; + + if (sscanf(q, ":%d:%d", &stream_no, &rate_no) != 2) { + break; + } + stream_no--; + if (stream_no < ratelen && stream_no >= 0) { + rates[stream_no] = rate_no; + } + + while (*q && *q != '\n' && !isspace(*q)) + q++; + } + + return 1; + } + } + p = strchr(p, '\n'); + if (!p) + break; + + p++; + } + + return 0; +} + +static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate) +{ + int i; + int best_bitrate = 100000000; + int best = -1; + + for (i = 0; i < feed->nb_streams; i++) { + AVCodecContext *feed_codec = feed->streams[i]->codec; + + if (feed_codec->codec_id != codec->codec_id || + feed_codec->sample_rate != codec->sample_rate || + feed_codec->width != codec->width || + feed_codec->height != codec->height) { + continue; + } + + /* Potential stream */ + + /* We want the fastest stream less than bit_rate, or the slowest + * faster than bit_rate + */ + + if (feed_codec->bit_rate <= bit_rate) { + if (best_bitrate > bit_rate || feed_codec->bit_rate > best_bitrate) { + best_bitrate = feed_codec->bit_rate; + best = i; + } + } else { + if (feed_codec->bit_rate < best_bitrate) { + best_bitrate = feed_codec->bit_rate; + best = i; + } + } + } + + return best; +} + +static int modify_current_stream(HTTPContext *c, char *rates) +{ + int i; + FFStream *req = c->stream; + int action_required = 0; + + /* Not much we can do for a feed */ + if (!req->feed) + return 0; + + for (i = 0; i < req->nb_streams; i++) { + AVCodecContext *codec = req->streams[i]->codec; + + switch(rates[i]) { + case 0: + c->switch_feed_streams[i] = req->feed_streams[i]; + break; + case 1: + c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 2); + break; + case 2: + /* Wants off or slow */ + c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 4); +#ifdef WANTS_OFF + /* This doesn't work well when it turns off the only stream! */ + c->switch_feed_streams[i] = -2; + c->feed_streams[i] = -2; +#endif + break; + } + + if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i]) + action_required = 1; + } + + return action_required; +} + + +static void do_switch_stream(HTTPContext *c, int i) +{ + if (c->switch_feed_streams[i] >= 0) { +#ifdef PHILIP + c->feed_streams[i] = c->switch_feed_streams[i]; +#endif + + /* Now update the stream */ + } + c->switch_feed_streams[i] = -1; +} + +/* XXX: factorize in utils.c ? */ +/* XXX: take care with different space meaning */ +static void skip_spaces(const char **pp) +{ + const char *p; + p = *pp; + while (*p == ' ' || *p == '\t') + p++; + *pp = p; +} + +static void get_word(char *buf, int buf_size, const char **pp) +{ + const char *p; + char *q; + + p = *pp; + skip_spaces(&p); + q = buf; + while (!isspace(*p) && *p != '\0') { + if ((q - buf) < buf_size - 1) + *q++ = *p; + p++; + } + if (buf_size > 0) + *q = '\0'; + *pp = p; +} + +static int validate_acl(FFStream *stream, HTTPContext *c) +{ + enum IPAddressAction last_action = IP_DENY; + IPAddressACL *acl; + struct in_addr *src = &c->from_addr.sin_addr; + unsigned long src_addr = ntohl(src->s_addr); + + for (acl = stream->acl; acl; acl = acl->next) { + if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr) { + return (acl->action == IP_ALLOW) ? 1 : 0; + } + last_action = acl->action; + } + + /* Nothing matched, so return not the last action */ + return (last_action == IP_DENY) ? 1 : 0; +} + +/* compute the real filename of a file by matching it without its + extensions to all the stream filenames */ +static void compute_real_filename(char *filename, int max_size) +{ + char file1[1024]; + char file2[1024]; + char *p; + FFStream *stream; + + /* compute filename by matching without the file extensions */ + pstrcpy(file1, sizeof(file1), filename); + p = strrchr(file1, '.'); + if (p) + *p = '\0'; + for(stream = first_stream; stream != NULL; stream = stream->next) { + pstrcpy(file2, sizeof(file2), stream->filename); + p = strrchr(file2, '.'); + if (p) + *p = '\0'; + if (!strcmp(file1, file2)) { + pstrcpy(filename, max_size, stream->filename); + break; + } + } +} + +enum RedirType { + REDIR_NONE, + REDIR_ASX, + REDIR_RAM, + REDIR_ASF, + REDIR_RTSP, + REDIR_SDP, +}; + +/* parse http request and prepare header */ +static int http_parse_request(HTTPContext *c) +{ + char *p; + enum RedirType redir_type; + char cmd[32]; + char info[1024], *filename; + char url[1024], *q; + char protocol[32]; + char msg[1024]; + const char *mime_type; + FFStream *stream; + int i; + char ratebuf[32]; + char *useragent = 0; + + p = c->buffer; + get_word(cmd, sizeof(cmd), (const char **)&p); + pstrcpy(c->method, sizeof(c->method), cmd); + + if (!strcmp(cmd, "GET")) + c->post = 0; + else if (!strcmp(cmd, "POST")) + c->post = 1; + else + return -1; + + get_word(url, sizeof(url), (const char **)&p); + pstrcpy(c->url, sizeof(c->url), url); + + get_word(protocol, sizeof(protocol), (const char **)&p); + if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1")) + return -1; + + pstrcpy(c->protocol, sizeof(c->protocol), protocol); + + if (ffserver_debug) + http_log("New connection: %s %s\n", cmd, url); + + /* find the filename and the optional info string in the request */ + p = url; + if (*p == '/') + p++; + filename = p; + p = strchr(p, '?'); + if (p) { + pstrcpy(info, sizeof(info), p); + *p = '\0'; + } else { + info[0] = '\0'; + } + + for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { + if (strncasecmp(p, "User-Agent:", 11) == 0) { + useragent = p + 11; + if (*useragent && *useragent != '\n' && isspace(*useragent)) + useragent++; + break; + } + p = strchr(p, '\n'); + if (!p) + break; + + p++; + } + + redir_type = REDIR_NONE; + if (match_ext(filename, "asx")) { + redir_type = REDIR_ASX; + filename[strlen(filename)-1] = 'f'; + } else if (match_ext(filename, "asf") && + (!useragent || strncasecmp(useragent, "NSPlayer", 8) != 0)) { + /* if this isn't WMP or lookalike, return the redirector file */ + redir_type = REDIR_ASF; + } else if (match_ext(filename, "rpm,ram")) { + redir_type = REDIR_RAM; + strcpy(filename + strlen(filename)-2, "m"); + } else if (match_ext(filename, "rtsp")) { + redir_type = REDIR_RTSP; + compute_real_filename(filename, sizeof(url) - 1); + } else if (match_ext(filename, "sdp")) { + redir_type = REDIR_SDP; + compute_real_filename(filename, sizeof(url) - 1); + } + + stream = first_stream; + while (stream != NULL) { + if (!strcmp(stream->filename, filename) && validate_acl(stream, c)) + break; + stream = stream->next; + } + if (stream == NULL) { + snprintf(msg, sizeof(msg), "File '%s' not found", url); + goto send_error; + } + + c->stream = stream; + memcpy(c->feed_streams, stream->feed_streams, sizeof(c->feed_streams)); + memset(c->switch_feed_streams, -1, sizeof(c->switch_feed_streams)); + + if (stream->stream_type == STREAM_TYPE_REDIRECT) { + c->http_error = 301; + q = c->buffer; + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 301 Moved\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Location: %s\r\n", stream->feed_filename); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: text/html\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Moved\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "You should be redirected.\r\n", stream->feed_filename); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + + /* prepare output buffer */ + c->buffer_ptr = c->buffer; + c->buffer_end = q; + c->state = HTTPSTATE_SEND_HEADER; + return 0; + } + + /* If this is WMP, get the rate information */ + if (extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) { + if (modify_current_stream(c, ratebuf)) { + for (i = 0; i < sizeof(c->feed_streams) / sizeof(c->feed_streams[0]); i++) { + if (c->switch_feed_streams[i] >= 0) + do_switch_stream(c, i); + } + } + } + + if (c->post == 0 && stream->stream_type == STREAM_TYPE_LIVE) { + current_bandwidth += stream->bandwidth; + } + + if (c->post == 0 && max_bandwidth < current_bandwidth) { + c->http_error = 200; + q = c->buffer; + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 Server too busy\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: text/html\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Too busy\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "

    The server is too busy to serve your request at this time.

    \r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "

    The bandwidth being served (including your stream) is %dkbit/sec, and this exceeds the limit of %dkbit/sec.

    \r\n", + current_bandwidth, max_bandwidth); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + + /* prepare output buffer */ + c->buffer_ptr = c->buffer; + c->buffer_end = q; + c->state = HTTPSTATE_SEND_HEADER; + return 0; + } + + if (redir_type != REDIR_NONE) { + char *hostinfo = 0; + + for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { + if (strncasecmp(p, "Host:", 5) == 0) { + hostinfo = p + 5; + break; + } + p = strchr(p, '\n'); + if (!p) + break; + + p++; + } + + if (hostinfo) { + char *eoh; + char hostbuf[260]; + + while (isspace(*hostinfo)) + hostinfo++; + + eoh = strchr(hostinfo, '\n'); + if (eoh) { + if (eoh[-1] == '\r') + eoh--; + + if (eoh - hostinfo < sizeof(hostbuf) - 1) { + memcpy(hostbuf, hostinfo, eoh - hostinfo); + hostbuf[eoh - hostinfo] = 0; + + c->http_error = 200; + q = c->buffer; + switch(redir_type) { + case REDIR_ASX: + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 ASX Follows\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: video/x-ms-asf\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + //q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n", + hostbuf, filename, info); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + break; + case REDIR_RAM: + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 RAM Follows\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: audio/x-pn-realaudio\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "# Autogenerated by ffserver\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "http://%s/%s%s\r\n", + hostbuf, filename, info); + break; + case REDIR_ASF: + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 ASF Redirect follows\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: video/x-ms-asf\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "[Reference]\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Ref1=http://%s/%s%s\r\n", + hostbuf, filename, info); + break; + case REDIR_RTSP: + { + char hostname[256], *p; + /* extract only hostname */ + pstrcpy(hostname, sizeof(hostname), hostbuf); + p = strrchr(hostname, ':'); + if (p) + *p = '\0'; + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 RTSP Redirect follows\r\n"); + /* XXX: incorrect mime type ? */ + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: application/x-rtsp\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "rtsp://%s:%d/%s\r\n", + hostname, ntohs(my_rtsp_addr.sin_port), + filename); + } + break; + case REDIR_SDP: + { + uint8_t *sdp_data; + int sdp_data_size, len; + struct sockaddr_in my_addr; + + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: application/sdp\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + + len = sizeof(my_addr); + getsockname(c->fd, (struct sockaddr *)&my_addr, &len); + + /* XXX: should use a dynamic buffer */ + sdp_data_size = prepare_sdp_description(stream, + &sdp_data, + my_addr.sin_addr); + if (sdp_data_size > 0) { + memcpy(q, sdp_data, sdp_data_size); + q += sdp_data_size; + *q = '\0'; + av_free(sdp_data); + } + } + break; + default: + av_abort(); + break; + } + + /* prepare output buffer */ + c->buffer_ptr = c->buffer; + c->buffer_end = q; + c->state = HTTPSTATE_SEND_HEADER; + return 0; + } + } + } + + snprintf(msg, sizeof(msg), "ASX/RAM file not handled"); + goto send_error; + } + + stream->conns_served++; + + /* XXX: add there authenticate and IP match */ + + if (c->post) { + /* if post, it means a feed is being sent */ + if (!stream->is_feed) { + /* However it might be a status report from WMP! Lets log the data + * as it might come in handy one day + */ + char *logline = 0; + int client_id = 0; + + for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { + if (strncasecmp(p, "Pragma: log-line=", 17) == 0) { + logline = p; + break; + } + if (strncasecmp(p, "Pragma: client-id=", 18) == 0) { + client_id = strtol(p + 18, 0, 10); + } + p = strchr(p, '\n'); + if (!p) + break; + + p++; + } + + if (logline) { + char *eol = strchr(logline, '\n'); + + logline += 17; + + if (eol) { + if (eol[-1] == '\r') + eol--; + http_log("%.*s\n", (int) (eol - logline), logline); + c->suppress_log = 1; + } + } + +#ifdef DEBUG_WMP + http_log("\nGot request:\n%s\n", c->buffer); +#endif + + if (client_id && extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) { + HTTPContext *wmpc; + + /* Now we have to find the client_id */ + for (wmpc = first_http_ctx; wmpc; wmpc = wmpc->next) { + if (wmpc->wmp_client_id == client_id) + break; + } + + if (wmpc) { + if (modify_current_stream(wmpc, ratebuf)) { + wmpc->switch_pending = 1; + } + } + } + + snprintf(msg, sizeof(msg), "POST command not handled"); + c->stream = 0; + goto send_error; + } + if (http_start_receive_data(c) < 0) { + snprintf(msg, sizeof(msg), "could not open feed"); + goto send_error; + } + c->http_error = 0; + c->state = HTTPSTATE_RECEIVE_DATA; + return 0; + } + +#ifdef DEBUG_WMP + if (strcmp(stream->filename + strlen(stream->filename) - 4, ".asf") == 0) { + http_log("\nGot request:\n%s\n", c->buffer); + } +#endif + + if (c->stream->stream_type == STREAM_TYPE_STATUS) + goto send_stats; + + /* open input stream */ + if (open_input_stream(c, info) < 0) { + snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url); + goto send_error; + } + + /* prepare http header */ + q = c->buffer; + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n"); + mime_type = c->stream->fmt->mime_type; + if (!mime_type) + mime_type = "application/x-octet_stream"; + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Pragma: no-cache\r\n"); + + /* for asf, we need extra headers */ + if (!strcmp(c->stream->fmt->name,"asf_stream")) { + /* Need to allocate a client id */ + + c->wmp_client_id = random() & 0x7fffffff; + + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id); + } + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-Type: %s\r\n", mime_type); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + + /* prepare output buffer */ + c->http_error = 0; + c->buffer_ptr = c->buffer; + c->buffer_end = q; + c->state = HTTPSTATE_SEND_HEADER; + return 0; + send_error: + c->http_error = 404; + q = c->buffer; + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 404 Not Found\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-type: %s\r\n", "text/html"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "404 Not Found\n"); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "%s\n", msg); + q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\n"); + + /* prepare output buffer */ + c->buffer_ptr = c->buffer; + c->buffer_end = q; + c->state = HTTPSTATE_SEND_HEADER; + return 0; + send_stats: + compute_stats(c); + c->http_error = 200; /* horrible : we use this value to avoid + going to the send data state */ + c->state = HTTPSTATE_SEND_HEADER; + return 0; +} + +static void fmt_bytecount(ByteIOContext *pb, int64_t count) +{ + static const char *suffix = " kMGTP"; + const char *s; + + for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++) { + } + + url_fprintf(pb, "%"PRId64"%c", count, *s); +} + +static void compute_stats(HTTPContext *c) +{ + HTTPContext *c1; + FFStream *stream; + char *p; + time_t ti; + int i, len; + ByteIOContext pb1, *pb = &pb1; + + if (url_open_dyn_buf(pb) < 0) { + /* XXX: return an error ? */ + c->buffer_ptr = c->buffer; + c->buffer_end = c->buffer; + return; + } + + url_fprintf(pb, "HTTP/1.0 200 OK\r\n"); + url_fprintf(pb, "Content-type: %s\r\n", "text/html"); + url_fprintf(pb, "Pragma: no-cache\r\n"); + url_fprintf(pb, "\r\n"); + + url_fprintf(pb, "FFServer Status\n"); + if (c->stream->feed_filename) { + url_fprintf(pb, "\n", c->stream->feed_filename); + } + url_fprintf(pb, "\n"); + url_fprintf(pb, "

    FFServer Status

    \n"); + /* format status */ + url_fprintf(pb, "

    Available Streams

    \n"); + url_fprintf(pb, "\n"); + url_fprintf(pb, "
    PathServed
    Conns

    bytes
    FormatBit rate
    kbits/s
    Video
    kbits/s

    Codec
    Audio
    kbits/s

    Codec
    Feed\n"); + stream = first_stream; + while (stream != NULL) { + char sfilename[1024]; + char *eosf; + + if (stream->feed != stream) { + pstrcpy(sfilename, sizeof(sfilename) - 10, stream->filename); + eosf = sfilename + strlen(sfilename); + if (eosf - sfilename >= 4) { + if (strcmp(eosf - 4, ".asf") == 0) { + strcpy(eosf - 4, ".asx"); + } else if (strcmp(eosf - 3, ".rm") == 0) { + strcpy(eosf - 3, ".ram"); + } else if (stream->fmt == &rtp_mux) { + /* generate a sample RTSP director if + unicast. Generate an SDP redirector if + multicast */ + eosf = strrchr(sfilename, '.'); + if (!eosf) + eosf = sfilename + strlen(sfilename); + if (stream->is_multicast) + strcpy(eosf, ".sdp"); + else + strcpy(eosf, ".rtsp"); + } + } + + url_fprintf(pb, "
    %s ", + sfilename, stream->filename); + url_fprintf(pb, " %d ", + stream->conns_served); + fmt_bytecount(pb, stream->bytes_served); + switch(stream->stream_type) { + case STREAM_TYPE_LIVE: + { + int audio_bit_rate = 0; + int video_bit_rate = 0; + const char *audio_codec_name = ""; + const char *video_codec_name = ""; + const char *audio_codec_name_extra = ""; + const char *video_codec_name_extra = ""; + + for(i=0;inb_streams;i++) { + AVStream *st = stream->streams[i]; + AVCodec *codec = avcodec_find_encoder(st->codec->codec_id); + switch(st->codec->codec_type) { + case CODEC_TYPE_AUDIO: + audio_bit_rate += st->codec->bit_rate; + if (codec) { + if (*audio_codec_name) + audio_codec_name_extra = "..."; + audio_codec_name = codec->name; + } + break; + case CODEC_TYPE_VIDEO: + video_bit_rate += st->codec->bit_rate; + if (codec) { + if (*video_codec_name) + video_codec_name_extra = "..."; + video_codec_name = codec->name; + } + break; + case CODEC_TYPE_DATA: + video_bit_rate += st->codec->bit_rate; + break; + default: + av_abort(); + } + } + url_fprintf(pb, " %s %d %d %s %s %d %s %s", + stream->fmt->name, + stream->bandwidth, + video_bit_rate / 1000, video_codec_name, video_codec_name_extra, + audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra); + if (stream->feed) { + url_fprintf(pb, "%s", stream->feed->filename); + } else { + url_fprintf(pb, "%s", stream->feed_filename); + } + url_fprintf(pb, "\n"); + } + break; + default: + url_fprintf(pb, " - - - - \n"); + break; + } + } + stream = stream->next; + } + url_fprintf(pb, "
    \n"); + + stream = first_stream; + while (stream != NULL) { + if (stream->feed == stream) { + url_fprintf(pb, "

    Feed %s

    ", stream->filename); + if (stream->pid) { + url_fprintf(pb, "Running as pid %d.\n", stream->pid); + +#if defined(linux) && !defined(CONFIG_NOCUTILS) + { + FILE *pid_stat; + char ps_cmd[64]; + + /* This is somewhat linux specific I guess */ + snprintf(ps_cmd, sizeof(ps_cmd), + "ps -o \"%%cpu,cputime\" --no-headers %d", + stream->pid); + + pid_stat = popen(ps_cmd, "r"); + if (pid_stat) { + char cpuperc[10]; + char cpuused[64]; + + if (fscanf(pid_stat, "%10s %64s", cpuperc, + cpuused) == 2) { + url_fprintf(pb, "Currently using %s%% of the cpu. Total time used %s.\n", + cpuperc, cpuused); + } + fclose(pid_stat); + } + } +#endif + + url_fprintf(pb, "

    "); + } + url_fprintf(pb, "
    Streamtypekbits/scodecParameters\n"); + + for (i = 0; i < stream->nb_streams; i++) { + AVStream *st = stream->streams[i]; + AVCodec *codec = avcodec_find_encoder(st->codec->codec_id); + const char *type = "unknown"; + char parameters[64]; + + parameters[0] = 0; + + switch(st->codec->codec_type) { + case CODEC_TYPE_AUDIO: + type = "audio"; + break; + case CODEC_TYPE_VIDEO: + type = "video"; + snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height, + st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num); + break; + default: + av_abort(); + } + url_fprintf(pb, "
    %d%s%d%s%s\n", + i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters); + } + url_fprintf(pb, "
    \n"); + + } + stream = stream->next; + } + +#if 0 + { + float avg; + AVCodecContext *enc; + char buf[1024]; + + /* feed status */ + stream = first_feed; + while (stream != NULL) { + url_fprintf(pb, "

    Feed '%s'

    \n", stream->filename); + url_fprintf(pb, "\n"); + url_fprintf(pb, "
    ParametersFrame countSizeAvg bitrate (kbits/s)\n"); + for(i=0;inb_streams;i++) { + AVStream *st = stream->streams[i]; + FeedData *fdata = st->priv_data; + enc = st->codec; + + avcodec_string(buf, sizeof(buf), enc); + avg = fdata->avg_frame_size * (float)enc->rate * 8.0; + if (enc->codec->type == CODEC_TYPE_AUDIO && enc->frame_size > 0) + avg /= enc->frame_size; + url_fprintf(pb, "
    %s %d %Ld %0.1f\n", + buf, enc->frame_number, fdata->data_count, avg / 1000.0); + } + url_fprintf(pb, "
    \n"); + stream = stream->next_feed; + } + } +#endif + + /* connection status */ + url_fprintf(pb, "

    Connection Status

    \n"); + + url_fprintf(pb, "Number of connections: %d / %d
    \n", + nb_connections, nb_max_connections); + + url_fprintf(pb, "Bandwidth in use: %dk / %dk
    \n", + current_bandwidth, max_bandwidth); + + url_fprintf(pb, "\n"); + url_fprintf(pb, "
    #FileIPProtoStateTarget bits/secActual bits/secBytes transferred\n"); + c1 = first_http_ctx; + i = 0; + while (c1 != NULL) { + int bitrate; + int j; + + bitrate = 0; + if (c1->stream) { + for (j = 0; j < c1->stream->nb_streams; j++) { + if (!c1->stream->feed) { + bitrate += c1->stream->streams[j]->codec->bit_rate; + } else { + if (c1->feed_streams[j] >= 0) { + bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate; + } + } + } + } + + i++; + p = inet_ntoa(c1->from_addr.sin_addr); + url_fprintf(pb, "
    %d%s%s%s%s%s", + i, + c1->stream ? c1->stream->filename : "", + c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "", + p, + c1->protocol, + http_state[c1->state]); + fmt_bytecount(pb, bitrate); + url_fprintf(pb, ""); + fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8); + url_fprintf(pb, ""); + fmt_bytecount(pb, c1->data_count); + url_fprintf(pb, "\n"); + c1 = c1->next; + } + url_fprintf(pb, "
    \n"); + + /* date */ + ti = time(NULL); + p = ctime(&ti); + url_fprintf(pb, "
    Generated at %s", p); + url_fprintf(pb, "\n\n"); + + len = url_close_dyn_buf(pb, &c->pb_buffer); + c->buffer_ptr = c->pb_buffer; + c->buffer_end = c->pb_buffer + len; +} + +/* check if the parser needs to be opened for stream i */ +static void open_parser(AVFormatContext *s, int i) +{ + AVStream *st = s->streams[i]; + AVCodec *codec; + + if (!st->codec->codec) { + codec = avcodec_find_decoder(st->codec->codec_id); + if (codec && (codec->capabilities & CODEC_CAP_PARSE_ONLY)) { + st->codec->parse_only = 1; + if (avcodec_open(st->codec, codec) < 0) { + st->codec->parse_only = 0; + } + } + } +} + +static int open_input_stream(HTTPContext *c, const char *info) +{ + char buf[128]; + char input_filename[1024]; + AVFormatContext *s; + int buf_size, i; + int64_t stream_pos; + + /* find file name */ + if (c->stream->feed) { + strcpy(input_filename, c->stream->feed->feed_filename); + buf_size = FFM_PACKET_SIZE; + /* compute position (absolute time) */ + if (find_info_tag(buf, sizeof(buf), "date", info)) { + stream_pos = parse_date(buf, 0); + } else if (find_info_tag(buf, sizeof(buf), "buffer", info)) { + int prebuffer = strtol(buf, 0, 10); + stream_pos = av_gettime() - prebuffer * (int64_t)1000000; + } else { + stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000; + } + } else { + strcpy(input_filename, c->stream->feed_filename); + buf_size = 0; + /* compute position (relative time) */ + if (find_info_tag(buf, sizeof(buf), "date", info)) { + stream_pos = parse_date(buf, 1); + } else { + stream_pos = 0; + } + } + if (input_filename[0] == '\0') + return -1; + +#if 0 + { time_t when = stream_pos / 1000000; + http_log("Stream pos = %lld, time=%s", stream_pos, ctime(&when)); + } +#endif + + /* open stream */ + if (av_open_input_file(&s, input_filename, c->stream->ifmt, + buf_size, c->stream->ap_in) < 0) { + http_log("%s not found", input_filename); + return -1; + } + c->fmt_in = s; + + /* open each parser */ + for(i=0;inb_streams;i++) + open_parser(s, i); + + /* choose stream as clock source (we favorize video stream if + present) for packet sending */ + c->pts_stream_index = 0; + for(i=0;istream->nb_streams;i++) { + if (c->pts_stream_index == 0 && + c->stream->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) { + c->pts_stream_index = i; + } + } + +#if 1 + if (c->fmt_in->iformat->read_seek) { + c->fmt_in->iformat->read_seek(c->fmt_in, 0, stream_pos, 0); + } +#endif + /* set the start time (needed for maxtime and RTP packet timing) */ + c->start_time = cur_time; + c->first_pts = AV_NOPTS_VALUE; + return 0; +} + +/* return the server clock (in us) */ +static int64_t get_server_clock(HTTPContext *c) +{ + /* compute current pts value from system time */ + return (int64_t)(cur_time - c->start_time) * 1000LL; +} + +/* return the estimated time at which the current packet must be sent + (in us) */ +static int64_t get_packet_send_clock(HTTPContext *c) +{ + int bytes_left, bytes_sent, frame_bytes; + + frame_bytes = c->cur_frame_bytes; + if (frame_bytes <= 0) { + return c->cur_pts; + } else { + bytes_left = c->buffer_end - c->buffer_ptr; + bytes_sent = frame_bytes - bytes_left; + return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes; + } +} + + +static int http_prepare_data(HTTPContext *c) +{ + int i, len, ret; + AVFormatContext *ctx; + + av_freep(&c->pb_buffer); + switch(c->state) { + case HTTPSTATE_SEND_DATA_HEADER: + memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx)); + pstrcpy(c->fmt_ctx.author, sizeof(c->fmt_ctx.author), + c->stream->author); + pstrcpy(c->fmt_ctx.comment, sizeof(c->fmt_ctx.comment), + c->stream->comment); + pstrcpy(c->fmt_ctx.copyright, sizeof(c->fmt_ctx.copyright), + c->stream->copyright); + pstrcpy(c->fmt_ctx.title, sizeof(c->fmt_ctx.title), + c->stream->title); + + /* open output stream by using specified codecs */ + c->fmt_ctx.oformat = c->stream->fmt; + c->fmt_ctx.nb_streams = c->stream->nb_streams; + for(i=0;ifmt_ctx.nb_streams;i++) { + AVStream *st; + AVStream *src; + st = av_mallocz(sizeof(AVStream)); + st->codec= avcodec_alloc_context(); + c->fmt_ctx.streams[i] = st; + /* if file or feed, then just take streams from FFStream struct */ + if (!c->stream->feed || + c->stream->feed == c->stream) + src = c->stream->streams[i]; + else + src = c->stream->feed->streams[c->stream->feed_streams[i]]; + + *st = *src; + st->priv_data = 0; + st->codec->frame_number = 0; /* XXX: should be done in + AVStream, not in codec */ + /* I'm pretty sure that this is not correct... + * However, without it, we crash + */ + st->codec->coded_frame = &dummy_frame; + } + c->got_key_frame = 0; + + /* prepare header and save header data in a stream */ + if (url_open_dyn_buf(&c->fmt_ctx.pb) < 0) { + /* XXX: potential leak */ + return -1; + } + c->fmt_ctx.pb.is_streamed = 1; + + av_set_parameters(&c->fmt_ctx, NULL); + av_write_header(&c->fmt_ctx); + + len = url_close_dyn_buf(&c->fmt_ctx.pb, &c->pb_buffer); + c->buffer_ptr = c->pb_buffer; + c->buffer_end = c->pb_buffer + len; + + c->state = HTTPSTATE_SEND_DATA; + c->last_packet_sent = 0; + break; + case HTTPSTATE_SEND_DATA: + /* find a new packet */ + { + AVPacket pkt; + + /* read a packet from the input stream */ + if (c->stream->feed) { + ffm_set_write_index(c->fmt_in, + c->stream->feed->feed_write_index, + c->stream->feed->feed_size); + } + + if (c->stream->max_time && + c->stream->max_time + c->start_time - cur_time < 0) { + /* We have timed out */ + c->state = HTTPSTATE_SEND_DATA_TRAILER; + } else { + redo: + if (av_read_frame(c->fmt_in, &pkt) < 0) { + if (c->stream->feed && c->stream->feed->feed_opened) { + /* if coming from feed, it means we reached the end of the + ffm file, so must wait for more data */ + c->state = HTTPSTATE_WAIT_FEED; + return 1; /* state changed */ + } else { + if (c->stream->loop) { + av_close_input_file(c->fmt_in); + c->fmt_in = NULL; + if (open_input_stream(c, "") < 0) + goto no_loop; + goto redo; + } else { + no_loop: + /* must send trailer now because eof or error */ + c->state = HTTPSTATE_SEND_DATA_TRAILER; + } + } + } else { + /* update first pts if needed */ + if (c->first_pts == AV_NOPTS_VALUE) { + c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q); + c->start_time = cur_time; + } + /* send it to the appropriate stream */ + if (c->stream->feed) { + /* if coming from a feed, select the right stream */ + if (c->switch_pending) { + c->switch_pending = 0; + for(i=0;istream->nb_streams;i++) { + if (c->switch_feed_streams[i] == pkt.stream_index) { + if (pkt.flags & PKT_FLAG_KEY) { + do_switch_stream(c, i); + } + } + if (c->switch_feed_streams[i] >= 0) { + c->switch_pending = 1; + } + } + } + for(i=0;istream->nb_streams;i++) { + if (c->feed_streams[i] == pkt.stream_index) { + pkt.stream_index = i; + if (pkt.flags & PKT_FLAG_KEY) { + c->got_key_frame |= 1 << i; + } + /* See if we have all the key frames, then + * we start to send. This logic is not quite + * right, but it works for the case of a + * single video stream with one or more + * audio streams (for which every frame is + * typically a key frame). + */ + if (!c->stream->send_on_key || + ((c->got_key_frame + 1) >> c->stream->nb_streams)) { + goto send_it; + } + } + } + } else { + AVCodecContext *codec; + + send_it: + /* specific handling for RTP: we use several + output stream (one for each RTP + connection). XXX: need more abstract handling */ + if (c->is_packetized) { + AVStream *st; + /* compute send time and duration */ + st = c->fmt_in->streams[pkt.stream_index]; + c->cur_pts = av_rescale_q(pkt.dts, st->time_base, AV_TIME_BASE_Q); + if (st->start_time != AV_NOPTS_VALUE) + c->cur_pts -= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q); + c->cur_frame_duration = av_rescale_q(pkt.duration, st->time_base, AV_TIME_BASE_Q); +#if 0 + printf("index=%d pts=%0.3f duration=%0.6f\n", + pkt.stream_index, + (double)c->cur_pts / + AV_TIME_BASE, + (double)c->cur_frame_duration / + AV_TIME_BASE); +#endif + /* find RTP context */ + c->packet_stream_index = pkt.stream_index; + ctx = c->rtp_ctx[c->packet_stream_index]; + if(!ctx) { + av_free_packet(&pkt); + break; + } + codec = ctx->streams[0]->codec; + /* only one stream per RTP connection */ + pkt.stream_index = 0; + } else { + ctx = &c->fmt_ctx; + /* Fudge here */ + codec = ctx->streams[pkt.stream_index]->codec; + } + + codec->coded_frame->key_frame = ((pkt.flags & PKT_FLAG_KEY) != 0); + if (c->is_packetized) { + int max_packet_size; + if (c->rtp_protocol == RTSP_PROTOCOL_RTP_TCP) + max_packet_size = RTSP_TCP_MAX_PACKET_SIZE; + else + max_packet_size = url_get_max_packet_size(c->rtp_handles[c->packet_stream_index]); + ret = url_open_dyn_packet_buf(&ctx->pb, max_packet_size); + } else { + ret = url_open_dyn_buf(&ctx->pb); + } + if (ret < 0) { + /* XXX: potential leak */ + return -1; + } + if (av_write_frame(ctx, &pkt)) { + c->state = HTTPSTATE_SEND_DATA_TRAILER; + } + + len = url_close_dyn_buf(&ctx->pb, &c->pb_buffer); + c->cur_frame_bytes = len; + c->buffer_ptr = c->pb_buffer; + c->buffer_end = c->pb_buffer + len; + + codec->frame_number++; + if (len == 0) + goto redo; + } + av_free_packet(&pkt); + } + } + } + break; + default: + case HTTPSTATE_SEND_DATA_TRAILER: + /* last packet test ? */ + if (c->last_packet_sent || c->is_packetized) + return -1; + ctx = &c->fmt_ctx; + /* prepare header */ + if (url_open_dyn_buf(&ctx->pb) < 0) { + /* XXX: potential leak */ + return -1; + } + av_write_trailer(ctx); + len = url_close_dyn_buf(&ctx->pb, &c->pb_buffer); + c->buffer_ptr = c->pb_buffer; + c->buffer_end = c->pb_buffer + len; + + c->last_packet_sent = 1; + break; + } + return 0; +} + +/* in bit/s */ +#define SHORT_TERM_BANDWIDTH 8000000 + +/* should convert the format at the same time */ +/* send data starting at c->buffer_ptr to the output connection + (either UDP or TCP connection) */ +static int http_send_data(HTTPContext *c) +{ + int len, ret; + + for(;;) { + if (c->buffer_ptr >= c->buffer_end) { + ret = http_prepare_data(c); + if (ret < 0) + return -1; + else if (ret != 0) { + /* state change requested */ + break; + } + } else { + if (c->is_packetized) { + /* RTP data output */ + len = c->buffer_end - c->buffer_ptr; + if (len < 4) { + /* fail safe - should never happen */ + fail1: + c->buffer_ptr = c->buffer_end; + return 0; + } + len = (c->buffer_ptr[0] << 24) | + (c->buffer_ptr[1] << 16) | + (c->buffer_ptr[2] << 8) | + (c->buffer_ptr[3]); + if (len > (c->buffer_end - c->buffer_ptr)) + goto fail1; + if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) { + /* nothing to send yet: we can wait */ + return 0; + } + + c->data_count += len; + update_datarate(&c->datarate, c->data_count); + if (c->stream) + c->stream->bytes_served += len; + + if (c->rtp_protocol == RTSP_PROTOCOL_RTP_TCP) { + /* RTP packets are sent inside the RTSP TCP connection */ + ByteIOContext pb1, *pb = &pb1; + int interleaved_index, size; + uint8_t header[4]; + HTTPContext *rtsp_c; + + rtsp_c = c->rtsp_c; + /* if no RTSP connection left, error */ + if (!rtsp_c) + return -1; + /* if already sending something, then wait. */ + if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST) { + break; + } + if (url_open_dyn_buf(pb) < 0) + goto fail1; + interleaved_index = c->packet_stream_index * 2; + /* RTCP packets are sent at odd indexes */ + if (c->buffer_ptr[1] == 200) + interleaved_index++; + /* write RTSP TCP header */ + header[0] = '$'; + header[1] = interleaved_index; + header[2] = len >> 8; + header[3] = len; + put_buffer(pb, header, 4); + /* write RTP packet data */ + c->buffer_ptr += 4; + put_buffer(pb, c->buffer_ptr, len); + size = url_close_dyn_buf(pb, &c->packet_buffer); + /* prepare asynchronous TCP sending */ + rtsp_c->packet_buffer_ptr = c->packet_buffer; + rtsp_c->packet_buffer_end = c->packet_buffer + size; + c->buffer_ptr += len; + + /* send everything we can NOW */ + len = write(rtsp_c->fd, rtsp_c->packet_buffer_ptr, + rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr); + if (len > 0) { + rtsp_c->packet_buffer_ptr += len; + } + if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) { + /* if we could not send all the data, we will + send it later, so a new state is needed to + "lock" the RTSP TCP connection */ + rtsp_c->state = RTSPSTATE_SEND_PACKET; + break; + } else { + /* all data has been sent */ + av_freep(&c->packet_buffer); + } + } else { + /* send RTP packet directly in UDP */ + c->buffer_ptr += 4; + url_write(c->rtp_handles[c->packet_stream_index], + c->buffer_ptr, len); + c->buffer_ptr += len; + /* here we continue as we can send several packets per 10 ms slot */ + } + } else { + /* TCP data output */ + len = write(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr); + if (len < 0) { + if (errno != EAGAIN && errno != EINTR) { + /* error : close connection */ + return -1; + } else { + return 0; + } + } else { + c->buffer_ptr += len; + } + c->data_count += len; + update_datarate(&c->datarate, c->data_count); + if (c->stream) + c->stream->bytes_served += len; + break; + } + } + } /* for(;;) */ + return 0; +} + +static int http_start_receive_data(HTTPContext *c) +{ + int fd; + + if (c->stream->feed_opened) + return -1; + + /* Don't permit writing to this one */ + if (c->stream->readonly) + return -1; + + /* open feed */ + fd = open(c->stream->feed_filename, O_RDWR); + if (fd < 0) + return -1; + c->feed_fd = fd; + + c->stream->feed_write_index = ffm_read_write_index(fd); + c->stream->feed_size = lseek(fd, 0, SEEK_END); + lseek(fd, 0, SEEK_SET); + + /* init buffer input */ + c->buffer_ptr = c->buffer; + c->buffer_end = c->buffer + FFM_PACKET_SIZE; + c->stream->feed_opened = 1; + return 0; +} + +static int http_receive_data(HTTPContext *c) +{ + HTTPContext *c1; + + if (c->buffer_end > c->buffer_ptr) { + int len; + + len = read(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr); + if (len < 0) { + if (errno != EAGAIN && errno != EINTR) { + /* error : close connection */ + goto fail; + } + } else if (len == 0) { + /* end of connection : close it */ + goto fail; + } else { + c->buffer_ptr += len; + c->data_count += len; + update_datarate(&c->datarate, c->data_count); + } + } + + if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) { + if (c->buffer[0] != 'f' || + c->buffer[1] != 'm') { + http_log("Feed stream has become desynchronized -- disconnecting\n"); + goto fail; + } + } + + if (c->buffer_ptr >= c->buffer_end) { + FFStream *feed = c->stream; + /* a packet has been received : write it in the store, except + if header */ + if (c->data_count > FFM_PACKET_SIZE) { + + // printf("writing pos=0x%Lx size=0x%Lx\n", feed->feed_write_index, feed->feed_size); + /* XXX: use llseek or url_seek */ + lseek(c->feed_fd, feed->feed_write_index, SEEK_SET); + write(c->feed_fd, c->buffer, FFM_PACKET_SIZE); + + feed->feed_write_index += FFM_PACKET_SIZE; + /* update file size */ + if (feed->feed_write_index > c->stream->feed_size) + feed->feed_size = feed->feed_write_index; + + /* handle wrap around if max file size reached */ + if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size) + feed->feed_write_index = FFM_PACKET_SIZE; + + /* write index */ + ffm_write_write_index(c->feed_fd, feed->feed_write_index); + + /* wake up any waiting connections */ + for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) { + if (c1->state == HTTPSTATE_WAIT_FEED && + c1->stream->feed == c->stream->feed) { + c1->state = HTTPSTATE_SEND_DATA; + } + } + } else { + /* We have a header in our hands that contains useful data */ + AVFormatContext s; + AVInputFormat *fmt_in; + ByteIOContext *pb = &s.pb; + int i; + + memset(&s, 0, sizeof(s)); + + url_open_buf(pb, c->buffer, c->buffer_end - c->buffer, URL_RDONLY); + pb->buf_end = c->buffer_end; /* ?? */ + pb->is_streamed = 1; + + /* use feed output format name to find corresponding input format */ + fmt_in = av_find_input_format(feed->fmt->name); + if (!fmt_in) + goto fail; + + if (fmt_in->priv_data_size > 0) { + s.priv_data = av_mallocz(fmt_in->priv_data_size); + if (!s.priv_data) + goto fail; + } else + s.priv_data = NULL; + + if (fmt_in->read_header(&s, 0) < 0) { + av_freep(&s.priv_data); + goto fail; + } + + /* Now we have the actual streams */ + if (s.nb_streams != feed->nb_streams) { + av_freep(&s.priv_data); + goto fail; + } + for (i = 0; i < s.nb_streams; i++) { + memcpy(feed->streams[i]->codec, + s.streams[i]->codec, sizeof(AVCodecContext)); + } + av_freep(&s.priv_data); + } + c->buffer_ptr = c->buffer; + } + + return 0; + fail: + c->stream->feed_opened = 0; + close(c->feed_fd); + return -1; +} + +/********************************************************************/ +/* RTSP handling */ + +static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number) +{ + const char *str; + time_t ti; + char *p; + char buf2[32]; + + switch(error_number) { +#define DEF(n, c, s) case c: str = s; break; +#include "rtspcodes.h" +#undef DEF + default: + str = "Unknown Error"; + break; + } + + url_fprintf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str); + url_fprintf(c->pb, "CSeq: %d\r\n", c->seq); + + /* output GMT time */ + ti = time(NULL); + p = ctime(&ti); + strcpy(buf2, p); + p = buf2 + strlen(p) - 1; + if (*p == '\n') + *p = '\0'; + url_fprintf(c->pb, "Date: %s GMT\r\n", buf2); +} + +static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number) +{ + rtsp_reply_header(c, error_number); + url_fprintf(c->pb, "\r\n"); +} + +static int rtsp_parse_request(HTTPContext *c) +{ + const char *p, *p1, *p2; + char cmd[32]; + char url[1024]; + char protocol[32]; + char line[1024]; + ByteIOContext pb1; + int len; + RTSPHeader header1, *header = &header1; + + c->buffer_ptr[0] = '\0'; + p = c->buffer; + + get_word(cmd, sizeof(cmd), &p); + get_word(url, sizeof(url), &p); + get_word(protocol, sizeof(protocol), &p); + + pstrcpy(c->method, sizeof(c->method), cmd); + pstrcpy(c->url, sizeof(c->url), url); + pstrcpy(c->protocol, sizeof(c->protocol), protocol); + + c->pb = &pb1; + if (url_open_dyn_buf(c->pb) < 0) { + /* XXX: cannot do more */ + c->pb = NULL; /* safety */ + return -1; + } + + /* check version name */ + if (strcmp(protocol, "RTSP/1.0") != 0) { + rtsp_reply_error(c, RTSP_STATUS_VERSION); + goto the_end; + } + + /* parse each header line */ + memset(header, 0, sizeof(RTSPHeader)); + /* skip to next line */ + while (*p != '\n' && *p != '\0') + p++; + if (*p == '\n') + p++; + while (*p != '\0') { + p1 = strchr(p, '\n'); + if (!p1) + break; + p2 = p1; + if (p2 > p && p2[-1] == '\r') + p2--; + /* skip empty line */ + if (p2 == p) + break; + len = p2 - p; + if (len > sizeof(line) - 1) + len = sizeof(line) - 1; + memcpy(line, p, len); + line[len] = '\0'; + rtsp_parse_line(header, line); + p = p1 + 1; + } + + /* handle sequence number */ + c->seq = header->seq; + + if (!strcmp(cmd, "DESCRIBE")) { + rtsp_cmd_describe(c, url); + } else if (!strcmp(cmd, "OPTIONS")) { + rtsp_cmd_options(c, url); + } else if (!strcmp(cmd, "SETUP")) { + rtsp_cmd_setup(c, url, header); + } else if (!strcmp(cmd, "PLAY")) { + rtsp_cmd_play(c, url, header); + } else if (!strcmp(cmd, "PAUSE")) { + rtsp_cmd_pause(c, url, header); + } else if (!strcmp(cmd, "TEARDOWN")) { + rtsp_cmd_teardown(c, url, header); + } else { + rtsp_reply_error(c, RTSP_STATUS_METHOD); + } + the_end: + len = url_close_dyn_buf(c->pb, &c->pb_buffer); + c->pb = NULL; /* safety */ + if (len < 0) { + /* XXX: cannot do more */ + return -1; + } + c->buffer_ptr = c->pb_buffer; + c->buffer_end = c->pb_buffer + len; + c->state = RTSPSTATE_SEND_REPLY; + return 0; +} + +/* XXX: move that to rtsp.c, but would need to replace FFStream by + AVFormatContext */ +static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, + struct in_addr my_ip) +{ + ByteIOContext pb1, *pb = &pb1; + int i, payload_type, port, private_payload_type, j; + const char *ipstr, *title, *mediatype; + AVStream *st; + + if (url_open_dyn_buf(pb) < 0) + return -1; + + /* general media info */ + + url_fprintf(pb, "v=0\n"); + ipstr = inet_ntoa(my_ip); + url_fprintf(pb, "o=- 0 0 IN IP4 %s\n", ipstr); + title = stream->title; + if (title[0] == '\0') + title = "No Title"; + url_fprintf(pb, "s=%s\n", title); + if (stream->comment[0] != '\0') + url_fprintf(pb, "i=%s\n", stream->comment); + if (stream->is_multicast) { + url_fprintf(pb, "c=IN IP4 %s\n", inet_ntoa(stream->multicast_ip)); + } + /* for each stream, we output the necessary info */ + private_payload_type = RTP_PT_PRIVATE; + for(i = 0; i < stream->nb_streams; i++) { + st = stream->streams[i]; + if (st->codec->codec_id == CODEC_ID_MPEG2TS) { + mediatype = "video"; + } else { + switch(st->codec->codec_type) { + case CODEC_TYPE_AUDIO: + mediatype = "audio"; + break; + case CODEC_TYPE_VIDEO: + mediatype = "video"; + break; + default: + mediatype = "application"; + break; + } + } + /* NOTE: the port indication is not correct in case of + unicast. It is not an issue because RTSP gives it */ + payload_type = rtp_get_payload_type(st->codec); + if (payload_type < 0) + payload_type = private_payload_type++; + if (stream->is_multicast) { + port = stream->multicast_port + 2 * i; + } else { + port = 0; + } + url_fprintf(pb, "m=%s %d RTP/AVP %d\n", + mediatype, port, payload_type); + if (payload_type >= RTP_PT_PRIVATE) { + /* for private payload type, we need to give more info */ + switch(st->codec->codec_id) { + case CODEC_ID_MPEG4: + { + uint8_t *data; + url_fprintf(pb, "a=rtpmap:%d MP4V-ES/%d\n", + payload_type, 90000); + /* we must also add the mpeg4 header */ + data = st->codec->extradata; + if (data) { + url_fprintf(pb, "a=fmtp:%d config=", payload_type); + for(j=0;jcodec->extradata_size;j++) { + url_fprintf(pb, "%02x", data[j]); + } + url_fprintf(pb, "\n"); + } + } + break; + default: + /* XXX: add other codecs ? */ + goto fail; + } + } + url_fprintf(pb, "a=control:streamid=%d\n", i); + } + return url_close_dyn_buf(pb, pbuffer); + fail: + url_close_dyn_buf(pb, pbuffer); + av_free(*pbuffer); + return -1; +} + +static void rtsp_cmd_options(HTTPContext *c, const char *url) +{ +// rtsp_reply_header(c, RTSP_STATUS_OK); + url_fprintf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK"); + url_fprintf(c->pb, "CSeq: %d\r\n", c->seq); + url_fprintf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE"); + url_fprintf(c->pb, "\r\n"); +} + +static void rtsp_cmd_describe(HTTPContext *c, const char *url) +{ + FFStream *stream; + char path1[1024]; + const char *path; + uint8_t *content; + int content_length, len; + struct sockaddr_in my_addr; + + /* find which url is asked */ + url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url); + path = path1; + if (*path == '/') + path++; + + for(stream = first_stream; stream != NULL; stream = stream->next) { + if (!stream->is_feed && stream->fmt == &rtp_mux && + !strcmp(path, stream->filename)) { + goto found; + } + } + /* no stream found */ + rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */ + return; + + found: + /* prepare the media description in sdp format */ + + /* get the host IP */ + len = sizeof(my_addr); + getsockname(c->fd, (struct sockaddr *)&my_addr, &len); + content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr); + if (content_length < 0) { + rtsp_reply_error(c, RTSP_STATUS_INTERNAL); + return; + } + rtsp_reply_header(c, RTSP_STATUS_OK); + url_fprintf(c->pb, "Content-Type: application/sdp\r\n"); + url_fprintf(c->pb, "Content-Length: %d\r\n", content_length); + url_fprintf(c->pb, "\r\n"); + put_buffer(c->pb, content, content_length); +} + +static HTTPContext *find_rtp_session(const char *session_id) +{ + HTTPContext *c; + + if (session_id[0] == '\0') + return NULL; + + for(c = first_http_ctx; c != NULL; c = c->next) { + if (!strcmp(c->session_id, session_id)) + return c; + } + return NULL; +} + +static RTSPTransportField *find_transport(RTSPHeader *h, enum RTSPProtocol protocol) +{ + RTSPTransportField *th; + int i; + + for(i=0;inb_transports;i++) { + th = &h->transports[i]; + if (th->protocol == protocol) + return th; + } + return NULL; +} + +static void rtsp_cmd_setup(HTTPContext *c, const char *url, + RTSPHeader *h) +{ + FFStream *stream; + int stream_index, port; + char buf[1024]; + char path1[1024]; + const char *path; + HTTPContext *rtp_c; + RTSPTransportField *th; + struct sockaddr_in dest_addr; + RTSPActionServerSetup setup; + + /* find which url is asked */ + url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url); + path = path1; + if (*path == '/') + path++; + + /* now check each stream */ + for(stream = first_stream; stream != NULL; stream = stream->next) { + if (!stream->is_feed && stream->fmt == &rtp_mux) { + /* accept aggregate filenames only if single stream */ + if (!strcmp(path, stream->filename)) { + if (stream->nb_streams != 1) { + rtsp_reply_error(c, RTSP_STATUS_AGGREGATE); + return; + } + stream_index = 0; + goto found; + } + + for(stream_index = 0; stream_index < stream->nb_streams; + stream_index++) { + snprintf(buf, sizeof(buf), "%s/streamid=%d", + stream->filename, stream_index); + if (!strcmp(path, buf)) + goto found; + } + } + } + /* no stream found */ + rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */ + return; + found: + + /* generate session id if needed */ + if (h->session_id[0] == '\0') { + snprintf(h->session_id, sizeof(h->session_id), + "%08x%08x", (int)random(), (int)random()); + } + + /* find rtp session, and create it if none found */ + rtp_c = find_rtp_session(h->session_id); + if (!rtp_c) { + /* always prefer UDP */ + th = find_transport(h, RTSP_PROTOCOL_RTP_UDP); + if (!th) { + th = find_transport(h, RTSP_PROTOCOL_RTP_TCP); + if (!th) { + rtsp_reply_error(c, RTSP_STATUS_TRANSPORT); + return; + } + } + + rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id, + th->protocol); + if (!rtp_c) { + rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH); + return; + } + + /* open input stream */ + if (open_input_stream(rtp_c, "") < 0) { + rtsp_reply_error(c, RTSP_STATUS_INTERNAL); + return; + } + } + + /* test if stream is OK (test needed because several SETUP needs + to be done for a given file) */ + if (rtp_c->stream != stream) { + rtsp_reply_error(c, RTSP_STATUS_SERVICE); + return; + } + + /* test if stream is already set up */ + if (rtp_c->rtp_ctx[stream_index]) { + rtsp_reply_error(c, RTSP_STATUS_STATE); + return; + } + + /* check transport */ + th = find_transport(h, rtp_c->rtp_protocol); + if (!th || (th->protocol == RTSP_PROTOCOL_RTP_UDP && + th->client_port_min <= 0)) { + rtsp_reply_error(c, RTSP_STATUS_TRANSPORT); + return; + } + + /* setup default options */ + setup.transport_option[0] = '\0'; + dest_addr = rtp_c->from_addr; + dest_addr.sin_port = htons(th->client_port_min); + + /* add transport option if needed */ + if (ff_rtsp_callback) { + setup.ipaddr = ntohl(dest_addr.sin_addr.s_addr); + if (ff_rtsp_callback(RTSP_ACTION_SERVER_SETUP, rtp_c->session_id, + (char *)&setup, sizeof(setup), + stream->rtsp_option) < 0) { + rtsp_reply_error(c, RTSP_STATUS_TRANSPORT); + return; + } + dest_addr.sin_addr.s_addr = htonl(setup.ipaddr); + } + + /* setup stream */ + if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) { + rtsp_reply_error(c, RTSP_STATUS_TRANSPORT); + return; + } + + /* now everything is OK, so we can send the connection parameters */ + rtsp_reply_header(c, RTSP_STATUS_OK); + /* session ID */ + url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id); + + switch(rtp_c->rtp_protocol) { + case RTSP_PROTOCOL_RTP_UDP: + port = rtp_get_local_port(rtp_c->rtp_handles[stream_index]); + url_fprintf(c->pb, "Transport: RTP/AVP/UDP;unicast;" + "client_port=%d-%d;server_port=%d-%d", + th->client_port_min, th->client_port_min + 1, + port, port + 1); + break; + case RTSP_PROTOCOL_RTP_TCP: + url_fprintf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d", + stream_index * 2, stream_index * 2 + 1); + break; + default: + break; + } + if (setup.transport_option[0] != '\0') { + url_fprintf(c->pb, ";%s", setup.transport_option); + } + url_fprintf(c->pb, "\r\n"); + + + url_fprintf(c->pb, "\r\n"); +} + + +/* find an rtp connection by using the session ID. Check consistency + with filename */ +static HTTPContext *find_rtp_session_with_url(const char *url, + const char *session_id) +{ + HTTPContext *rtp_c; + char path1[1024]; + const char *path; + char buf[1024]; + int s; + + rtp_c = find_rtp_session(session_id); + if (!rtp_c) + return NULL; + + /* find which url is asked */ + url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url); + path = path1; + if (*path == '/') + path++; + if(!strcmp(path, rtp_c->stream->filename)) return rtp_c; + for(s=0; sstream->nb_streams; ++s) { + snprintf(buf, sizeof(buf), "%s/streamid=%d", + rtp_c->stream->filename, s); + if(!strncmp(path, buf, sizeof(buf))) { + // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1? + return rtp_c; + } + } + return NULL; +} + +static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPHeader *h) +{ + HTTPContext *rtp_c; + + rtp_c = find_rtp_session_with_url(url, h->session_id); + if (!rtp_c) { + rtsp_reply_error(c, RTSP_STATUS_SESSION); + return; + } + + if (rtp_c->state != HTTPSTATE_SEND_DATA && + rtp_c->state != HTTPSTATE_WAIT_FEED && + rtp_c->state != HTTPSTATE_READY) { + rtsp_reply_error(c, RTSP_STATUS_STATE); + return; + } + +#if 0 + /* XXX: seek in stream */ + if (h->range_start != AV_NOPTS_VALUE) { + printf("range_start=%0.3f\n", (double)h->range_start / AV_TIME_BASE); + av_seek_frame(rtp_c->fmt_in, -1, h->range_start); + } +#endif + + rtp_c->state = HTTPSTATE_SEND_DATA; + + /* now everything is OK, so we can send the connection parameters */ + rtsp_reply_header(c, RTSP_STATUS_OK); + /* session ID */ + url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id); + url_fprintf(c->pb, "\r\n"); +} + +static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPHeader *h) +{ + HTTPContext *rtp_c; + + rtp_c = find_rtp_session_with_url(url, h->session_id); + if (!rtp_c) { + rtsp_reply_error(c, RTSP_STATUS_SESSION); + return; + } + + if (rtp_c->state != HTTPSTATE_SEND_DATA && + rtp_c->state != HTTPSTATE_WAIT_FEED) { + rtsp_reply_error(c, RTSP_STATUS_STATE); + return; + } + + rtp_c->state = HTTPSTATE_READY; + rtp_c->first_pts = AV_NOPTS_VALUE; + /* now everything is OK, so we can send the connection parameters */ + rtsp_reply_header(c, RTSP_STATUS_OK); + /* session ID */ + url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id); + url_fprintf(c->pb, "\r\n"); +} + +static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPHeader *h) +{ + HTTPContext *rtp_c; + + rtp_c = find_rtp_session_with_url(url, h->session_id); + if (!rtp_c) { + rtsp_reply_error(c, RTSP_STATUS_SESSION); + return; + } + + /* abort the session */ + close_connection(rtp_c); + + if (ff_rtsp_callback) { + ff_rtsp_callback(RTSP_ACTION_SERVER_TEARDOWN, rtp_c->session_id, + NULL, 0, + rtp_c->stream->rtsp_option); + } + + /* now everything is OK, so we can send the connection parameters */ + rtsp_reply_header(c, RTSP_STATUS_OK); + /* session ID */ + url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id); + url_fprintf(c->pb, "\r\n"); +} + + +/********************************************************************/ +/* RTP handling */ + +static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr, + FFStream *stream, const char *session_id, + enum RTSPProtocol rtp_protocol) +{ + HTTPContext *c = NULL; + const char *proto_str; + + /* XXX: should output a warning page when coming + close to the connection limit */ + if (nb_connections >= nb_max_connections) + goto fail; + + /* add a new connection */ + c = av_mallocz(sizeof(HTTPContext)); + if (!c) + goto fail; + + c->fd = -1; + c->poll_entry = NULL; + c->from_addr = *from_addr; + c->buffer_size = IOBUFFER_INIT_SIZE; + c->buffer = av_malloc(c->buffer_size); + if (!c->buffer) + goto fail; + nb_connections++; + c->stream = stream; + pstrcpy(c->session_id, sizeof(c->session_id), session_id); + c->state = HTTPSTATE_READY; + c->is_packetized = 1; + c->rtp_protocol = rtp_protocol; + + /* protocol is shown in statistics */ + switch(c->rtp_protocol) { + case RTSP_PROTOCOL_RTP_UDP_MULTICAST: + proto_str = "MCAST"; + break; + case RTSP_PROTOCOL_RTP_UDP: + proto_str = "UDP"; + break; + case RTSP_PROTOCOL_RTP_TCP: + proto_str = "TCP"; + break; + default: + proto_str = "???"; + break; + } + pstrcpy(c->protocol, sizeof(c->protocol), "RTP/"); + pstrcat(c->protocol, sizeof(c->protocol), proto_str); + + current_bandwidth += stream->bandwidth; + + c->next = first_http_ctx; + first_http_ctx = c; + return c; + + fail: + if (c) { + av_free(c->buffer); + av_free(c); + } + return NULL; +} + +/* add a new RTP stream in an RTP connection (used in RTSP SETUP + command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is + used. */ +static int rtp_new_av_stream(HTTPContext *c, + int stream_index, struct sockaddr_in *dest_addr, + HTTPContext *rtsp_c) +{ + AVFormatContext *ctx; + AVStream *st; + char *ipaddr; + URLContext *h; + uint8_t *dummy_buf; + char buf2[32]; + int max_packet_size; + + /* now we can open the relevant output stream */ + ctx = av_alloc_format_context(); + if (!ctx) + return -1; + ctx->oformat = &rtp_mux; + + st = av_mallocz(sizeof(AVStream)); + if (!st) + goto fail; + st->codec= avcodec_alloc_context(); + ctx->nb_streams = 1; + ctx->streams[0] = st; + + if (!c->stream->feed || + c->stream->feed == c->stream) { + memcpy(st, c->stream->streams[stream_index], sizeof(AVStream)); + } else { + memcpy(st, + c->stream->feed->streams[c->stream->feed_streams[stream_index]], + sizeof(AVStream)); + } + + /* build destination RTP address */ + ipaddr = inet_ntoa(dest_addr->sin_addr); + + switch(c->rtp_protocol) { + case RTSP_PROTOCOL_RTP_UDP: + case RTSP_PROTOCOL_RTP_UDP_MULTICAST: + /* RTP/UDP case */ + + /* XXX: also pass as parameter to function ? */ + if (c->stream->is_multicast) { + int ttl; + ttl = c->stream->multicast_ttl; + if (!ttl) + ttl = 16; + snprintf(ctx->filename, sizeof(ctx->filename), + "rtp://%s:%d?multicast=1&ttl=%d", + ipaddr, ntohs(dest_addr->sin_port), ttl); + } else { + snprintf(ctx->filename, sizeof(ctx->filename), + "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port)); + } + + if (url_open(&h, ctx->filename, URL_WRONLY) < 0) + goto fail; + c->rtp_handles[stream_index] = h; + max_packet_size = url_get_max_packet_size(h); + break; + case RTSP_PROTOCOL_RTP_TCP: + /* RTP/TCP case */ + c->rtsp_c = rtsp_c; + max_packet_size = RTSP_TCP_MAX_PACKET_SIZE; + break; + default: + goto fail; + } + + http_log("%s:%d - - [%s] \"PLAY %s/streamid=%d %s\"\n", + ipaddr, ntohs(dest_addr->sin_port), + ctime1(buf2), + c->stream->filename, stream_index, c->protocol); + + /* normally, no packets should be output here, but the packet size may be checked */ + if (url_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) { + /* XXX: close stream */ + goto fail; + } + av_set_parameters(ctx, NULL); + if (av_write_header(ctx) < 0) { + fail: + if (h) + url_close(h); + av_free(ctx); + return -1; + } + url_close_dyn_buf(&ctx->pb, &dummy_buf); + av_free(dummy_buf); + + c->rtp_ctx[stream_index] = ctx; + return 0; +} + +/********************************************************************/ +/* ffserver initialization */ + +static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec) +{ + AVStream *fst; + + fst = av_mallocz(sizeof(AVStream)); + if (!fst) + return NULL; + fst->codec= avcodec_alloc_context(); + fst->priv_data = av_mallocz(sizeof(FeedData)); + memcpy(fst->codec, codec, sizeof(AVCodecContext)); + fst->codec->coded_frame = &dummy_frame; + fst->index = stream->nb_streams; + av_set_pts_info(fst, 33, 1, 90000); + stream->streams[stream->nb_streams++] = fst; + return fst; +} + +/* return the stream number in the feed */ +static int add_av_stream(FFStream *feed, AVStream *st) +{ + AVStream *fst; + AVCodecContext *av, *av1; + int i; + + av = st->codec; + for(i=0;inb_streams;i++) { + st = feed->streams[i]; + av1 = st->codec; + if (av1->codec_id == av->codec_id && + av1->codec_type == av->codec_type && + av1->bit_rate == av->bit_rate) { + + switch(av->codec_type) { + case CODEC_TYPE_AUDIO: + if (av1->channels == av->channels && + av1->sample_rate == av->sample_rate) + goto found; + break; + case CODEC_TYPE_VIDEO: + if (av1->width == av->width && + av1->height == av->height && + av1->time_base.den == av->time_base.den && + av1->time_base.num == av->time_base.num && + av1->gop_size == av->gop_size) + goto found; + break; + default: + av_abort(); + } + } + } + + fst = add_av_stream1(feed, av); + if (!fst) + return -1; + return feed->nb_streams - 1; + found: + return i; +} + +static void remove_stream(FFStream *stream) +{ + FFStream **ps; + ps = &first_stream; + while (*ps != NULL) { + if (*ps == stream) { + *ps = (*ps)->next; + } else { + ps = &(*ps)->next; + } + } +} + +/* specific mpeg4 handling : we extract the raw parameters */ +static void extract_mpeg4_header(AVFormatContext *infile) +{ + int mpeg4_count, i, size; + AVPacket pkt; + AVStream *st; + const uint8_t *p; + + mpeg4_count = 0; + for(i=0;inb_streams;i++) { + st = infile->streams[i]; + if (st->codec->codec_id == CODEC_ID_MPEG4 && + st->codec->extradata_size == 0) { + mpeg4_count++; + } + } + if (!mpeg4_count) + return; + + printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename); + while (mpeg4_count > 0) { + if (av_read_packet(infile, &pkt) < 0) + break; + st = infile->streams[pkt.stream_index]; + if (st->codec->codec_id == CODEC_ID_MPEG4 && + st->codec->extradata_size == 0) { + av_freep(&st->codec->extradata); + /* fill extradata with the header */ + /* XXX: we make hard suppositions here ! */ + p = pkt.data; + while (p < pkt.data + pkt.size - 4) { + /* stop when vop header is found */ + if (p[0] == 0x00 && p[1] == 0x00 && + p[2] == 0x01 && p[3] == 0xb6) { + size = p - pkt.data; + // av_hex_dump(pkt.data, size); + st->codec->extradata = av_malloc(size); + st->codec->extradata_size = size; + memcpy(st->codec->extradata, pkt.data, size); + break; + } + p++; + } + mpeg4_count--; + } + av_free_packet(&pkt); + } +} + +/* compute the needed AVStream for each file */ +static void build_file_streams(void) +{ + FFStream *stream, *stream_next; + AVFormatContext *infile; + int i; + + /* gather all streams */ + for(stream = first_stream; stream != NULL; stream = stream_next) { + stream_next = stream->next; + if (stream->stream_type == STREAM_TYPE_LIVE && + !stream->feed) { + /* the stream comes from a file */ + /* try to open the file */ + /* open stream */ + stream->ap_in = av_mallocz(sizeof(AVFormatParameters)); + if (stream->fmt == &rtp_mux) { + /* specific case : if transport stream output to RTP, + we use a raw transport stream reader */ + stream->ap_in->mpeg2ts_raw = 1; + stream->ap_in->mpeg2ts_compute_pcr = 1; + } + + if (av_open_input_file(&infile, stream->feed_filename, + stream->ifmt, 0, stream->ap_in) < 0) { + http_log("%s not found", stream->feed_filename); + /* remove stream (no need to spend more time on it) */ + fail: + remove_stream(stream); + } else { + /* find all the AVStreams inside and reference them in + 'stream' */ + if (av_find_stream_info(infile) < 0) { + http_log("Could not find codec parameters from '%s'", + stream->feed_filename); + av_close_input_file(infile); + goto fail; + } + extract_mpeg4_header(infile); + + for(i=0;inb_streams;i++) { + add_av_stream1(stream, infile->streams[i]->codec); + } + av_close_input_file(infile); + } + } + } +} + +/* compute the needed AVStream for each feed */ +static void build_feed_streams(void) +{ + FFStream *stream, *feed; + int i; + + /* gather all streams */ + for(stream = first_stream; stream != NULL; stream = stream->next) { + feed = stream->feed; + if (feed) { + if (!stream->is_feed) { + /* we handle a stream coming from a feed */ + for(i=0;inb_streams;i++) { + stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]); + } + } + } + } + + /* gather all streams */ + for(stream = first_stream; stream != NULL; stream = stream->next) { + feed = stream->feed; + if (feed) { + if (stream->is_feed) { + for(i=0;inb_streams;i++) { + stream->feed_streams[i] = i; + } + } + } + } + + /* create feed files if needed */ + for(feed = first_feed; feed != NULL; feed = feed->next_feed) { + int fd; + + if (url_exist(feed->feed_filename)) { + /* See if it matches */ + AVFormatContext *s; + int matches = 0; + + if (av_open_input_file(&s, feed->feed_filename, NULL, FFM_PACKET_SIZE, NULL) >= 0) { + /* Now see if it matches */ + if (s->nb_streams == feed->nb_streams) { + matches = 1; + for(i=0;inb_streams;i++) { + AVStream *sf, *ss; + sf = feed->streams[i]; + ss = s->streams[i]; + + if (sf->index != ss->index || + sf->id != ss->id) { + printf("Index & Id do not match for stream %d (%s)\n", + i, feed->feed_filename); + matches = 0; + } else { + AVCodecContext *ccf, *ccs; + + ccf = sf->codec; + ccs = ss->codec; +#define CHECK_CODEC(x) (ccf->x != ccs->x) + + if (CHECK_CODEC(codec) || CHECK_CODEC(codec_type)) { + printf("Codecs do not match for stream %d\n", i); + matches = 0; + } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) { + printf("Codec bitrates do not match for stream %d\n", i); + matches = 0; + } else if (ccf->codec_type == CODEC_TYPE_VIDEO) { + if (CHECK_CODEC(time_base.den) || + CHECK_CODEC(time_base.num) || + CHECK_CODEC(width) || + CHECK_CODEC(height)) { + printf("Codec width, height and framerate do not match for stream %d\n", i); + matches = 0; + } + } else if (ccf->codec_type == CODEC_TYPE_AUDIO) { + if (CHECK_CODEC(sample_rate) || + CHECK_CODEC(channels) || + CHECK_CODEC(frame_size)) { + printf("Codec sample_rate, channels, frame_size do not match for stream %d\n", i); + matches = 0; + } + } else { + printf("Unknown codec type\n"); + matches = 0; + } + } + if (!matches) { + break; + } + } + } else { + printf("Deleting feed file '%s' as stream counts differ (%d != %d)\n", + feed->feed_filename, s->nb_streams, feed->nb_streams); + } + + av_close_input_file(s); + } else { + printf("Deleting feed file '%s' as it appears to be corrupt\n", + feed->feed_filename); + } + if (!matches) { + if (feed->readonly) { + printf("Unable to delete feed file '%s' as it is marked readonly\n", + feed->feed_filename); + exit(1); + } + unlink(feed->feed_filename); + } + } + if (!url_exist(feed->feed_filename)) { + AVFormatContext s1, *s = &s1; + + if (feed->readonly) { + printf("Unable to create feed file '%s' as it is marked readonly\n", + feed->feed_filename); + exit(1); + } + + /* only write the header of the ffm file */ + if (url_fopen(&s->pb, feed->feed_filename, URL_WRONLY) < 0) { + fprintf(stderr, "Could not open output feed file '%s'\n", + feed->feed_filename); + exit(1); + } + s->oformat = feed->fmt; + s->nb_streams = feed->nb_streams; + for(i=0;inb_streams;i++) { + AVStream *st; + st = feed->streams[i]; + s->streams[i] = st; + } + av_set_parameters(s, NULL); + av_write_header(s); + /* XXX: need better api */ + av_freep(&s->priv_data); + url_fclose(&s->pb); + } + /* get feed size and write index */ + fd = open(feed->feed_filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Could not open output feed file '%s'\n", + feed->feed_filename); + exit(1); + } + + feed->feed_write_index = ffm_read_write_index(fd); + feed->feed_size = lseek(fd, 0, SEEK_END); + /* ensure that we do not wrap before the end of file */ + if (feed->feed_max_size && feed->feed_max_size < feed->feed_size) + feed->feed_max_size = feed->feed_size; + + close(fd); + } +} + +/* compute the bandwidth used by each stream */ +static void compute_bandwidth(void) +{ + int bandwidth, i; + FFStream *stream; + + for(stream = first_stream; stream != NULL; stream = stream->next) { + bandwidth = 0; + for(i=0;inb_streams;i++) { + AVStream *st = stream->streams[i]; + switch(st->codec->codec_type) { + case CODEC_TYPE_AUDIO: + case CODEC_TYPE_VIDEO: + bandwidth += st->codec->bit_rate; + break; + default: + break; + } + } + stream->bandwidth = (bandwidth + 999) / 1000; + } +} + +static void get_arg(char *buf, int buf_size, const char **pp) +{ + const char *p; + char *q; + int quote; + + p = *pp; + while (isspace(*p)) p++; + q = buf; + quote = 0; + if (*p == '\"' || *p == '\'') + quote = *p++; + for(;;) { + if (quote) { + if (*p == quote) + break; + } else { + if (isspace(*p)) + break; + } + if (*p == '\0') + break; + if ((q - buf) < buf_size - 1) + *q++ = *p; + p++; + } + *q = '\0'; + if (quote && *p == quote) + p++; + *pp = p; +} + +/* add a codec and set the default parameters */ +static void add_codec(FFStream *stream, AVCodecContext *av) +{ + AVStream *st; + + /* compute default parameters */ + switch(av->codec_type) { + case CODEC_TYPE_AUDIO: + if (av->bit_rate == 0) + av->bit_rate = 64000; + if (av->sample_rate == 0) + av->sample_rate = 22050; + if (av->channels == 0) + av->channels = 1; + break; + case CODEC_TYPE_VIDEO: + if (av->bit_rate == 0) + av->bit_rate = 64000; + if (av->time_base.num == 0){ + av->time_base.den = 5; + av->time_base.num = 1; + } + if (av->width == 0 || av->height == 0) { + av->width = 160; + av->height = 128; + } + /* Bitrate tolerance is less for streaming */ + if (av->bit_rate_tolerance == 0) + av->bit_rate_tolerance = av->bit_rate / 4; + if (av->qmin == 0) + av->qmin = 3; + if (av->qmax == 0) + av->qmax = 31; + if (av->max_qdiff == 0) + av->max_qdiff = 3; + av->qcompress = 0.5; + av->qblur = 0.5; + + if (!av->nsse_weight) + av->nsse_weight = 8; + + av->frame_skip_cmp = FF_CMP_DCTMAX; + av->me_method = ME_EPZS; + av->rc_buffer_aggressivity = 1.0; + + if (!av->rc_eq) + av->rc_eq = "tex^qComp"; + if (!av->i_quant_factor) + av->i_quant_factor = -0.8; + if (!av->b_quant_factor) + av->b_quant_factor = 1.25; + if (!av->b_quant_offset) + av->b_quant_offset = 1.25; + if (!av->rc_max_rate) + av->rc_max_rate = av->bit_rate * 2; + + if (av->rc_max_rate && !av->rc_buffer_size) { + av->rc_buffer_size = av->rc_max_rate; + } + + + break; + default: + av_abort(); + } + + st = av_mallocz(sizeof(AVStream)); + if (!st) + return; + st->codec = avcodec_alloc_context(); + stream->streams[stream->nb_streams++] = st; + memcpy(st->codec, av, sizeof(AVCodecContext)); +} + +static int opt_audio_codec(const char *arg) +{ + AVCodec *p; + + p = first_avcodec; + while (p) { + if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_AUDIO) + break; + p = p->next; + } + if (p == NULL) { + return CODEC_ID_NONE; + } + + return p->id; +} + +static int opt_video_codec(const char *arg) +{ + AVCodec *p; + + p = first_avcodec; + while (p) { + if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_VIDEO) + break; + p = p->next; + } + if (p == NULL) { + return CODEC_ID_NONE; + } + + return p->id; +} + +/* simplistic plugin support */ + +#ifdef CONFIG_HAVE_DLOPEN +void load_module(const char *filename) +{ + void *dll; + void (*init_func)(void); + dll = dlopen(filename, RTLD_NOW); + if (!dll) { + fprintf(stderr, "Could not load module '%s' - %s\n", + filename, dlerror()); + return; + } + + init_func = dlsym(dll, "ffserver_module_init"); + if (!init_func) { + fprintf(stderr, + "%s: init function 'ffserver_module_init()' not found\n", + filename); + dlclose(dll); + } + + init_func(); +} +#endif + +static int parse_ffconfig(const char *filename) +{ + FILE *f; + char line[1024]; + char cmd[64]; + char arg[1024]; + const char *p; + int val, errors, line_num; + FFStream **last_stream, *stream, *redirect; + FFStream **last_feed, *feed; + AVCodecContext audio_enc, video_enc; + int audio_id, video_id; + + f = fopen(filename, "r"); + if (!f) { + perror(filename); + return -1; + } + + errors = 0; + line_num = 0; + first_stream = NULL; + last_stream = &first_stream; + first_feed = NULL; + last_feed = &first_feed; + stream = NULL; + feed = NULL; + redirect = NULL; + audio_id = CODEC_ID_NONE; + video_id = CODEC_ID_NONE; + for(;;) { + if (fgets(line, sizeof(line), f) == NULL) + break; + line_num++; + p = line; + while (isspace(*p)) + p++; + if (*p == '\0' || *p == '#') + continue; + + get_arg(cmd, sizeof(cmd), &p); + + if (!strcasecmp(cmd, "Port")) { + get_arg(arg, sizeof(arg), &p); + my_http_addr.sin_port = htons (atoi(arg)); + } else if (!strcasecmp(cmd, "BindAddress")) { + get_arg(arg, sizeof(arg), &p); + if (!inet_aton(arg, &my_http_addr.sin_addr)) { + fprintf(stderr, "%s:%d: Invalid IP address: %s\n", + filename, line_num, arg); + errors++; + } + } else if (!strcasecmp(cmd, "NoDaemon")) { + ffserver_daemon = 0; + } else if (!strcasecmp(cmd, "RTSPPort")) { + get_arg(arg, sizeof(arg), &p); + my_rtsp_addr.sin_port = htons (atoi(arg)); + } else if (!strcasecmp(cmd, "RTSPBindAddress")) { + get_arg(arg, sizeof(arg), &p); + if (!inet_aton(arg, &my_rtsp_addr.sin_addr)) { + fprintf(stderr, "%s:%d: Invalid IP address: %s\n", + filename, line_num, arg); + errors++; + } + } else if (!strcasecmp(cmd, "MaxClients")) { + get_arg(arg, sizeof(arg), &p); + val = atoi(arg); + if (val < 1 || val > HTTP_MAX_CONNECTIONS) { + fprintf(stderr, "%s:%d: Invalid MaxClients: %s\n", + filename, line_num, arg); + errors++; + } else { + nb_max_connections = val; + } + } else if (!strcasecmp(cmd, "MaxBandwidth")) { + get_arg(arg, sizeof(arg), &p); + val = atoi(arg); + if (val < 10 || val > 100000) { + fprintf(stderr, "%s:%d: Invalid MaxBandwidth: %s\n", + filename, line_num, arg); + errors++; + } else { + max_bandwidth = val; + } + } else if (!strcasecmp(cmd, "CustomLog")) { + get_arg(logfilename, sizeof(logfilename), &p); + } else if (!strcasecmp(cmd, "next; + /* add in feed list */ + *last_feed = feed; + last_feed = &feed->next_feed; + + get_arg(feed->filename, sizeof(feed->filename), &p); + q = strrchr(feed->filename, '>'); + if (*q) + *q = '\0'; + feed->fmt = guess_format("ffm", NULL, NULL); + /* defaut feed file */ + snprintf(feed->feed_filename, sizeof(feed->feed_filename), + "/tmp/%s.ffm", feed->filename); + feed->feed_max_size = 5 * 1024 * 1024; + feed->is_feed = 1; + feed->feed = feed; /* self feeding :-) */ + } + } else if (!strcasecmp(cmd, "Launch")) { + if (feed) { + int i; + + feed->child_argv = (char **) av_mallocz(64 * sizeof(char *)); + + for (i = 0; i < 62; i++) { + char argbuf[256]; + + get_arg(argbuf, sizeof(argbuf), &p); + if (!argbuf[0]) + break; + + feed->child_argv[i] = av_malloc(strlen(argbuf) + 1); + strcpy(feed->child_argv[i], argbuf); + } + + feed->child_argv[i] = av_malloc(30 + strlen(feed->filename)); + + snprintf(feed->child_argv[i], 30+strlen(feed->filename), + "http://%s:%d/%s", + (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" : + inet_ntoa(my_http_addr.sin_addr), + ntohs(my_http_addr.sin_port), feed->filename); + + if (ffserver_debug) + { + int j; + fprintf(stdout, "Launch commandline: "); + for (j = 0; j <= i; j++) + fprintf(stdout, "%s ", feed->child_argv[j]); + fprintf(stdout, "\n"); + } + } + } else if (!strcasecmp(cmd, "ReadOnlyFile")) { + if (feed) { + get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p); + feed->readonly = 1; + } else if (stream) { + get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); + } + } else if (!strcasecmp(cmd, "File")) { + if (feed) { + get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p); + } else if (stream) { + get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); + } + } else if (!strcasecmp(cmd, "FileMaxSize")) { + if (feed) { + const char *p1; + double fsize; + + get_arg(arg, sizeof(arg), &p); + p1 = arg; + fsize = strtod(p1, (char **)&p1); + switch(toupper(*p1)) { + case 'K': + fsize *= 1024; + break; + case 'M': + fsize *= 1024 * 1024; + break; + case 'G': + fsize *= 1024 * 1024 * 1024; + break; + } + feed->feed_max_size = (int64_t)fsize; + } + } else if (!strcasecmp(cmd, "")) { + if (!feed) { + fprintf(stderr, "%s:%d: No corresponding for \n", + filename, line_num); + errors++; +#if 0 + } else { + /* Make sure that we start out clean */ + if (unlink(feed->feed_filename) < 0 + && errno != ENOENT) { + fprintf(stderr, "%s:%d: Unable to clean old feed file '%s': %s\n", + filename, line_num, feed->feed_filename, strerror(errno)); + errors++; + } +#endif + } + feed = NULL; + } else if (!strcasecmp(cmd, "next; + + get_arg(stream->filename, sizeof(stream->filename), &p); + q = strrchr(stream->filename, '>'); + if (*q) + *q = '\0'; + stream->fmt = guess_stream_format(NULL, stream->filename, NULL); + memset(&audio_enc, 0, sizeof(AVCodecContext)); + memset(&video_enc, 0, sizeof(AVCodecContext)); + audio_id = CODEC_ID_NONE; + video_id = CODEC_ID_NONE; + if (stream->fmt) { + audio_id = stream->fmt->audio_codec; + video_id = stream->fmt->video_codec; + } + } + } else if (!strcasecmp(cmd, "Feed")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + FFStream *sfeed; + + sfeed = first_feed; + while (sfeed != NULL) { + if (!strcmp(sfeed->filename, arg)) + break; + sfeed = sfeed->next_feed; + } + if (!sfeed) { + fprintf(stderr, "%s:%d: feed '%s' not defined\n", + filename, line_num, arg); + } else { + stream->feed = sfeed; + } + } + } else if (!strcasecmp(cmd, "Format")) { + get_arg(arg, sizeof(arg), &p); + if (!strcmp(arg, "status")) { + stream->stream_type = STREAM_TYPE_STATUS; + stream->fmt = NULL; + } else { + stream->stream_type = STREAM_TYPE_LIVE; + /* jpeg cannot be used here, so use single frame jpeg */ + if (!strcmp(arg, "jpeg")) + strcpy(arg, "mjpeg"); + stream->fmt = guess_stream_format(arg, NULL, NULL); + if (!stream->fmt) { + fprintf(stderr, "%s:%d: Unknown Format: %s\n", + filename, line_num, arg); + errors++; + } + } + if (stream->fmt) { + audio_id = stream->fmt->audio_codec; + video_id = stream->fmt->video_codec; + } + } else if (!strcasecmp(cmd, "InputFormat")) { + stream->ifmt = av_find_input_format(arg); + if (!stream->ifmt) { + fprintf(stderr, "%s:%d: Unknown input format: %s\n", + filename, line_num, arg); + } + } else if (!strcasecmp(cmd, "FaviconURL")) { + if (stream && stream->stream_type == STREAM_TYPE_STATUS) { + get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); + } else { + fprintf(stderr, "%s:%d: FaviconURL only permitted for status streams\n", + filename, line_num); + errors++; + } + } else if (!strcasecmp(cmd, "Author")) { + if (stream) { + get_arg(stream->author, sizeof(stream->author), &p); + } + } else if (!strcasecmp(cmd, "Comment")) { + if (stream) { + get_arg(stream->comment, sizeof(stream->comment), &p); + } + } else if (!strcasecmp(cmd, "Copyright")) { + if (stream) { + get_arg(stream->copyright, sizeof(stream->copyright), &p); + } + } else if (!strcasecmp(cmd, "Title")) { + if (stream) { + get_arg(stream->title, sizeof(stream->title), &p); + } + } else if (!strcasecmp(cmd, "Preroll")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + stream->prebuffer = atof(arg) * 1000; + } + } else if (!strcasecmp(cmd, "StartSendOnKey")) { + if (stream) { + stream->send_on_key = 1; + } + } else if (!strcasecmp(cmd, "AudioCodec")) { + get_arg(arg, sizeof(arg), &p); + audio_id = opt_audio_codec(arg); + if (audio_id == CODEC_ID_NONE) { + fprintf(stderr, "%s:%d: Unknown AudioCodec: %s\n", + filename, line_num, arg); + errors++; + } + } else if (!strcasecmp(cmd, "VideoCodec")) { + get_arg(arg, sizeof(arg), &p); + video_id = opt_video_codec(arg); + if (video_id == CODEC_ID_NONE) { + fprintf(stderr, "%s:%d: Unknown VideoCodec: %s\n", + filename, line_num, arg); + errors++; + } + } else if (!strcasecmp(cmd, "MaxTime")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + stream->max_time = atof(arg) * 1000; + } + } else if (!strcasecmp(cmd, "AudioBitRate")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + audio_enc.bit_rate = atoi(arg) * 1000; + } + } else if (!strcasecmp(cmd, "AudioChannels")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + audio_enc.channels = atoi(arg); + } + } else if (!strcasecmp(cmd, "AudioSampleRate")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + audio_enc.sample_rate = atoi(arg); + } + } else if (!strcasecmp(cmd, "AudioQuality")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { +// audio_enc.quality = atof(arg) * 1000; + } + } else if (!strcasecmp(cmd, "VideoBitRateRange")) { + if (stream) { + int minrate, maxrate; + + get_arg(arg, sizeof(arg), &p); + + if (sscanf(arg, "%d-%d", &minrate, &maxrate) == 2) { + video_enc.rc_min_rate = minrate * 1000; + video_enc.rc_max_rate = maxrate * 1000; + } else { + fprintf(stderr, "%s:%d: Incorrect format for VideoBitRateRange -- should be -: %s\n", + filename, line_num, arg); + errors++; + } + } + } else if (!strcasecmp(cmd, "Debug")) { + if (stream) { + get_arg(arg, sizeof(arg), &p); + video_enc.debug = strtol(arg,0,0); + } + } else if (!strcasecmp(cmd, "Strict")) { + if (stream) { + get_arg(arg, sizeof(arg), &p); + video_enc.strict_std_compliance = atoi(arg); + } + } else if (!strcasecmp(cmd, "VideoBufferSize")) { + if (stream) { + get_arg(arg, sizeof(arg), &p); + video_enc.rc_buffer_size = atoi(arg) * 8*1024; + } + } else if (!strcasecmp(cmd, "VideoBitRateTolerance")) { + if (stream) { + get_arg(arg, sizeof(arg), &p); + video_enc.bit_rate_tolerance = atoi(arg) * 1000; + } + } else if (!strcasecmp(cmd, "VideoBitRate")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.bit_rate = atoi(arg) * 1000; + } + } else if (!strcasecmp(cmd, "VideoSize")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + parse_image_size(&video_enc.width, &video_enc.height, arg); + if ((video_enc.width % 16) != 0 || + (video_enc.height % 16) != 0) { + fprintf(stderr, "%s:%d: Image size must be a multiple of 16\n", + filename, line_num); + errors++; + } + } + } else if (!strcasecmp(cmd, "VideoFrameRate")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.time_base.num= DEFAULT_FRAME_RATE_BASE; + video_enc.time_base.den = (int)(strtod(arg, NULL) * video_enc.time_base.num); + } + } else if (!strcasecmp(cmd, "VideoGopSize")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.gop_size = atoi(arg); + } + } else if (!strcasecmp(cmd, "VideoIntraOnly")) { + if (stream) { + video_enc.gop_size = 1; + } + } else if (!strcasecmp(cmd, "VideoHighQuality")) { + if (stream) { + video_enc.mb_decision = FF_MB_DECISION_BITS; + } + } else if (!strcasecmp(cmd, "Video4MotionVector")) { + if (stream) { + video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove + video_enc.flags |= CODEC_FLAG_4MV; + } + } else if (!strcasecmp(cmd, "BitExact")) { + if (stream) { + video_enc.flags |= CODEC_FLAG_BITEXACT; + } + } else if (!strcasecmp(cmd, "DctFastint")) { + if (stream) { + video_enc.dct_algo = FF_DCT_FASTINT; + } + } else if (!strcasecmp(cmd, "IdctSimple")) { + if (stream) { + video_enc.idct_algo = FF_IDCT_SIMPLE; + } + } else if (!strcasecmp(cmd, "Qscale")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.flags |= CODEC_FLAG_QSCALE; + video_enc.global_quality = FF_QP2LAMBDA * atoi(arg); + } + } else if (!strcasecmp(cmd, "VideoQDiff")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.max_qdiff = atoi(arg); + if (video_enc.max_qdiff < 1 || video_enc.max_qdiff > 31) { + fprintf(stderr, "%s:%d: VideoQDiff out of range\n", + filename, line_num); + errors++; + } + } + } else if (!strcasecmp(cmd, "VideoQMax")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.qmax = atoi(arg); + if (video_enc.qmax < 1 || video_enc.qmax > 31) { + fprintf(stderr, "%s:%d: VideoQMax out of range\n", + filename, line_num); + errors++; + } + } + } else if (!strcasecmp(cmd, "VideoQMin")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.qmin = atoi(arg); + if (video_enc.qmin < 1 || video_enc.qmin > 31) { + fprintf(stderr, "%s:%d: VideoQMin out of range\n", + filename, line_num); + errors++; + } + } + } else if (!strcasecmp(cmd, "LumaElim")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.luma_elim_threshold = atoi(arg); + } + } else if (!strcasecmp(cmd, "ChromaElim")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.chroma_elim_threshold = atoi(arg); + } + } else if (!strcasecmp(cmd, "LumiMask")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.lumi_masking = atof(arg); + } + } else if (!strcasecmp(cmd, "DarkMask")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + video_enc.dark_masking = atof(arg); + } + } else if (!strcasecmp(cmd, "NoVideo")) { + video_id = CODEC_ID_NONE; + } else if (!strcasecmp(cmd, "NoAudio")) { + audio_id = CODEC_ID_NONE; + } else if (!strcasecmp(cmd, "ACL")) { + IPAddressACL acl; + struct hostent *he; + + get_arg(arg, sizeof(arg), &p); + if (strcasecmp(arg, "allow") == 0) { + acl.action = IP_ALLOW; + } else if (strcasecmp(arg, "deny") == 0) { + acl.action = IP_DENY; + } else { + fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n", + filename, line_num, arg); + errors++; + } + + get_arg(arg, sizeof(arg), &p); + + he = gethostbyname(arg); + if (!he) { + fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n", + filename, line_num, arg); + errors++; + } else { + /* Only take the first */ + acl.first.s_addr = ntohl(((struct in_addr *) he->h_addr_list[0])->s_addr); + acl.last = acl.first; + } + + get_arg(arg, sizeof(arg), &p); + + if (arg[0]) { + he = gethostbyname(arg); + if (!he) { + fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n", + filename, line_num, arg); + errors++; + } else { + /* Only take the first */ + acl.last.s_addr = ntohl(((struct in_addr *) he->h_addr_list[0])->s_addr); + } + } + + if (!errors) { + IPAddressACL *nacl = (IPAddressACL *) av_mallocz(sizeof(*nacl)); + IPAddressACL **naclp = 0; + + *nacl = acl; + nacl->next = 0; + + if (stream) { + naclp = &stream->acl; + } else if (feed) { + naclp = &feed->acl; + } else { + fprintf(stderr, "%s:%d: ACL found not in or \n", + filename, line_num); + errors++; + } + + if (naclp) { + while (*naclp) + naclp = &(*naclp)->next; + + *naclp = nacl; + } + } + } else if (!strcasecmp(cmd, "RTSPOption")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + av_freep(&stream->rtsp_option); + /* XXX: av_strdup ? */ + stream->rtsp_option = av_malloc(strlen(arg) + 1); + if (stream->rtsp_option) { + strcpy(stream->rtsp_option, arg); + } + } + } else if (!strcasecmp(cmd, "MulticastAddress")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + if (!inet_aton(arg, &stream->multicast_ip)) { + fprintf(stderr, "%s:%d: Invalid IP address: %s\n", + filename, line_num, arg); + errors++; + } + stream->is_multicast = 1; + stream->loop = 1; /* default is looping */ + } + } else if (!strcasecmp(cmd, "MulticastPort")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + stream->multicast_port = atoi(arg); + } + } else if (!strcasecmp(cmd, "MulticastTTL")) { + get_arg(arg, sizeof(arg), &p); + if (stream) { + stream->multicast_ttl = atoi(arg); + } + } else if (!strcasecmp(cmd, "NoLoop")) { + if (stream) { + stream->loop = 0; + } + } else if (!strcasecmp(cmd, "")) { + if (!stream) { + fprintf(stderr, "%s:%d: No corresponding for \n", + filename, line_num); + errors++; + } + if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) { + if (audio_id != CODEC_ID_NONE) { + audio_enc.codec_type = CODEC_TYPE_AUDIO; + audio_enc.codec_id = audio_id; + add_codec(stream, &audio_enc); + } + if (video_id != CODEC_ID_NONE) { + video_enc.codec_type = CODEC_TYPE_VIDEO; + video_enc.codec_id = video_id; + add_codec(stream, &video_enc); + } + } + stream = NULL; + } else if (!strcasecmp(cmd, "next; + + get_arg(redirect->filename, sizeof(redirect->filename), &p); + q = strrchr(redirect->filename, '>'); + if (*q) + *q = '\0'; + redirect->stream_type = STREAM_TYPE_REDIRECT; + } + } else if (!strcasecmp(cmd, "URL")) { + if (redirect) { + get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p); + } + } else if (!strcasecmp(cmd, "")) { + if (!redirect) { + fprintf(stderr, "%s:%d: No corresponding for \n", + filename, line_num); + errors++; + } + if (!redirect->feed_filename[0]) { + fprintf(stderr, "%s:%d: No URL found for \n", + filename, line_num); + errors++; + } + redirect = NULL; + } else if (!strcasecmp(cmd, "LoadModule")) { + get_arg(arg, sizeof(arg), &p); +#ifdef CONFIG_HAVE_DLOPEN + load_module(arg); +#else + fprintf(stderr, "%s:%d: Module support not compiled into this version: '%s'\n", + filename, line_num, arg); + errors++; +#endif + } else { + fprintf(stderr, "%s:%d: Incorrect keyword: '%s'\n", + filename, line_num, cmd); + errors++; + } + } + + fclose(f); + if (errors) + return -1; + else + return 0; +} + + +#if 0 +static void write_packet(FFCodec *ffenc, + uint8_t *buf, int size) +{ + PacketHeader hdr; + AVCodecContext *enc = &ffenc->enc; + uint8_t *wptr; + mk_header(&hdr, enc, size); + wptr = http_fifo.wptr; + fifo_write(&http_fifo, (uint8_t *)&hdr, sizeof(hdr), &wptr); + fifo_write(&http_fifo, buf, size, &wptr); + /* atomic modification of wptr */ + http_fifo.wptr = wptr; + ffenc->data_count += size; + ffenc->avg_frame_size = ffenc->avg_frame_size * AVG_COEF + size * (1.0 - AVG_COEF); +} +#endif + +static void show_banner(void) +{ + printf("ffserver version " FFMPEG_VERSION ", Copyright (c) 2000-2003 Fabrice Bellard\n"); +} + +static void show_help(void) +{ + show_banner(); + printf("usage: ffserver [-L] [-h] [-f configfile]\n" + "Hyper fast multi format Audio/Video streaming server\n" + "\n" + "-L : print the LICENSE\n" + "-h : this help\n" + "-f configfile : use configfile instead of /etc/ffserver.conf\n" + ); +} + +static void show_license(void) +{ + show_banner(); + printf( + "This library is free software; you can redistribute it and/or\n" + "modify it under the terms of the GNU Lesser General Public\n" + "License as published by the Free Software Foundation; either\n" + "version 2 of the License, or (at your option) any later version.\n" + "\n" + "This library is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" + "Lesser General Public License for more details.\n" + "\n" + "You should have received a copy of the GNU Lesser General Public\n" + "License along with this library; if not, write to the Free Software\n" + "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n" + ); +} + +static void handle_child_exit(int sig) +{ + pid_t pid; + int status; + + while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { + FFStream *feed; + + for (feed = first_feed; feed; feed = feed->next) { + if (feed->pid == pid) { + int uptime = time(0) - feed->pid_start; + + feed->pid = 0; + fprintf(stderr, "%s: Pid %d exited with status %d after %d seconds\n", feed->filename, pid, status, uptime); + + if (uptime < 30) { + /* Turn off any more restarts */ + feed->child_argv = 0; + } + } + } + } + + need_to_start_children = 1; +} + +int main(int argc, char **argv) +{ + const char *config_filename; + int c; + struct sigaction sigact; + + av_register_all(); + + config_filename = "/etc/ffserver.conf"; + + my_program_name = argv[0]; + my_program_dir = getcwd(0, 0); + ffserver_daemon = 1; + + for(;;) { + c = getopt(argc, argv, "ndLh?f:"); + if (c == -1) + break; + switch(c) { + case 'L': + show_license(); + exit(1); + case '?': + case 'h': + show_help(); + exit(1); + case 'n': + no_launch = 1; + break; + case 'd': + ffserver_debug = 1; + ffserver_daemon = 0; + break; + case 'f': + config_filename = optarg; + break; + default: + exit(2); + } + } + + putenv("http_proxy"); /* Kill the http_proxy */ + + srandom(gettime_ms() + (getpid() << 16)); + + /* address on which the server will handle HTTP connections */ + my_http_addr.sin_family = AF_INET; + my_http_addr.sin_port = htons (8080); + my_http_addr.sin_addr.s_addr = htonl (INADDR_ANY); + + /* address on which the server will handle RTSP connections */ + my_rtsp_addr.sin_family = AF_INET; + my_rtsp_addr.sin_port = htons (5454); + my_rtsp_addr.sin_addr.s_addr = htonl (INADDR_ANY); + + nb_max_connections = 5; + max_bandwidth = 1000; + first_stream = NULL; + logfilename[0] = '\0'; + + memset(&sigact, 0, sizeof(sigact)); + sigact.sa_handler = handle_child_exit; + sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART; + sigaction(SIGCHLD, &sigact, 0); + + if (parse_ffconfig(config_filename) < 0) { + fprintf(stderr, "Incorrect config file - exiting.\n"); + exit(1); + } + + build_file_streams(); + + build_feed_streams(); + + compute_bandwidth(); + + /* put the process in background and detach it from its TTY */ + if (ffserver_daemon) { + int pid; + + pid = fork(); + if (pid < 0) { + perror("fork"); + exit(1); + } else if (pid > 0) { + /* parent : exit */ + exit(0); + } else { + /* child */ + setsid(); + chdir("/"); + close(0); + open("/dev/null", O_RDWR); + if (strcmp(logfilename, "-") != 0) { + close(1); + dup(0); + } + close(2); + dup(0); + } + } + + /* signal init */ + signal(SIGPIPE, SIG_IGN); + + /* open log file if needed */ + if (logfilename[0] != '\0') { + if (!strcmp(logfilename, "-")) + logfile = stdout; + else + logfile = fopen(logfilename, "w"); + } + + if (http_server() < 0) { + fprintf(stderr, "Could not start server\n"); + exit(1); + } + + return 0; +} diff --git a/mpeg4/src/ffserver.h b/mpeg4/src/ffserver.h new file mode 100644 index 00000000..868e4cd9 --- /dev/null +++ b/mpeg4/src/ffserver.h @@ -0,0 +1,8 @@ +#ifndef FFSERVER_H +#define FFSERVER_H + +/* interface between ffserver and modules */ + +void ffserver_module_init(void); + +#endif diff --git a/mpeg4/src/libavcodec/.cvsignore b/mpeg4/src/libavcodec/.cvsignore new file mode 100644 index 00000000..b6a5f4cf --- /dev/null +++ b/mpeg4/src/libavcodec/.cvsignore @@ -0,0 +1,6 @@ +Makefile.* +.depend +amr +amr*_float +apiexample +*-test diff --git a/mpeg4/src/libavcodec/4xm.c b/mpeg4/src/libavcodec/4xm.c new file mode 100644 index 00000000..3ca2338d --- /dev/null +++ b/mpeg4/src/libavcodec/4xm.c @@ -0,0 +1,753 @@ +/* + * 4XM codec + * Copyright (c) 2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file 4xm.c + * 4XM codec. + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + +//#undef NDEBUG +//#include + +#define BLOCK_TYPE_VLC_BITS 5 +#define ACDC_VLC_BITS 9 + +#define CFRAME_BUFFER_COUNT 100 + +static const uint8_t block_type_tab[4][8][2]={ + { //{8,4,2}x{8,4,2} + { 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0} + },{ //{8,4}x1 + { 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0} + },{ //1x{8,4} + { 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0} + },{ //1x2, 2x1 + { 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4} + } +}; + +static const uint8_t size2index[4][4]={ + {-1, 3, 1, 1}, + { 3, 0, 0, 0}, + { 2, 0, 0, 0}, + { 2, 0, 0, 0}, +}; + +static const int8_t mv[256][2]={ +{ 0, 0},{ 0, -1},{ -1, 0},{ 1, 0},{ 0, 1},{ -1, -1},{ 1, -1},{ -1, 1}, +{ 1, 1},{ 0, -2},{ -2, 0},{ 2, 0},{ 0, 2},{ -1, -2},{ 1, -2},{ -2, -1}, +{ 2, -1},{ -2, 1},{ 2, 1},{ -1, 2},{ 1, 2},{ -2, -2},{ 2, -2},{ -2, 2}, +{ 2, 2},{ 0, -3},{ -3, 0},{ 3, 0},{ 0, 3},{ -1, -3},{ 1, -3},{ -3, -1}, +{ 3, -1},{ -3, 1},{ 3, 1},{ -1, 3},{ 1, 3},{ -2, -3},{ 2, -3},{ -3, -2}, +{ 3, -2},{ -3, 2},{ 3, 2},{ -2, 3},{ 2, 3},{ 0, -4},{ -4, 0},{ 4, 0}, +{ 0, 4},{ -1, -4},{ 1, -4},{ -4, -1},{ 4, -1},{ 4, 1},{ -1, 4},{ 1, 4}, +{ -3, -3},{ -3, 3},{ 3, 3},{ -2, -4},{ -4, -2},{ 4, -2},{ -4, 2},{ -2, 4}, +{ 2, 4},{ -3, -4},{ 3, -4},{ 4, -3},{ -5, 0},{ -4, 3},{ -3, 4},{ 3, 4}, +{ -1, -5},{ -5, -1},{ -5, 1},{ -1, 5},{ -2, -5},{ 2, -5},{ 5, -2},{ 5, 2}, +{ -4, -4},{ -4, 4},{ -3, -5},{ -5, -3},{ -5, 3},{ 3, 5},{ -6, 0},{ 0, 6}, +{ -6, -1},{ -6, 1},{ 1, 6},{ 2, -6},{ -6, 2},{ 2, 6},{ -5, -4},{ 5, 4}, +{ 4, 5},{ -6, -3},{ 6, 3},{ -7, 0},{ -1, -7},{ 5, -5},{ -7, 1},{ -1, 7}, +{ 4, -6},{ 6, 4},{ -2, -7},{ -7, 2},{ -3, -7},{ 7, -3},{ 3, 7},{ 6, -5}, +{ 0, -8},{ -1, -8},{ -7, -4},{ -8, 1},{ 4, 7},{ 2, -8},{ -2, 8},{ 6, 6}, +{ -8, 3},{ 5, -7},{ -5, 7},{ 8, -4},{ 0, -9},{ -9, -1},{ 1, 9},{ 7, -6}, +{ -7, 6},{ -5, -8},{ -5, 8},{ -9, 3},{ 9, -4},{ 7, -7},{ 8, -6},{ 6, 8}, +{ 10, 1},{-10, 2},{ 9, -5},{ 10, -3},{ -8, -7},{-10, -4},{ 6, -9},{-11, 0}, +{ 11, 1},{-11, -2},{ -2, 11},{ 7, -9},{ -7, 9},{ 10, 6},{ -4, 11},{ 8, -9}, +{ 8, 9},{ 5, 11},{ 7,-10},{ 12, -3},{ 11, 6},{ -9, -9},{ 8, 10},{ 5, 12}, +{-11, 7},{ 13, 2},{ 6,-12},{ 10, 9},{-11, 8},{ -7, 12},{ 0, 14},{ 14, -2}, +{ -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{ 5, 14},{-15, -1},{-14, -6},{ 3,-15}, +{ 11,-11},{ -7, 14},{ -5, 15},{ 8,-14},{ 15, 6},{ 3, 16},{ 7,-15},{-16, 5}, +{ 0, 17},{-16, -6},{-10, 14},{-16, 7},{ 12, 13},{-16, 8},{-17, 6},{-18, 3}, +{ -7, 17},{ 15, 11},{ 16, 10},{ 2,-19},{ 3,-19},{-11,-16},{-18, 8},{-19, -6}, +{ 2,-20},{-17,-11},{-10,-18},{ 8, 19},{-21, -1},{-20, 7},{ -4, 21},{ 21, 5}, +{ 15, 16},{ 2,-22},{-10,-20},{-22, 5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5}, +{ 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24}, +{ 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27, 6},{ 1,-28}, +{-11, 26},{-17,-23},{ 7, 28},{ 11,-27},{ 29, 5},{-23,-19},{-28,-11},{-21, 22}, +{-30, 7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27}, +{-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32} +}; + +// this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table +static const uint8_t dequant_table[64]={ + 16, 15, 13, 19, 24, 31, 28, 17, + 17, 23, 25, 31, 36, 63, 45, 21, + 18, 24, 27, 37, 52, 59, 49, 20, + 16, 28, 34, 40, 60, 80, 51, 20, + 18, 31, 48, 66, 68, 86, 56, 21, + 19, 38, 56, 59, 64, 64, 48, 20, + 27, 48, 55, 55, 56, 51, 35, 15, + 20, 35, 34, 32, 31, 22, 15, 8, +}; + +static VLC block_type_vlc[4]; + + +typedef struct CFrameBuffer{ + int allocated_size; + int size; + int id; + uint8_t *data; +}CFrameBuffer; + +typedef struct FourXContext{ + AVCodecContext *avctx; + DSPContext dsp; + AVFrame current_picture, last_picture; + GetBitContext pre_gb; ///< ac/dc prefix + GetBitContext gb; + uint8_t *bytestream; + uint16_t *wordstream; + int mv[256]; + VLC pre_vlc; + int last_dc; + DECLARE_ALIGNED_8(DCTELEM, block[6][64]); + uint8_t *bitstream_buffer; + unsigned int bitstream_buffer_size; + CFrameBuffer cfrm[CFRAME_BUFFER_COUNT]; +} FourXContext; + + +#define FIX_1_082392200 70936 +#define FIX_1_414213562 92682 +#define FIX_1_847759065 121095 +#define FIX_2_613125930 171254 + +#define MULTIPLY(var,const) (((var)*(const)) >> 16) + +static void idct(DCTELEM block[64]){ + int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + int tmp10, tmp11, tmp12, tmp13; + int z5, z10, z11, z12, z13; + int i; + int temp[64]; + + for(i=0; i<8; i++){ + tmp10 = block[8*0 + i] + block[8*4 + i]; + tmp11 = block[8*0 + i] - block[8*4 + i]; + + tmp13 = block[8*2 + i] + block[8*6 + i]; + tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + z13 = block[8*5 + i] + block[8*3 + i]; + z10 = block[8*5 + i] - block[8*3 + i]; + z11 = block[8*1 + i] + block[8*7 + i]; + z12 = block[8*1 + i] - block[8*7 + i]; + + tmp7 = z11 + z13; + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; + + tmp6 = tmp12 - tmp7; + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + temp[8*0 + i] = tmp0 + tmp7; + temp[8*7 + i] = tmp0 - tmp7; + temp[8*1 + i] = tmp1 + tmp6; + temp[8*6 + i] = tmp1 - tmp6; + temp[8*2 + i] = tmp2 + tmp5; + temp[8*5 + i] = tmp2 - tmp5; + temp[8*4 + i] = tmp3 + tmp4; + temp[8*3 + i] = tmp3 - tmp4; + } + + for(i=0; i<8*8; i+=8){ + tmp10 = temp[0 + i] + temp[4 + i]; + tmp11 = temp[0 + i] - temp[4 + i]; + + tmp13 = temp[2 + i] + temp[6 + i]; + tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13; + + tmp0 = tmp10 + tmp13; + tmp3 = tmp10 - tmp13; + tmp1 = tmp11 + tmp12; + tmp2 = tmp11 - tmp12; + + z13 = temp[5 + i] + temp[3 + i]; + z10 = temp[5 + i] - temp[3 + i]; + z11 = temp[1 + i] + temp[7 + i]; + z12 = temp[1 + i] - temp[7 + i]; + + tmp7 = z11 + z13; + tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); + + z5 = MULTIPLY(z10 + z12, FIX_1_847759065); + tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; + tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; + + tmp6 = tmp12 - tmp7; + tmp5 = tmp11 - tmp6; + tmp4 = tmp10 + tmp5; + + block[0 + i] = (tmp0 + tmp7)>>6; + block[7 + i] = (tmp0 - tmp7)>>6; + block[1 + i] = (tmp1 + tmp6)>>6; + block[6 + i] = (tmp1 - tmp6)>>6; + block[2 + i] = (tmp2 + tmp5)>>6; + block[5 + i] = (tmp2 - tmp5)>>6; + block[4 + i] = (tmp3 + tmp4)>>6; + block[3 + i] = (tmp3 - tmp4)>>6; + } +} + +static void init_vlcs(FourXContext *f){ + int i; + + for(i=0; i<4; i++){ + init_vlc(&block_type_vlc[i], BLOCK_TYPE_VLC_BITS, 7, + &block_type_tab[i][0][1], 2, 1, + &block_type_tab[i][0][0], 2, 1, 1); + } +} + +static void init_mv(FourXContext *f){ + int i; + + for(i=0; i<256; i++){ + f->mv[i] = mv[i][0] + mv[i][1]*f->current_picture.linesize[0]/2; + } +} + +static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){ + int i; + dc*= 0x10001; + + switch(log2w){ + case 0: + for(i=0; igb, block_type_vlc[index].table, BLOCK_TYPE_VLC_BITS, 1); + + assert(code>=0 && code<=6); + + if(code == 0){ + src += f->mv[ *f->bytestream++ ]; + mcdc(dst, src, log2w, h, stride, 1, 0); + }else if(code == 1){ + log2h--; + decode_p_block(f, dst , src , log2w, log2h, stride); + decode_p_block(f, dst + (stride<mv[ *f->bytestream++ ]; + mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++)); + }else if(code == 5){ + mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++)); + }else if(code == 6){ + if(log2w){ + dst[0] = le2me_16(*f->wordstream++); + dst[1] = le2me_16(*f->wordstream++); + }else{ + dst[0 ] = le2me_16(*f->wordstream++); + dst[stride] = le2me_16(*f->wordstream++); + } + } +} + +static int get32(void *p){ + return le2me_32(*(uint32_t*)p); +} + +static int decode_p_frame(FourXContext *f, uint8_t *buf, int length){ + int x, y; + const int width= f->avctx->width; + const int height= f->avctx->height; + uint16_t *src= (uint16_t*)f->last_picture.data[0]; + uint16_t *dst= (uint16_t*)f->current_picture.data[0]; + const int stride= f->current_picture.linesize[0]>>1; + const unsigned int bitstream_size= get32(buf+8); + const unsigned int bytestream_size= get32(buf+16); + const unsigned int wordstream_size= get32(buf+12); + + if(bitstream_size+ bytestream_size+ wordstream_size + 20 != length + || bitstream_size > (1<<26) + || bytestream_size > (1<<26) + || wordstream_size > (1<<26) + ){ + av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size, + bitstream_size+ bytestream_size+ wordstream_size - length); + return -1; + } + + f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE); + f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)(buf + 20), bitstream_size/4); + init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size); + + f->wordstream= (uint16_t*)(buf + 20 + bitstream_size); + f->bytestream= buf + 20 + bitstream_size + wordstream_size; + + init_mv(f); + + for(y=0; ygb)+31)/32*4) + av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n", + bitstream_size - (get_bits_count(&f->gb)+31)/32*4, + bytestream_size - (f->bytestream - (buf + 20 + bitstream_size + wordstream_size)), + wordstream_size - (((uint8_t*)f->wordstream) - (buf + 20 + bitstream_size)) + ); + + return 0; +} + +/** + * decode block and dequantize. + * Note this is allmost identical to mjpeg + */ +static int decode_i_block(FourXContext *f, DCTELEM *block){ + int code, i, j, level, val; + + /* DC coef */ + val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); + if (val>>4){ + av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n"); + } + + if(val) + val = get_xbits(&f->gb, val); + + val = val * dequant_table[0] + f->last_dc; + f->last_dc = + block[0] = val; + /* AC coefs */ + i = 1; + for(;;) { + code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); + + /* EOB */ + if (code == 0) + break; + if (code == 0xf0) { + i += 16; + } else { + level = get_xbits(&f->gb, code & 0xf); + i += code >> 4; + if (i >= 64) { + av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i); + return 0; + } + + j= ff_zigzag_direct[i]; + block[j] = level * dequant_table[j]; + i++; + if (i >= 64) + break; + } + } + + return 0; +} + +static inline void idct_put(FourXContext *f, int x, int y){ + DCTELEM (*block)[64]= f->block; + int stride= f->current_picture.linesize[0]>>1; + int i; + uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x; + + for(i=0; i<4; i++){ + block[i][0] += 0x80*8*8; + idct(block[i]); + } + + if(!(f->avctx->flags&CODEC_FLAG_GRAY)){ + for(i=4; i<6; i++) idct(block[i]); + } + +/* Note transform is: +y= ( 1b + 4g + 2r)/14 +cb=( 3b - 2g - 1r)/14 +cr=(-1b - 4g + 5r)/14 +*/ + for(y=0; y<8; y++){ + for(x=0; x<8; x++){ + DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize + int cb= block[4][x + 8*y]; + int cr= block[5][x + 8*y]; + int cg= (cb + cr)>>1; + int y; + + cb+=cb; + + y = temp[0]; + dst[0 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); + y = temp[1]; + dst[1 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); + y = temp[8]; + dst[ stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); + y = temp[9]; + dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8); + dst += 2; + } + dst += 2*stride - 2*8; + } +} + +static int decode_i_mb(FourXContext *f){ + int i; + + f->dsp.clear_blocks(f->block[0]); + + for(i=0; i<6; i++){ + if(decode_i_block(f, f->block[i]) < 0) + return -1; + } + + return 0; +} + +static uint8_t *read_huffman_tables(FourXContext *f, uint8_t * const buf){ + int frequency[512]; + uint8_t flag[512]; + int up[512]; + uint8_t len_tab[257]; + int bits_tab[257]; + int start, end; + uint8_t *ptr= buf; + int j; + + memset(frequency, 0, sizeof(frequency)); + memset(up, -1, sizeof(up)); + + start= *ptr++; + end= *ptr++; + for(;;){ + int i; + + for(i=start; i<=end; i++){ + frequency[i]= *ptr++; +// printf("%d %d %d\n", start, end, frequency[i]); + } + start= *ptr++; + if(start==0) break; + + end= *ptr++; + } + frequency[256]=1; + + while((ptr - buf)&3) ptr++; // 4byte align + +// for(j=0; j<16; j++) +// printf("%2X", ptr[j]); + + for(j=257; j<512; j++){ + int min_freq[2]= {256*256, 256*256}; + int smallest[2]= {0, 0}; + int i; + for(i=0; i 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ? + } + + bits_tab[j]= bits; + len_tab[j]= len; + } + + init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, + len_tab , 1, 1, + bits_tab, 4, 4, 0); + + return ptr; +} + +static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){ + int x, y; + const int width= f->avctx->width; + const int height= f->avctx->height; + uint16_t *dst= (uint16_t*)f->current_picture.data[0]; + const int stride= f->current_picture.linesize[0]>>1; + const unsigned int bitstream_size= get32(buf); + const int token_count __attribute__((unused)) = get32(buf + bitstream_size + 8); + unsigned int prestream_size= 4*get32(buf + bitstream_size + 4); + uint8_t *prestream= buf + bitstream_size + 12; + + if(prestream_size + bitstream_size + 12 != length + || bitstream_size > (1<<26) + || prestream_size > (1<<26)){ + av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); + return -1; + } + + prestream= read_huffman_tables(f, prestream); + + init_get_bits(&f->gb, buf + 4, 8*bitstream_size); + + prestream_size= length + buf - prestream; + + f->bitstream_buffer= av_fast_realloc(f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE); + f->dsp.bswap_buf((uint32_t*)f->bitstream_buffer, (uint32_t*)prestream, prestream_size/4); + init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size); + + f->last_dc= 0*128*8*8; + + for(y=0; ypre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256) + av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n"); + + return 0; +} + +static int decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + FourXContext * const f = avctx->priv_data; + AVFrame *picture = data; + AVFrame *p, temp; + int i, frame_4cc, frame_size; + + frame_4cc= get32(buf); + if(buf_size != get32(buf+4)+8){ + av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, get32(buf+4)); + } + + if(frame_4cc == ff_get_fourcc("cfrm")){ + int free_index=-1; + const int data_size= buf_size - 20; + const int id= get32(buf+12); + const int whole_size= get32(buf+16); + CFrameBuffer *cfrm; + + for(i=0; icfrm[i].id && f->cfrm[i].id < avctx->frame_number) + av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id); + } + + for(i=0; icfrm[i].id == id) break; + if(f->cfrm[i].size == 0 ) free_index= i; + } + + if(i>=CFRAME_BUFFER_COUNT){ + i= free_index; + f->cfrm[i].id= id; + } + cfrm= &f->cfrm[i]; + + cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE); + + memcpy(cfrm->data + cfrm->size, buf+20, data_size); + cfrm->size += data_size; + + if(cfrm->size >= whole_size){ + buf= cfrm->data; + frame_size= cfrm->size; + + if(id != avctx->frame_number){ + av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number); + } + + cfrm->size= cfrm->id= 0; + frame_4cc= ff_get_fourcc("pfrm"); + }else + return buf_size; + }else{ + buf= buf + 12; + frame_size= buf_size - 12; + } + + temp= f->current_picture; + f->current_picture= f->last_picture; + f->last_picture= temp; + + p= &f->current_picture; + avctx->coded_frame= p; + + avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management + + if(p->data[0]) + avctx->release_buffer(avctx, p); + + p->reference= 1; + if(avctx->get_buffer(avctx, p) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + if(frame_4cc == ff_get_fourcc("ifrm")){ + p->pict_type= I_TYPE; + if(decode_i_frame(f, buf, frame_size) < 0) + return -1; + }else if(frame_4cc == ff_get_fourcc("pfrm")){ + p->pict_type= P_TYPE; + if(decode_p_frame(f, buf, frame_size) < 0) + return -1; + }else if(frame_4cc == ff_get_fourcc("snd_")){ + av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size); + }else{ + av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size); + } + +#if 0 +for(i=0; i<20; i++){ + printf("%2X %c ", buf[i], clip(buf[i],16,126)); +} +#endif + + p->key_frame= p->pict_type == I_TYPE; + + *picture= *p; + *data_size = sizeof(AVPicture); + + emms_c(); + + return buf_size; +} + + +static void common_init(AVCodecContext *avctx){ + FourXContext * const f = avctx->priv_data; + + dsputil_init(&f->dsp, avctx); + + f->avctx= avctx; +} + +static int decode_init(AVCodecContext *avctx){ + FourXContext * const f = avctx->priv_data; + + common_init(avctx); + init_vlcs(f); + + avctx->pix_fmt= PIX_FMT_RGB565; + + return 0; +} + + +static int decode_end(AVCodecContext *avctx){ + FourXContext * const f = avctx->priv_data; + int i; + + av_freep(&f->bitstream_buffer); + f->bitstream_buffer_size=0; + for(i=0; icfrm[i].data); + f->cfrm[i].allocated_size= 0; + } + free_vlc(&f->pre_vlc); + + return 0; +} + +AVCodec fourxm_decoder = { + "4xm", + CODEC_TYPE_VIDEO, + CODEC_ID_4XM, + sizeof(FourXContext), + decode_init, + NULL, + decode_end, + decode_frame, + /*CODEC_CAP_DR1,*/ +}; + diff --git a/mpeg4/src/libavcodec/8bps.c b/mpeg4/src/libavcodec/8bps.c new file mode 100644 index 00000000..b16e3bb5 --- /dev/null +++ b/mpeg4/src/libavcodec/8bps.c @@ -0,0 +1,234 @@ +/* + * Quicktime Planar RGB (8BPS) Video Decoder + * Copyright (C) 2003 Roberto Togni + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file 8bps.c + * QT 8BPS Video Decoder by Roberto Togni + * For more information about the 8BPS format, visit: + * http://www.pcisys.net/~melanson/codecs/ + * + * Supports: PAL8 (RGB 8bpp, paletted) + * : BGR24 (RGB 24bpp) (can also output it as RGBA32) + * : RGBA32 (RGB 32bpp, 4th plane is probably alpha and it's ignored) + * + */ + +#include +#include + +#include "common.h" +#include "avcodec.h" + + +const enum PixelFormat pixfmt_rgb24[] = {PIX_FMT_BGR24, PIX_FMT_RGBA32, -1}; + +/* + * Decoder context + */ +typedef struct EightBpsContext { + + AVCodecContext *avctx; + AVFrame pic; + + unsigned char planes; + unsigned char planemap[4]; +} EightBpsContext; + + +/* + * + * Decode a frame + * + */ +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +{ + EightBpsContext * const c = (EightBpsContext *)avctx->priv_data; + unsigned char *encoded = (unsigned char *)buf; + unsigned char *pixptr, *pixptr_end; + unsigned int height = avctx->height; // Real image height + unsigned int dlen, p, row; + unsigned char *lp, *dp; + unsigned char count; + unsigned int px_inc; + unsigned int planes = c->planes; + unsigned char *planemap = c->planemap; + + if(c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + + c->pic.reference = 0; + c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; + if(avctx->get_buffer(avctx, &c->pic) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + /* Set data pointer after line lengths */ + dp = encoded + planes * (height << 1); + + /* Ignore alpha plane, don't know what to do with it */ + if (planes == 4) + planes--; + + px_inc = planes + (avctx->pix_fmt == PIX_FMT_RGBA32); + + for (p = 0; p < planes; p++) { + /* Lines length pointer for this plane */ + lp = encoded + p * (height << 1); + + /* Decode a plane */ + for(row = 0; row < height; row++) { + pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p]; + pixptr_end = pixptr + c->pic.linesize[0]; + dlen = be2me_16(*(unsigned short *)(lp+row*2)); + /* Decode a row of this plane */ + while(dlen > 0) { + if(dp + 1 >= buf+buf_size) return -1; + if ((count = *dp++) <= 127) { + count++; + dlen -= count + 1; + if (pixptr + count * px_inc > pixptr_end) + break; + if(dp + count > buf+buf_size) return -1; + while(count--) { + *pixptr = *dp++; + pixptr += px_inc; + } + } else { + count = 257 - count; + if (pixptr + count * px_inc > pixptr_end) + break; + while(count--) { + *pixptr = *dp; + pixptr += px_inc; + } + dp++; + dlen -= 2; + } + } + } + } + + if (avctx->palctrl) { + memcpy (c->pic.data[1], avctx->palctrl->palette, AVPALETTE_SIZE); + if (avctx->palctrl->palette_changed) { + c->pic.palette_has_changed = 1; + avctx->palctrl->palette_changed = 0; + } else + c->pic.palette_has_changed = 0; + } + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = c->pic; + + /* always report that the buffer was completely consumed */ + return buf_size; +} + + +/* + * + * Init 8BPS decoder + * + */ +static int decode_init(AVCodecContext *avctx) +{ + EightBpsContext * const c = (EightBpsContext *)avctx->priv_data; + + c->avctx = avctx; + avctx->has_b_frames = 0; + + c->pic.data[0] = NULL; + + if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { + return 1; + } + + switch (avctx->bits_per_sample) { + case 8: + avctx->pix_fmt = PIX_FMT_PAL8; + c->planes = 1; + c->planemap[0] = 0; // 1st plane is palette indexes + if (avctx->palctrl == NULL) { + av_log(avctx, AV_LOG_ERROR, "Error: PAL8 format but no palette from demuxer.\n"); + return -1; + } + break; + case 24: + avctx->pix_fmt = avctx->get_format(avctx, pixfmt_rgb24); + c->planes = 3; + c->planemap[0] = 2; // 1st plane is red + c->planemap[1] = 1; // 2nd plane is green + c->planemap[2] = 0; // 3rd plane is blue + break; + case 32: + avctx->pix_fmt = PIX_FMT_RGBA32; + c->planes = 4; +#ifdef WORDS_BIGENDIAN + c->planemap[0] = 1; // 1st plane is red + c->planemap[1] = 2; // 2nd plane is green + c->planemap[2] = 3; // 3rd plane is blue + c->planemap[3] = 0; // 4th plane is alpha??? +#else + c->planemap[0] = 2; // 1st plane is red + c->planemap[1] = 1; // 2nd plane is green + c->planemap[2] = 0; // 3rd plane is blue + c->planemap[3] = 3; // 4th plane is alpha??? +#endif + break; + default: + av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n", avctx->bits_per_sample); + return -1; + } + + return 0; +} + + + + +/* + * + * Uninit 8BPS decoder + * + */ +static int decode_end(AVCodecContext *avctx) +{ + EightBpsContext * const c = (EightBpsContext *)avctx->priv_data; + + if (c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + + return 0; +} + + + +AVCodec eightbps_decoder = { + "8bps", + CODEC_TYPE_VIDEO, + CODEC_ID_8BPS, + sizeof(EightBpsContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; diff --git a/mpeg4/src/libavcodec/Makefile b/mpeg4/src/libavcodec/Makefile new file mode 100644 index 00000000..d8e24625 --- /dev/null +++ b/mpeg4/src/libavcodec/Makefile @@ -0,0 +1,476 @@ +# +# libavcodec Makefile +# (c) 2000-2005 Fabrice Bellard +# +include ../config.mak + +# NOTE: -I.. is needed to include config.h +CFLAGS=$(OPTFLAGS) -DHAVE_AV_CONFIG_H -I.. -I$(SRC_PATH)/libavutil -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE $(AMR_CFLAGS) + +OBJS= bitstream.o utils.o mem.o allcodecs.o \ + mpegvideo.o jrevdct.o jfdctfst.o jfdctint.o\ + mpegaudio.o ac3enc.o mjpeg.o resample.o resample2.o dsputil.o \ + motion_est.o imgconvert.o imgresample.o \ + mpeg12.o mpegaudiodec.o pcm.o simple_idct.o \ + ratecontrol.o adpcm.o eval.o error_resilience.o \ + fft.o mdct.o raw.o golomb.o cabac.o\ + dpcm.o adx.o faandct.o parser.o g726.o \ + vp3dsp.o h264idct.o rangecoder.o pnm.o h263.o msmpeg4.o h263dec.o \ + opt.o + +HEADERS = avcodec.h + +ifeq ($(CONFIG_AASC_DECODER),yes) + OBJS+= aasc.o +endif +ifeq ($(CONFIG_ALAC_DECODER),yes) + OBJS+= alac.o +endif +ifneq ($(CONFIG_ASV1_DECODER)$(CONFIG_ASV1_ENCODER)$(CONFIG_ASV2_DECODER)$(CONFIG_ASV2_ENCODER),) + OBJS+= asv1.o +endif +ifeq ($(CONFIG_AVS_DECODER),yes) + OBJS+= avs.o +endif +ifeq ($(CONFIG_CINEPAK_DECODER),yes) + OBJS+= cinepak.o +endif +ifeq ($(CONFIG_COOK_DECODER),yes) + OBJS+= cook.o +endif +ifneq ($(CONFIG_CLJR_DECODER)$(CONFIG_CLJR_ENCODER),) + OBJS+= cljr.o +endif +ifeq ($(CONFIG_CYUV_DECODER),yes) + OBJS+= cyuv.o +endif +ifeq ($(CONFIG_DVBSUB_DECODER),yes) + OBJS+= dvbsubdec.o +endif +ifeq ($(CONFIG_DVBSUB_ENCODER),yes) + OBJS+= dvbsub.o +endif +ifeq ($(CONFIG_DVDSUB_DECODER),yes) + OBJS+= dvdsub.o +endif +ifeq ($(CONFIG_DVDSUB_ENCODER),yes) + OBJS+= dvdsubenc.o +endif +ifneq ($(CONFIG_DVVIDEO_DECODER)$(CONFIG_DVVIDEO_ENCODER),) + OBJS+= dv.o +endif +ifeq ($(CONFIG_EIGHTBPS_DECODER),yes) + OBJS+= 8bps.o +endif +ifneq ($(CONFIG_FFV1_DECODER)$(CONFIG_FFV1_ENCODER),) + OBJS+= ffv1.o +endif +ifeq ($(CONFIG_FLAC_DECODER),yes) + OBJS+= flac.o +endif +ifeq ($(CONFIG_FLIC_DECODER),yes) + OBJS+= flicvideo.o +endif +ifeq ($(CONFIG_FOURXM_DECODER),yes) + OBJS+= 4xm.o +endif +ifeq ($(CONFIG_FRAPS_DECODER),yes) + OBJS+= fraps.o +endif +ifneq ($(CONFIG_H261_DECODER)$(CONFIG_H261_ENCODER),) + OBJS+= h261.o +endif +ifneq ($(CONFIG_H264_DECODER)$(CONFIG_SVQ3_DECODER),) + OBJS+= h264.o +endif +ifneq ($(CONFIG_HUFFYUV_DECODER)$(CONFIG_HUFFYUV_ENCODER)$(CONFIG_FFVHUFF_DECODER)$(CONFIG_FFVHUFF_ENCODER),) + OBJS+= huffyuv.o +endif +ifeq ($(CONFIG_IDCIN_DECODER),yes) + OBJS+= idcinvideo.o +endif +ifeq ($(CONFIG_INDEO2_DECODER),yes) + OBJS+= indeo2.o +endif +ifeq ($(CONFIG_INDEO3_DECODER),yes) + OBJS+= indeo3.o +endif +ifeq ($(CONFIG_INTERPLAY_VIDEO_DECODER),yes) + OBJS+= interplayvideo.o +endif +ifeq ($(CONFIG_KMVC_DECODER),yes) + OBJS+= kmvc.o +endif +ifneq ($(CONFIG_MSZH_DECODER)$(CONFIG_ZLIB_DECODER)$(CONFIG_ZLIB_ENCODER),) + OBJS+= lcl.o +endif +ifeq ($(CONFIG_LOCO_DECODER),yes) + OBJS+= loco.o +endif +ifneq ($(CONFIG_MACE3_DECODER)$(CONFIG_MACE6_DECODER),) + OBJS+= mace.o +endif +ifeq ($(CONFIG_MSRLE_DECODER),yes) + OBJS+= msrle.o +endif +ifeq ($(CONFIG_MSVIDEO1_DECODER),yes) + OBJS+= msvideo1.o +endif +ifneq ($(CONFIG_PNG_DECODER)$(CONFIG_PNG_ENCODER),) + OBJS+= png.o +endif +ifeq ($(CONFIG_QDM2_DECODER),yes) + OBJS+= qdm2.o +endif +ifeq ($(CONFIG_QDRAW_DECODER),yes) + OBJS+= qdrw.o +endif +ifeq ($(CONFIG_QPEG_DECODER),yes) + OBJS+= qpeg.o +endif +ifeq ($(CONFIG_QTRLE_DECODER),yes) + OBJS+= qtrle.o +endif +ifeq ($(CONFIG_RA_144_DECODER),yes) + OBJS+= ra144.o +endif +ifeq ($(CONFIG_RA_288_DECODER),yes) + OBJS+= ra288.o +endif +ifeq ($(CONFIG_ROQ_DECODER),yes) + OBJS+= roqvideo.o +endif +ifeq ($(CONFIG_RPZA_DECODER),yes) + OBJS+= rpza.o +endif +ifneq ($(CONFIG_RV10_DECODER)$(CONFIG_RV20_DECODER)$(CONFIG_RV10_ENCODER)$(CONFIG_RV20_ENCODER),) + OBJS+= rv10.o +endif +ifeq ($(CONFIG_SHORTEN_DECODER),yes) + OBJS+= shorten.o +endif +ifneq ($(CONFIG_SMACKER_DECODER)$(CONFIG_SMACKAUD_DECODER),) + OBJS+= smacker.o +endif +ifeq ($(CONFIG_SMC_DECODER),yes) + OBJS+= smc.o +endif +ifneq ($(CONFIG_SNOW_DECODER)$(CONFIG_SNOW_ENCODER),) + OBJS+= snow.o +endif +ifneq ($(CONFIG_SONIC_DECODER)$(CONFIG_SONIC_ENCODER)$(CONFIG_SONIC_LS_ENCODER),) + OBJS+= sonic.o +endif +ifneq ($(CONFIG_SVQ1_DECODER)$(CONFIG_SVQ1_ENCODER),) + OBJS+= svq1.o +endif +ifeq ($(CONFIG_TRUEMOTION1_DECODER),yes) + OBJS+= truemotion1.o +endif +ifeq ($(CONFIG_TRUEMOTION2_DECODER),yes) + OBJS+= truemotion2.o +endif +ifeq ($(CONFIG_TRUESPEECH_DECODER),yes) + OBJS+= truespeech.o +endif +ifeq ($(CONFIG_TTA_DECODER),yes) + OBJS+= tta.o +endif +ifeq ($(CONFIG_TSCC_DECODER),yes) + OBJS+= tscc.o +endif +ifeq ($(CONFIG_CSCD_DECODER),yes) + OBJS+= cscd.o + OBJS+= lzo.o +endif +ifeq ($(CONFIG_NUV_DECODER),yes) + OBJS+= nuv.o + OBJS+= rtjpeg.o + OBJS+= lzo.o +endif +ifeq ($(CONFIG_ULTI_DECODER),yes) + OBJS+= ulti.o +endif +ifneq ($(CONFIG_VC9_DECODER)$(CONFIG_WMV3_DECODER),) + OBJS+= vc9.o +endif +ifneq ($(CONFIG_VCR1_DECODER)$(CONFIG_VCR1_ENCODER),) + OBJS+= vcr1.o +endif +ifneq ($(CONFIG_VMDVIDEO_DECODER)$(CONFIG_VMDAUDIO_DECODER),) + OBJS+= vmdav.o +endif +ifeq ($(CONFIG_VORBIS_DECODER),yes) + OBJS+= vorbis.o +endif +ifneq ($(CONFIG_VP3_DECODER)$(CONFIG_THEORA_DECODER),) + OBJS+= vp3.o +endif +ifeq ($(CONFIG_VQA_DECODER),yes) + OBJS+= vqavideo.o +endif +ifneq ($(CONFIG_WMAV1_DECODER)$(CONFIG_WMAV2_DECODER),) + OBJS+= wmadec.o +endif +ifeq ($(CONFIG_WNV1_DECODER),yes) + OBJS+= wnv1.o +endif +ifeq ($(CONFIG_WS_SND1_DECODER),yes) + OBJS+= ws-snd1.o +endif +ifneq ($(CONFIG_XAN_WC3_DECODER)$(CONFIG_XAN_WC4_DECODER),) + OBJS+= xan.o +endif +ifeq ($(CONFIG_XL_DECODER),yes) + OBJS+= xl.o +endif +ifeq ($(CONFIG_BMP_DECODER),yes) + OBJS+= bmp.o +endif +ifeq ($(CONFIG_MMVIDEO_DECODER),yes) + OBJS+= mmvideo.o +endif +ifeq ($(CONFIG_ZMBV_DECODER),yes) + OBJS+= zmbv.o +endif + +AMROBJS= +ifeq ($(AMR_NB),yes) +ifeq ($(AMR_NB_FIXED),yes) +AMROBJS= amr.o +AMREXTRALIBS+= amr/*.o +AMRLIBS=amrlibs +CLEANAMR=cleanamr +else +AMROBJS= amr.o +OBJS+= amr_float/sp_dec.o amr_float/sp_enc.o amr_float/interf_dec.o amr_float/interf_enc.o +CLEANAMR=cleanamrfloat +endif +endif + +ifeq ($(HAVE_PTHREADS),yes) +OBJS+= pthread.o +endif + +ifeq ($(HAVE_W32THREADS),yes) +OBJS+= w32thread.o +endif + +ifeq ($(HAVE_OS2THREADS),yes) +OBJS+= os2thread.o +endif + + +ifeq ($(HAVE_BEOSTHREADS),yes) +OBJS+= beosthread.o +endif + +ifeq ($(AMR_WB),yes) +AMROBJS= amr.o +OBJS+= amrwb_float/dec_acelp.o amrwb_float/dec_dtx.o amrwb_float/dec_gain.o \ + amrwb_float/dec_if.o amrwb_float/dec_lpc.o amrwb_float/dec_main.o \ + amrwb_float/dec_rom.o amrwb_float/dec_util.o amrwb_float/enc_acelp.o \ + amrwb_float/enc_dtx.o amrwb_float/enc_gain.o amrwb_float/enc_if.o \ + amrwb_float/enc_lpc.o amrwb_float/enc_main.o amrwb_float/enc_rom.o \ + amrwb_float/enc_util.o amrwb_float/if_rom.o +endif +OBJS+= $(AMROBJS) +CLEANAMRWB=cleanamrwbfloat +ASM_OBJS= + +ifeq ($(HAVE_XVMC_ACCEL),yes) +OBJS+= xvmcvideo.o +endif + +# currently using liba52 for ac3 decoding +ifeq ($(CONFIG_AC3),yes) +OBJS+= a52dec.o + +# using builtin liba52 or runtime linked liba52.so.0 +ifneq ($(CONFIG_A52BIN),yes) +OBJS+= liba52/bit_allocate.o liba52/bitstream.o liba52/downmix.o \ + liba52/imdct.o liba52/parse.o liba52/crc.o liba52/resample.o +endif +endif + +EXTRALIBS := -L../libavutil -lavutil$(BUILDSUF) $(EXTRALIBS) + +# currently using libdts for dts decoding +ifeq ($(CONFIG_DTS),yes) +OBJS+= dtsdec.o +CFLAGS += $(DTS_INC) +endif + +ifeq ($(CONFIG_FAAD),yes) +OBJS+= faad.o +endif + +ifeq ($(CONFIG_FAAC),yes) +OBJS+= faac.o +endif + +ifeq ($(CONFIG_XVID),yes) +OBJS+= xvidff.o +OBJS+= xvid_rc.o +endif + +ifeq ($(CONFIG_X264),yes) +OBJS+= x264.o +endif + +ifeq ($(CONFIG_MP3LAME),yes) +OBJS += mp3lameaudio.o +endif + +ifeq ($(CONFIG_LIBOGG),yes) +ifeq ($(CONFIG_LIBVORBIS),yes) +OBJS += oggvorbis.o +endif +ifeq ($(CONFIG_LIBTHEORA), yes) +OBJS += oggtheora.o +endif +endif + +ifeq ($(CONFIG_LIBGSM),yes) +OBJS += libgsm.o +endif + +# i386 mmx specific stuff +ifeq ($(TARGET_MMX),yes) +OBJS += i386/fdct_mmx.o i386/cputest.o \ + i386/dsputil_mmx.o i386/mpegvideo_mmx.o \ + i386/idct_mmx.o i386/motion_est_mmx.o \ + i386/simple_idct_mmx.o i386/fft_sse.o i386/vp3dsp_mmx.o \ + i386/vp3dsp_sse2.o i386/fft_3dn.o i386/fft_3dn2.o i386/snowdsp_mmx.o +ifeq ($(CONFIG_GPL),yes) +OBJS += i386/idct_mmx_xvid.o +endif +ifdef TARGET_BUILTIN_VECTOR +i386/fft_sse.o: CFLAGS+= -msse +depend: CFLAGS+= -msse +endif +ifdef TARGET_BUILTIN_3DNOW +i386/fft_3dn.o: CFLAGS+= -m3dnow +i386/fft_3dn2.o: CFLAGS+= -march=athlon +endif +endif + +# armv4l specific stuff +ifeq ($(TARGET_ARCH_ARMV4L),yes) +ASM_OBJS += armv4l/jrevdct_arm.o armv4l/simple_idct_arm.o armv4l/dsputil_arm_s.o +OBJS += armv4l/dsputil_arm.o armv4l/mpegvideo_arm.o +ifeq ($(TARGET_IWMMXT),yes) +OBJS += armv4l/dsputil_iwmmxt.o armv4l/mpegvideo_iwmmxt.o +endif +endif + +# sun mediaLib specific stuff +# currently only works when libavcodec is used in mplayer +ifeq ($(HAVE_MLIB),yes) +OBJS += mlib/dsputil_mlib.o +CFLAGS += $(MLIB_INC) +endif + +# Intel IPP specific stuff +# currently only works when libavcodec is used in mplayer +ifeq ($(HAVE_IPP),yes) +CFLAGS += $(IPP_INC) +endif + +# alpha specific stuff +ifeq ($(TARGET_ARCH_ALPHA),yes) +OBJS += alpha/dsputil_alpha.o alpha/mpegvideo_alpha.o \ + alpha/simple_idct_alpha.o alpha/motion_est_alpha.o +ASM_OBJS += alpha/dsputil_alpha_asm.o alpha/motion_est_mvi_asm.o +CFLAGS += -fforce-addr +endif + +ifeq ($(TARGET_ARCH_POWERPC),yes) +OBJS += ppc/dsputil_ppc.o ppc/mpegvideo_ppc.o +endif + +ifeq ($(TARGET_MMI),yes) +OBJS += ps2/dsputil_mmi.o ps2/idct_mmi.o ps2/mpegvideo_mmi.o +endif + +ifeq ($(TARGET_ALTIVEC),yes) +OBJS += ppc/dsputil_altivec.o ppc/mpegvideo_altivec.o ppc/idct_altivec.o \ + ppc/fft_altivec.o ppc/gmc_altivec.o ppc/fdct_altivec.o \ + ppc/dsputil_h264_altivec.o ppc/dsputil_snow_altivec.o +endif + +ifeq ($(TARGET_ARCH_SH4),yes) +OBJS+= sh4/idct_sh4.o sh4/dsputil_sh4.o sh4/dsputil_align.o +endif + +ifeq ($(TARGET_ARCH_SPARC),yes) +OBJS+=sparc/dsputil_vis.o +sparc/%.o: sparc/%.c + $(CC) -mcpu=ultrasparc -mtune=ultrasparc $(CFLAGS) -c -o $@ $< +endif + +NAME=avcodec +SUBDIR=libavcodec +LIBAVUTIL= $(SRC_PATH)/libavutil/$(LIBPREF)avutil$(LIBSUF) +ifeq ($(BUILD_SHARED),yes) +LIBVERSION=$(LAVCVERSION) +LIBMAJOR=$(LAVCMAJOR) +endif +TESTS= imgresample-test dct-test motion-test fft-test + +EXTRAOBJS = $(AMREXTRALIBS) + +include $(SRC_PATH)/common.mak + +$(LIB): $(AMRLIBS) + +amrlibs: + $(MAKE) -C amr spclib fipoplib + +tests: apiexample cpuid_test $(TESTS) + +dsputil.o: dsputil.c dsputil.h + +clean:: $(CLEANAMR) + rm -f \ + i386/*.o i386/*~ \ + armv4l/*.o armv4l/*~ \ + mlib/*.o mlib/*~ \ + alpha/*.o alpha/*~ \ + ppc/*.o ppc/*~ \ + ps2/*.o ps2/*~ \ + sh4/*.o sh4/*~ \ + sparc/*.o sparc/*~ \ + liba52/*.o liba52/*~ \ + apiexample $(TESTS) + +cleanamr: + $(MAKE) -C amr clean + +cleanamrfloat: + rm -f amr_float/*.o + +cleanamrwbfloat: + $(MAKE) -C amrwb_float -f makefile.gcc clean + +# api example program +apiexample: apiexample.c $(LIB) + $(CC) $(CFLAGS) -o $@ $< $(LIB) $(LIBAVUTIL) $(EXTRALIBS) + +# cpuid test +cpuid_test: i386/cputest.c + $(CC) $(CFLAGS) -D__TEST__ -o $@ $< + +# testing progs + +imgresample-test: imgresample.c + $(CC) $(CFLAGS) -DTEST -o $@ $^ -lm + +dct-test: dct-test.o fdctref.o $(LIB) + $(CC) -o $@ $^ -lm $(LIBAVUTIL) + +motion-test: motion_test.o $(LIB) + $(CC) -o $@ $^ -lm + +fft-test: fft-test.o $(LIB) + $(CC) -o $@ $^ $(LIBAVUTIL) -lm diff --git a/mpeg4/src/libavcodec/a52dec.c b/mpeg4/src/libavcodec/a52dec.c new file mode 100644 index 00000000..5226325a --- /dev/null +++ b/mpeg4/src/libavcodec/a52dec.c @@ -0,0 +1,255 @@ +/* + * A52 decoder + * Copyright (c) 2001 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file a52dec.c + * A52 decoder. + */ + +#include "avcodec.h" +#include "liba52/a52.h" + +#ifdef CONFIG_A52BIN +#include +static const char* liba52name = "liba52.so.0"; +#endif + +/** + * liba52 - Copyright (C) Aaron Holtzman + * released under the GPL license. + */ +typedef struct AC3DecodeState { + uint8_t inbuf[4096]; /* input buffer */ + uint8_t *inbuf_ptr; + int frame_size; + int flags; + int channels; + a52_state_t* state; + sample_t* samples; + + /* + * virtual method table + * + * using this function table so the liba52 doesn't + * have to be really linked together with ffmpeg + * and might be linked in runtime - this allows binary + * distribution of ffmpeg library which doens't depend + * on liba52 library - but if user has it installed + * it will be used - user might install such library + * separately + */ + void* handle; + a52_state_t* (*a52_init)(uint32_t mm_accel); + sample_t* (*a52_samples)(a52_state_t * state); + int (*a52_syncinfo)(uint8_t * buf, int * flags, + int * sample_rate, int * bit_rate); + int (*a52_frame)(a52_state_t * state, uint8_t * buf, int * flags, + sample_t * level, sample_t bias); + void (*a52_dynrng)(a52_state_t * state, + sample_t (* call) (sample_t, void *), void * data); + int (*a52_block)(a52_state_t * state); + void (*a52_free)(a52_state_t * state); + +} AC3DecodeState; + +#ifdef CONFIG_A52BIN +static void* dlsymm(void* handle, const char* symbol) +{ + void* f = dlsym(handle, symbol); + if (!f) + av_log( NULL, AV_LOG_ERROR, "A52 Decoder - function '%s' can't be resolved\n", symbol); + return f; +} +#endif + +static int a52_decode_init(AVCodecContext *avctx) +{ + AC3DecodeState *s = avctx->priv_data; + +#ifdef CONFIG_A52BIN + s->handle = dlopen(liba52name, RTLD_LAZY); + if (!s->handle) + { + av_log( avctx, AV_LOG_ERROR, "A52 library %s could not be opened! \n%s\n", liba52name, dlerror()); + return -1; + } + s->a52_init = (a52_state_t* (*)(uint32_t)) dlsymm(s->handle, "a52_init"); + s->a52_samples = (sample_t* (*)(a52_state_t*)) dlsymm(s->handle, "a52_samples"); + s->a52_syncinfo = (int (*)(uint8_t*, int*, int*, int*)) dlsymm(s->handle, "a52_syncinfo"); + s->a52_frame = (int (*)(a52_state_t*, uint8_t*, int*, sample_t*, sample_t)) dlsymm(s->handle, "a52_frame"); + s->a52_block = (int (*)(a52_state_t*)) dlsymm(s->handle, "a52_block"); + s->a52_free = (void (*)(a52_state_t*)) dlsymm(s->handle, "a52_free"); + if (!s->a52_init || !s->a52_samples || !s->a52_syncinfo + || !s->a52_frame || !s->a52_block || !s->a52_free) + { + dlclose(s->handle); + return -1; + } +#else + /* static linked version */ + s->handle = 0; + s->a52_init = a52_init; + s->a52_samples = a52_samples; + s->a52_syncinfo = a52_syncinfo; + s->a52_frame = a52_frame; + s->a52_block = a52_block; + s->a52_free = a52_free; +#endif + s->state = s->a52_init(0); /* later use CPU flags */ + s->samples = s->a52_samples(s->state); + s->inbuf_ptr = s->inbuf; + s->frame_size = 0; + + return 0; +} + +/**** the following two functions comes from a52dec */ +static inline int blah (int32_t i) +{ + if (i > 0x43c07fff) + return 32767; + else if (i < 0x43bf8000) + return -32768; + return i - 0x43c00000; +} + +static inline void float_to_int (float * _f, int16_t * s16, int nchannels) +{ + int i, j, c; + int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format + + j = 0; + nchannels *= 256; + for (i = 0; i < 256; i++) { + for (c = 0; c < nchannels; c += 256) + s16[j++] = blah (f[i + c]); + } +} + +/**** end */ + +#define HEADER_SIZE 7 + +static int a52_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + AC3DecodeState *s = avctx->priv_data; + uint8_t *buf_ptr; + int flags, i, len; + int sample_rate, bit_rate; + short *out_samples = data; + float level; + static const int ac3_channels[8] = { + 2, 1, 2, 3, 3, 4, 4, 5 + }; + + buf_ptr = buf; + while (buf_size > 0) { + len = s->inbuf_ptr - s->inbuf; + if (s->frame_size == 0) { + /* no header seen : find one. We need at least 7 bytes to parse it */ + len = HEADER_SIZE - len; + if (len > buf_size) + len = buf_size; + memcpy(s->inbuf_ptr, buf_ptr, len); + buf_ptr += len; + s->inbuf_ptr += len; + buf_size -= len; + if ((s->inbuf_ptr - s->inbuf) == HEADER_SIZE) { + len = s->a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate); + if (len == 0) { + /* no sync found : move by one byte (inefficient, but simple!) */ + memcpy(s->inbuf, s->inbuf + 1, HEADER_SIZE - 1); + s->inbuf_ptr--; + } else { + s->frame_size = len; + /* update codec info */ + avctx->sample_rate = sample_rate; + s->channels = ac3_channels[s->flags & 7]; + if (s->flags & A52_LFE) + s->channels++; + if (avctx->channels == 0) + /* No specific number of channel requested */ + avctx->channels = s->channels; + else if (s->channels < avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "ac3dec: AC3 Source channels are less than specified: output to %d channels.. (frmsize: %d)\n", s->channels, len); + avctx->channels = s->channels; + } + avctx->bit_rate = bit_rate; + } + } + } else if (len < s->frame_size) { + len = s->frame_size - len; + if (len > buf_size) + len = buf_size; + + memcpy(s->inbuf_ptr, buf_ptr, len); + buf_ptr += len; + s->inbuf_ptr += len; + buf_size -= len; + } else { + flags = s->flags; + if (avctx->channels == 1) + flags = A52_MONO; + else if (avctx->channels == 2) + flags = A52_STEREO; + else + flags |= A52_ADJUST_LEVEL; + level = 1; + if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { + fail: + s->inbuf_ptr = s->inbuf; + s->frame_size = 0; + continue; + } + for (i = 0; i < 6; i++) { + if (s->a52_block(s->state)) + goto fail; + float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); + } + s->inbuf_ptr = s->inbuf; + s->frame_size = 0; + *data_size = 6 * avctx->channels * 256 * sizeof(int16_t); + break; + } + } + return buf_ptr - buf; +} + +static int a52_decode_end(AVCodecContext *avctx) +{ + AC3DecodeState *s = avctx->priv_data; + s->a52_free(s->state); +#ifdef CONFIG_A52BIN + dlclose(s->handle); +#endif + return 0; +} + +AVCodec ac3_decoder = { + "ac3", + CODEC_TYPE_AUDIO, + CODEC_ID_AC3, + sizeof(AC3DecodeState), + a52_decode_init, + NULL, + a52_decode_end, + a52_decode_frame, +}; diff --git a/mpeg4/src/libavcodec/aasc.c b/mpeg4/src/libavcodec/aasc.c new file mode 100644 index 00000000..46228280 --- /dev/null +++ b/mpeg4/src/libavcodec/aasc.c @@ -0,0 +1,174 @@ +/* + * Autodesc RLE Decoder + * Copyright (C) 2005 the ffmpeg project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file aasc.c + * Autodesc RLE Video Decoder by Konstantin Shishkov + */ + +#include +#include +#include + +#include "common.h" +#include "avcodec.h" +#include "dsputil.h" + +typedef struct AascContext { + AVCodecContext *avctx; + AVFrame frame; +} AascContext; + +#define FETCH_NEXT_STREAM_BYTE() \ + if (stream_ptr >= buf_size) \ + { \ + av_log(s->avctx, AV_LOG_ERROR, " AASC: stream ptr just went out of bounds (fetch)\n"); \ + break; \ + } \ + stream_byte = buf[stream_ptr++]; + +static int aasc_decode_init(AVCodecContext *avctx) +{ + AascContext *s = (AascContext *)avctx->priv_data; + + s->avctx = avctx; + + avctx->pix_fmt = PIX_FMT_BGR24; + avctx->has_b_frames = 0; + s->frame.data[0] = NULL; + + return 0; +} + +static int aasc_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + AascContext *s = (AascContext *)avctx->priv_data; + int stream_ptr = 4; + unsigned char rle_code; + unsigned char stream_byte; + int pixel_ptr = 0; + int row_dec, row_ptr; + int frame_size; + int i; + + s->frame.reference = 1; + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &s->frame)) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + + row_dec = s->frame.linesize[0]; + row_ptr = (s->avctx->height - 1) * row_dec; + frame_size = row_dec * s->avctx->height; + + while (row_ptr >= 0) { + FETCH_NEXT_STREAM_BYTE(); + rle_code = stream_byte; + if (rle_code == 0) { + /* fetch the next byte to see how to handle escape code */ + FETCH_NEXT_STREAM_BYTE(); + if (stream_byte == 0) { + /* line is done, goto the next one */ + row_ptr -= row_dec; + pixel_ptr = 0; + } else if (stream_byte == 1) { + /* decode is done */ + break; + } else if (stream_byte == 2) { + /* reposition frame decode coordinates */ + FETCH_NEXT_STREAM_BYTE(); + pixel_ptr += stream_byte; + FETCH_NEXT_STREAM_BYTE(); + row_ptr -= stream_byte * row_dec; + } else { + /* copy pixels from encoded stream */ + if ((pixel_ptr + stream_byte > avctx->width * 3) || + (row_ptr < 0)) { + av_log(s->avctx, AV_LOG_ERROR, " AASC: frame ptr just went out of bounds (copy1)\n"); + break; + } + + rle_code = stream_byte; + if (stream_ptr + rle_code > buf_size) { + av_log(s->avctx, AV_LOG_ERROR, " AASC: stream ptr just went out of bounds (copy2)\n"); + break; + } + + for (i = 0; i < rle_code; i++) { + FETCH_NEXT_STREAM_BYTE(); + s->frame.data[0][row_ptr + pixel_ptr] = stream_byte; + pixel_ptr++; + } + if (rle_code & 1) + stream_ptr++; + } + } else { + /* decode a run of data */ + if ((pixel_ptr + rle_code > avctx->width * 3) || + (row_ptr < 0)) { + av_log(s->avctx, AV_LOG_ERROR, " AASC: frame ptr just went out of bounds (run1)\n"); + break; + } + + FETCH_NEXT_STREAM_BYTE(); + + while(rle_code--) { + s->frame.data[0][row_ptr + pixel_ptr] = stream_byte; + pixel_ptr++; + } + } + } + + /* one last sanity check on the way out */ + if (stream_ptr < buf_size) + av_log(s->avctx, AV_LOG_ERROR, " AASC: ended frame decode with bytes left over (%d < %d)\n", + stream_ptr, buf_size); + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = s->frame; + + /* report that the buffer was completely consumed */ + return buf_size; +} + +static int aasc_decode_end(AVCodecContext *avctx) +{ + AascContext *s = (AascContext *)avctx->priv_data; + + /* release the last frame */ + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + return 0; +} + +AVCodec aasc_decoder = { + "aasc", + CODEC_TYPE_VIDEO, + CODEC_ID_AASC, + sizeof(AascContext), + aasc_decode_init, + NULL, + aasc_decode_end, + aasc_decode_frame, + CODEC_CAP_DR1, +}; diff --git a/mpeg4/src/libavcodec/ac3.h b/mpeg4/src/libavcodec/ac3.h new file mode 100644 index 00000000..f59d16a9 --- /dev/null +++ b/mpeg4/src/libavcodec/ac3.h @@ -0,0 +1,63 @@ +/* + * Common code between AC3 encoder and decoder + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file ac3.h + * Common code between AC3 encoder and decoder. + */ + +#define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ +#define AC3_MAX_CHANNELS 6 /* including LFE channel */ + +#define NB_BLOCKS 6 /* number of PCM blocks inside an AC3 frame */ +#define AC3_FRAME_SIZE (NB_BLOCKS * 256) + +/* exponent encoding strategy */ +#define EXP_REUSE 0 +#define EXP_NEW 1 + +#define EXP_D15 1 +#define EXP_D25 2 +#define EXP_D45 3 + +typedef struct AC3BitAllocParameters { + int fscod; /* frequency */ + int halfratecod; + int sgain, sdecay, fdecay, dbknee, floor; + int cplfleak, cplsleak; +} AC3BitAllocParameters; + +#if 0 +extern const uint16_t ac3_freqs[3]; +extern const uint16_t ac3_bitratetab[19]; +extern const int16_t ac3_window[256]; +extern const uint8_t sdecaytab[4]; +extern const uint8_t fdecaytab[4]; +extern const uint16_t sgaintab[4]; +extern const uint16_t dbkneetab[4]; +extern const uint16_t floortab[8]; +extern const uint16_t fgaintab[8]; +#endif + +void ac3_common_init(void); +void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap, + int8_t *exp, int start, int end, + int snroffset, int fgain, int is_lfe, + int deltbae,int deltnseg, + uint8_t *deltoffst, uint8_t *deltlen, uint8_t *deltba); diff --git a/mpeg4/src/libavcodec/ac3dec.c b/mpeg4/src/libavcodec/ac3dec.c new file mode 100644 index 00000000..b6b7852e --- /dev/null +++ b/mpeg4/src/libavcodec/ac3dec.c @@ -0,0 +1,182 @@ +/* + * AC3 decoder + * Copyright (c) 2001 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file ac3dec.c + * AC3 decoder. + */ + +//#define DEBUG + +#include "avcodec.h" +#include "libac3/ac3.h" + +/* currently, I use libac3 which is Copyright (C) Aaron Holtzman and + released under the GPL license. I may reimplement it someday... */ +typedef struct AC3DecodeState { + uint8_t inbuf[4096]; /* input buffer */ + uint8_t *inbuf_ptr; + int frame_size; + int flags; + int channels; + ac3_state_t state; +} AC3DecodeState; + +static int ac3_decode_init(AVCodecContext *avctx) +{ + AC3DecodeState *s = avctx->priv_data; + + ac3_init (); + s->inbuf_ptr = s->inbuf; + s->frame_size = 0; + return 0; +} + +stream_samples_t samples; + +/**** the following two functions comes from ac3dec */ +static inline int blah (int32_t i) +{ + if (i > 0x43c07fff) + return 32767; + else if (i < 0x43bf8000) + return -32768; + else + return i - 0x43c00000; +} + +static inline void float_to_int (float * _f, int16_t * s16, int nchannels) +{ + int i, j, c; + int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format + + j = 0; + nchannels *= 256; + for (i = 0; i < 256; i++) { + for (c = 0; c < nchannels; c += 256) + s16[j++] = blah (f[i + c]); + } +} + +/**** end */ + +#define HEADER_SIZE 7 + +static int ac3_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + AC3DecodeState *s = avctx->priv_data; + uint8_t *buf_ptr; + int flags, i, len; + int sample_rate, bit_rate; + short *out_samples = data; + float level; + static const int ac3_channels[8] = { + 2, 1, 2, 3, 3, 4, 4, 5 + }; + + buf_ptr = buf; + while (buf_size > 0) { + len = s->inbuf_ptr - s->inbuf; + if (s->frame_size == 0) { + /* no header seen : find one. We need at least 7 bytes to parse it */ + len = HEADER_SIZE - len; + if (len > buf_size) + len = buf_size; + memcpy(s->inbuf_ptr, buf_ptr, len); + buf_ptr += len; + s->inbuf_ptr += len; + buf_size -= len; + if ((s->inbuf_ptr - s->inbuf) == HEADER_SIZE) { + len = ac3_syncinfo (s->inbuf, &s->flags, &sample_rate, &bit_rate); + if (len == 0) { + /* no sync found : move by one byte (inefficient, but simple!) */ + memcpy(s->inbuf, s->inbuf + 1, HEADER_SIZE - 1); + s->inbuf_ptr--; + } else { + s->frame_size = len; + /* update codec info */ + avctx->sample_rate = sample_rate; + s->channels = ac3_channels[s->flags & 7]; + if (s->flags & AC3_LFE) + s->channels++; + if (avctx->channels == 0) + /* No specific number of channel requested */ + avctx->channels = s->channels; + else if (s->channels < avctx->channels) { + av_log( avctx, AV_LOG_INFO, "ac3dec: AC3 Source channels are less than specified: output to %d channels.. (frmsize: %d)\n", s->channels, len); + avctx->channels = s->channels; + } + avctx->bit_rate = bit_rate; + } + } + } else if (len < s->frame_size) { + len = s->frame_size - len; + if (len > buf_size) + len = buf_size; + + memcpy(s->inbuf_ptr, buf_ptr, len); + buf_ptr += len; + s->inbuf_ptr += len; + buf_size -= len; + } else { + flags = s->flags; + if (avctx->channels == 1) + flags = AC3_MONO; + else if (avctx->channels == 2) + flags = AC3_STEREO; + else + flags |= AC3_ADJUST_LEVEL; + level = 1; + if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) { + fail: + s->inbuf_ptr = s->inbuf; + s->frame_size = 0; + continue; + } + for (i = 0; i < 6; i++) { + if (ac3_block (&s->state)) + goto fail; + float_to_int (*samples, out_samples + i * 256 * avctx->channels, avctx->channels); + } + s->inbuf_ptr = s->inbuf; + s->frame_size = 0; + *data_size = 6 * avctx->channels * 256 * sizeof(int16_t); + break; + } + } + return buf_ptr - buf; +} + +static int ac3_decode_end(AVCodecContext *s) +{ + return 0; +} + +AVCodec ac3_decoder = { + "ac3", + CODEC_TYPE_AUDIO, + CODEC_ID_AC3, + sizeof(AC3DecodeState), + ac3_decode_init, + NULL, + ac3_decode_end, + ac3_decode_frame, +}; diff --git a/mpeg4/src/libavcodec/ac3enc.c b/mpeg4/src/libavcodec/ac3enc.c new file mode 100644 index 00000000..a587c647 --- /dev/null +++ b/mpeg4/src/libavcodec/ac3enc.c @@ -0,0 +1,1602 @@ +/* + * The simplest AC3 encoder + * Copyright (c) 2000 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file ac3enc.c + * The simplest AC3 encoder. + */ +//#define DEBUG +//#define DEBUG_BITALLOC +#include "avcodec.h" +#include "bitstream.h" +#include "crc.h" +#include "ac3.h" + +typedef struct AC3EncodeContext { + PutBitContext pb; + int nb_channels; + int nb_all_channels; + int lfe_channel; + int bit_rate; + unsigned int sample_rate; + unsigned int bsid; + unsigned int frame_size_min; /* minimum frame size in case rounding is necessary */ + unsigned int frame_size; /* current frame size in words */ + unsigned int bits_written; + unsigned int samples_written; + int halfratecod; + unsigned int frmsizecod; + unsigned int fscod; /* frequency */ + unsigned int acmod; + int lfe; + unsigned int bsmod; + short last_samples[AC3_MAX_CHANNELS][256]; + unsigned int chbwcod[AC3_MAX_CHANNELS]; + int nb_coefs[AC3_MAX_CHANNELS]; + + /* bitrate allocation control */ + int sgaincod, sdecaycod, fdecaycod, dbkneecod, floorcod; + AC3BitAllocParameters bit_alloc; + int csnroffst; + int fgaincod[AC3_MAX_CHANNELS]; + int fsnroffst[AC3_MAX_CHANNELS]; + /* mantissa encoding */ + int mant1_cnt, mant2_cnt, mant4_cnt; +} AC3EncodeContext; + +#include "ac3tab.h" + +#define MDCT_NBITS 9 +#define N (1 << MDCT_NBITS) + +/* new exponents are sent if their Norm 1 exceed this number */ +#define EXP_DIFF_THRESHOLD 1000 + +static void fft_init(int ln); + +static inline int16_t fix15(float a) +{ + int v; + v = (int)(a * (float)(1 << 15)); + if (v < -32767) + v = -32767; + else if (v > 32767) + v = 32767; + return v; +} + + +/** + * Generate a Kaiser Window. + */ +static void k_window_init(int alpha, double *window, int n, int iter) +{ + int j, k; + double a, x; + a = alpha * M_PI / n; + a = a*a; + for(k=0; k0; j--) { + window[k] = (window[k] * x / (j*j)) + 1.0; + } + } +} + +/** + * Generate a Kaiser-Bessel Derived Window. + * @param alpha determines window shape + * @param window array to fill with window values + * @param iter number of iterations to use in BesselI0 + */ + +static void kbd_window_init(int alpha, int16_t *out_window, int iter) +{ + int k, n2; + double kwindow[256]; + double window[256]; + + n2 = 256; + k_window_init(alpha, kwindow, n2, iter); + window[0] = kwindow[0]; + for(k=1; k b1) { + a = a - 64; + if (a < 0) a=0; + } + return a; +} + +static inline int calc_lowcomp(int a, int b0, int b1, int bin) +{ + if (bin < 7) { + if ((b0 + 256) == b1) { + a = 384 ; + } else if (b0 > b1) { + a = a - 64; + if (a < 0) a=0; + } + } else if (bin < 20) { + if ((b0 + 256) == b1) { + a = 320 ; + } else if (b0 > b1) { + a= a - 64; + if (a < 0) a=0; + } + } else { + a = a - 128; + if (a < 0) a=0; + } + return a; +} + +/* AC3 bit allocation. The algorithm is the one described in the AC3 + spec. */ +void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap, + int8_t *exp, int start, int end, + int snroffset, int fgain, int is_lfe, + int deltbae,int deltnseg, + uint8_t *deltoffst, uint8_t *deltlen, uint8_t *deltba) +{ + int bin,i,j,k,end1,v,v1,bndstrt,bndend,lowcomp,begin; + int fastleak,slowleak,address,tmp; + int16_t psd[256]; /* scaled exponents */ + int16_t bndpsd[50]; /* interpolated exponents */ + int16_t excite[50]; /* excitation */ + int16_t mask[50]; /* masking value */ + + /* exponent mapping to PSD */ + for(bin=start;bin end) end1=end; + for(i=j;i= 0) { + adr=c >> 1; + if (adr > 255) adr=255; + v=v + latab[adr]; + } else { + adr=(-c) >> 1; + if (adr > 255) adr=255; + v=v1 + latab[adr]; + } + j++; + } + bndpsd[k]=v; + k++; + } while (end > bndtab[k]); + + /* excitation function */ + bndstrt = masktab[start]; + bndend = masktab[end-1] + 1; + + if (bndstrt == 0) { + lowcomp = 0; + lowcomp = calc_lowcomp1(lowcomp, bndpsd[0], bndpsd[1]) ; + excite[0] = bndpsd[0] - fgain - lowcomp ; + lowcomp = calc_lowcomp1(lowcomp, bndpsd[1], bndpsd[2]) ; + excite[1] = bndpsd[1] - fgain - lowcomp ; + begin = 7 ; + for (bin = 2; bin < 7; bin++) { + if (!(is_lfe && bin == 6)) + lowcomp = calc_lowcomp1(lowcomp, bndpsd[bin], bndpsd[bin+1]) ; + fastleak = bndpsd[bin] - fgain ; + slowleak = bndpsd[bin] - s->sgain ; + excite[bin] = fastleak - lowcomp ; + if (!(is_lfe && bin == 6)) { + if (bndpsd[bin] <= bndpsd[bin+1]) { + begin = bin + 1 ; + break ; + } + } + } + + end1=bndend; + if (end1 > 22) end1=22; + + for (bin = begin; bin < end1; bin++) { + if (!(is_lfe && bin == 6)) + lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin) ; + + fastleak -= s->fdecay ; + v = bndpsd[bin] - fgain; + if (fastleak < v) fastleak = v; + + slowleak -= s->sdecay ; + v = bndpsd[bin] - s->sgain; + if (slowleak < v) slowleak = v; + + v=fastleak - lowcomp; + if (slowleak > v) v=slowleak; + + excite[bin] = v; + } + begin = 22; + } else { + /* coupling channel */ + begin = bndstrt; + + fastleak = (s->cplfleak << 8) + 768; + slowleak = (s->cplsleak << 8) + 768; + } + + for (bin = begin; bin < bndend; bin++) { + fastleak -= s->fdecay ; + v = bndpsd[bin] - fgain; + if (fastleak < v) fastleak = v; + slowleak -= s->sdecay ; + v = bndpsd[bin] - s->sgain; + if (slowleak < v) slowleak = v; + + v=fastleak; + if (slowleak > v) v = slowleak; + excite[bin] = v; + } + + /* compute masking curve */ + + for (bin = bndstrt; bin < bndend; bin++) { + v1 = excite[bin]; + tmp = s->dbknee - bndpsd[bin]; + if (tmp > 0) { + v1 += tmp >> 2; + } + v=hth[bin >> s->halfratecod][s->fscod]; + if (v1 > v) v=v1; + mask[bin] = v; + } + + /* delta bit allocation */ + + if (deltbae == 0 || deltbae == 1) { + int band, seg, delta; + band = 0 ; + for (seg = 0; seg < deltnseg; seg++) { + band += deltoffst[seg] ; + if (deltba[seg] >= 4) { + delta = (deltba[seg] - 3) << 7; + } else { + delta = (deltba[seg] - 4) << 7; + } + for (k = 0; k < deltlen[seg]; k++) { + mask[band] += delta ; + band++ ; + } + } + } + + /* compute bit allocation */ + + i = start ; + j = masktab[start] ; + do { + v=mask[j]; + v -= snroffset ; + v -= s->floor ; + if (v < 0) v = 0; + v &= 0x1fe0 ; + v += s->floor ; + + end1=bndtab[j] + bndsz[j]; + if (end1 > end) end1=end; + + for (k = i; k < end1; k++) { + address = (psd[i] - v) >> 5 ; + if (address < 0) address=0; + else if (address > 63) address=63; + bap[i] = baptab[address]; + i++; + } + } while (end > bndtab[j++]) ; +} + +typedef struct IComplex { + short re,im; +} IComplex; + +static void fft_init(int ln) +{ + int i, j, m, n; + float alpha; + + n = 1 << ln; + + for(i=0;i<(n/2);i++) { + alpha = 2 * M_PI * (float)i / (float)n; + costab[i] = fix15(cos(alpha)); + sintab[i] = fix15(sin(alpha)); + } + + for(i=0;i> j) & 1) << (ln-j-1); + } + fft_rev[i]=m; + } +} + +/* butter fly op */ +#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \ +{\ + int ax, ay, bx, by;\ + bx=pre1;\ + by=pim1;\ + ax=qre1;\ + ay=qim1;\ + pre = (bx + ax) >> 1;\ + pim = (by + ay) >> 1;\ + qre = (bx - ax) >> 1;\ + qim = (by - ay) >> 1;\ +} + +#define MUL16(a,b) ((a) * (b)) + +#define CMUL(pre, pim, are, aim, bre, bim) \ +{\ + pre = (MUL16(are, bre) - MUL16(aim, bim)) >> 15;\ + pim = (MUL16(are, bim) + MUL16(bre, aim)) >> 15;\ +} + + +/* do a 2^n point complex fft on 2^ln points. */ +static void fft(IComplex *z, int ln) +{ + int j, l, np, np2; + int nblocks, nloops; + register IComplex *p,*q; + int tmp_re, tmp_im; + + np = 1 << ln; + + /* reverse */ + for(j=0;j> 1); + do { + BF(p[0].re, p[0].im, p[1].re, p[1].im, + p[0].re, p[0].im, p[1].re, p[1].im); + p+=2; + } while (--j != 0); + + /* pass 1 */ + + p=&z[0]; + j=np >> 2; + do { + BF(p[0].re, p[0].im, p[2].re, p[2].im, + p[0].re, p[0].im, p[2].re, p[2].im); + BF(p[1].re, p[1].im, p[3].re, p[3].im, + p[1].re, p[1].im, p[3].im, -p[3].re); + p+=4; + } while (--j != 0); + + /* pass 2 .. ln-1 */ + + nblocks = np >> 3; + nloops = 1 << 2; + np2 = np >> 1; + do { + p = z; + q = z + nloops; + for (j = 0; j < nblocks; ++j) { + + BF(p->re, p->im, q->re, q->im, + p->re, p->im, q->re, q->im); + + p++; + q++; + for(l = nblocks; l < np2; l += nblocks) { + CMUL(tmp_re, tmp_im, costab[l], -sintab[l], q->re, q->im); + BF(p->re, p->im, q->re, q->im, + p->re, p->im, tmp_re, tmp_im); + p++; + q++; + } + p += nloops; + q += nloops; + } + nblocks = nblocks >> 1; + nloops = nloops << 1; + } while (nblocks != 0); +} + +/* do a 512 point mdct */ +static void mdct512(int32_t *out, int16_t *in) +{ + int i, re, im, re1, im1; + int16_t rot[N]; + IComplex x[N/4]; + + /* shift to simplify computations */ + for(i=0;i> 1; + im = -((int)rot[N/2+2*i] - (int)rot[N/2-1-2*i]) >> 1; + CMUL(x[i].re, x[i].im, re, im, -xcos1[i], xsin1[i]); + } + + fft(x, MDCT_NBITS - 2); + + /* post rotation */ + for(i=0;i EXP_DIFF_THRESHOLD) + exp_strategy[i][ch] = EXP_NEW; + else + exp_strategy[i][ch] = EXP_REUSE; + } + if (is_lfe) + return; + + /* now select the encoding strategy type : if exponents are often + recoded, we use a coarse encoding */ + i = 0; + while (i < NB_BLOCKS) { + j = i + 1; + while (j < NB_BLOCKS && exp_strategy[j][ch] == EXP_REUSE) + j++; + switch(j - i) { + case 1: + exp_strategy[i][ch] = EXP_D45; + break; + case 2: + case 3: + exp_strategy[i][ch] = EXP_D25; + break; + default: + exp_strategy[i][ch] = EXP_D15; + break; + } + i = j; + } +} + +/* set exp[i] to min(exp[i], exp1[i]) */ +static void exponent_min(uint8_t exp[N/2], uint8_t exp1[N/2], int n) +{ + int i; + + for(i=0;i= 0 && exp_min <= 24); + for(j=1;j 15) + exp1[0] = 15; + + /* Decrease the delta between each groups to within 2 + * so that they can be differentially encoded */ + for (i=1;i<=nb_groups;i++) + exp1[i] = FFMIN(exp1[i], exp1[i-1] + 2); + for (i=nb_groups-1;i>=0;i--) + exp1[i] = FFMIN(exp1[i], exp1[i+1] + 2); + + /* now we have the exponent values the decoder will see */ + encoded_exp[0] = exp1[0]; + k = 1; + for(i=1;i<=nb_groups;i++) { + for(j=0;jmant1_cnt == 0) + bits += 5; + if (++s->mant1_cnt == 3) + s->mant1_cnt = 0; + break; + case 2: + /* 3 mantissa in 7 bits */ + if (s->mant2_cnt == 0) + bits += 7; + if (++s->mant2_cnt == 3) + s->mant2_cnt = 0; + break; + case 3: + bits += 3; + break; + case 4: + /* 2 mantissa in 7 bits */ + if (s->mant4_cnt == 0) + bits += 7; + if (++s->mant4_cnt == 2) + s->mant4_cnt = 0; + break; + case 14: + bits += 14; + break; + case 15: + bits += 16; + break; + default: + bits += mant - 1; + break; + } + } + return bits; +} + + +static int bit_alloc(AC3EncodeContext *s, + uint8_t bap[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], + uint8_t encoded_exp[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], + uint8_t exp_strategy[NB_BLOCKS][AC3_MAX_CHANNELS], + int frame_bits, int csnroffst, int fsnroffst) +{ + int i, ch; + + /* compute size */ + for(i=0;imant1_cnt = 0; + s->mant2_cnt = 0; + s->mant4_cnt = 0; + for(ch=0;chnb_all_channels;ch++) { + ac3_parametric_bit_allocation(&s->bit_alloc, + bap[i][ch], (int8_t *)encoded_exp[i][ch], + 0, s->nb_coefs[ch], + (((csnroffst-15) << 4) + + fsnroffst) << 2, + fgaintab[s->fgaincod[ch]], + ch == s->lfe_channel, + 2, 0, NULL, NULL, NULL); + frame_bits += compute_mantissa_size(s, bap[i][ch], + s->nb_coefs[ch]); + } + } +#if 0 + printf("csnr=%d fsnr=%d frame_bits=%d diff=%d\n", + csnroffst, fsnroffst, frame_bits, + 16 * s->frame_size - ((frame_bits + 7) & ~7)); +#endif + return 16 * s->frame_size - frame_bits; +} + +#define SNR_INC1 4 + +static int compute_bit_allocation(AC3EncodeContext *s, + uint8_t bap[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], + uint8_t encoded_exp[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], + uint8_t exp_strategy[NB_BLOCKS][AC3_MAX_CHANNELS], + int frame_bits) +{ + int i, ch; + int csnroffst, fsnroffst; + uint8_t bap1[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; + static int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 }; + + /* init default parameters */ + s->sdecaycod = 2; + s->fdecaycod = 1; + s->sgaincod = 1; + s->dbkneecod = 2; + s->floorcod = 4; + for(ch=0;chnb_all_channels;ch++) + s->fgaincod[ch] = 4; + + /* compute real values */ + s->bit_alloc.fscod = s->fscod; + s->bit_alloc.halfratecod = s->halfratecod; + s->bit_alloc.sdecay = sdecaytab[s->sdecaycod] >> s->halfratecod; + s->bit_alloc.fdecay = fdecaytab[s->fdecaycod] >> s->halfratecod; + s->bit_alloc.sgain = sgaintab[s->sgaincod]; + s->bit_alloc.dbknee = dbkneetab[s->dbkneecod]; + s->bit_alloc.floor = floortab[s->floorcod]; + + /* header size */ + frame_bits += 65; + // if (s->acmod == 2) + // frame_bits += 2; + frame_bits += frame_bits_inc[s->acmod]; + + /* audio blocks */ + for(i=0;inb_channels * 2 + 2; /* blksw * c, dithflag * c, dynrnge, cplstre */ + if (s->acmod == 2) { + frame_bits++; /* rematstr */ + if(i==0) frame_bits += 4; + } + frame_bits += 2 * s->nb_channels; /* chexpstr[2] * c */ + if (s->lfe) + frame_bits++; /* lfeexpstr */ + for(ch=0;chnb_channels;ch++) { + if (exp_strategy[i][ch] != EXP_REUSE) + frame_bits += 6 + 2; /* chbwcod[6], gainrng[2] */ + } + frame_bits++; /* baie */ + frame_bits++; /* snr */ + frame_bits += 2; /* delta / skip */ + } + frame_bits++; /* cplinu for block 0 */ + /* bit alloc info */ + /* sdcycod[2], fdcycod[2], sgaincod[2], dbpbcod[2], floorcod[3] */ + /* csnroffset[6] */ + /* (fsnoffset[4] + fgaincod[4]) * c */ + frame_bits += 2*4 + 3 + 6 + s->nb_all_channels * (4 + 3); + + /* auxdatae, crcrsv */ + frame_bits += 2; + + /* CRC */ + frame_bits += 16; + + /* now the big work begins : do the bit allocation. Modify the snr + offset until we can pack everything in the requested frame size */ + + csnroffst = s->csnroffst; + while (csnroffst >= 0 && + bit_alloc(s, bap, encoded_exp, exp_strategy, frame_bits, csnroffst, 0) < 0) + csnroffst -= SNR_INC1; + if (csnroffst < 0) { + av_log(NULL, AV_LOG_ERROR, "Bit allocation failed, try increasing the bitrate, -ab 384 for example!\n"); + return -1; + } + while ((csnroffst + SNR_INC1) <= 63 && + bit_alloc(s, bap1, encoded_exp, exp_strategy, frame_bits, + csnroffst + SNR_INC1, 0) >= 0) { + csnroffst += SNR_INC1; + memcpy(bap, bap1, sizeof(bap1)); + } + while ((csnroffst + 1) <= 63 && + bit_alloc(s, bap1, encoded_exp, exp_strategy, frame_bits, csnroffst + 1, 0) >= 0) { + csnroffst++; + memcpy(bap, bap1, sizeof(bap1)); + } + + fsnroffst = 0; + while ((fsnroffst + SNR_INC1) <= 15 && + bit_alloc(s, bap1, encoded_exp, exp_strategy, frame_bits, + csnroffst, fsnroffst + SNR_INC1) >= 0) { + fsnroffst += SNR_INC1; + memcpy(bap, bap1, sizeof(bap1)); + } + while ((fsnroffst + 1) <= 15 && + bit_alloc(s, bap1, encoded_exp, exp_strategy, frame_bits, + csnroffst, fsnroffst + 1) >= 0) { + fsnroffst++; + memcpy(bap, bap1, sizeof(bap1)); + } + + s->csnroffst = csnroffst; + for(ch=0;chnb_all_channels;ch++) + s->fsnroffst[ch] = fsnroffst; +#if defined(DEBUG_BITALLOC) + { + int j; + + for(i=0;i<6;i++) { + for(ch=0;chnb_all_channels;ch++) { + printf("Block #%d Ch%d:\n", i, ch); + printf("bap="); + for(j=0;jnb_coefs[ch];j++) { + printf("%d ",bap[i][ch][j]); + } + printf("\n"); + } + } + } +#endif + return 0; +} + +void ac3_common_init(void) +{ + int i, j, k, l, v; + /* compute bndtab and masktab from bandsz */ + k = 0; + l = 0; + for(i=0;i<50;i++) { + bndtab[i] = l; + v = bndsz[i]; + for(j=0;jsample_rate; + int bitrate = avctx->bit_rate; + int channels = avctx->channels; + AC3EncodeContext *s = avctx->priv_data; + int i, j, ch; + float alpha; + static const uint8_t acmod_defs[6] = { + 0x01, /* C */ + 0x02, /* L R */ + 0x03, /* L C R */ + 0x06, /* L R SL SR */ + 0x07, /* L C R SL SR */ + 0x07, /* L C R SL SR (+LFE) */ + }; + + avctx->frame_size = AC3_FRAME_SIZE; + + /* number of channels */ + if (channels < 1 || channels > 6) + return -1; + s->acmod = acmod_defs[channels - 1]; + s->lfe = (channels == 6) ? 1 : 0; + s->nb_all_channels = channels; + s->nb_channels = channels > 5 ? 5 : channels; + s->lfe_channel = s->lfe ? 5 : -1; + + /* frequency */ + for(i=0;i<3;i++) { + for(j=0;j<3;j++) + if ((ac3_freqs[j] >> i) == freq) + goto found; + } + return -1; + found: + s->sample_rate = freq; + s->halfratecod = i; + s->fscod = j; + s->bsid = 8 + s->halfratecod; + s->bsmod = 0; /* complete main audio service */ + + /* bitrate & frame size */ + bitrate /= 1000; + for(i=0;i<19;i++) { + if ((ac3_bitratetab[i] >> s->halfratecod) == bitrate) + break; + } + if (i == 19) + return -1; + s->bit_rate = bitrate; + s->frmsizecod = i << 1; + s->frame_size_min = (bitrate * 1000 * AC3_FRAME_SIZE) / (freq * 16); + s->bits_written = 0; + s->samples_written = 0; + s->frame_size = s->frame_size_min; + + /* bit allocation init */ + for(ch=0;chnb_channels;ch++) { + /* bandwidth for each channel */ + /* XXX: should compute the bandwidth according to the frame + size, so that we avoid anoying high freq artefacts */ + s->chbwcod[ch] = 50; /* sample bandwidth as mpeg audio layer 2 table 0 */ + s->nb_coefs[ch] = ((s->chbwcod[ch] + 12) * 3) + 37; + } + if (s->lfe) { + s->nb_coefs[s->lfe_channel] = 7; /* fixed */ + } + /* initial snr offset */ + s->csnroffst = 40; + + ac3_common_init(); + + /* mdct init */ + kbd_window_init(5.0, ac3_window, 50); + + fft_init(MDCT_NBITS - 2); + for(i=0;icoded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + + return 0; +} + +/* output the AC3 frame header */ +static void output_frame_header(AC3EncodeContext *s, unsigned char *frame) +{ + init_put_bits(&s->pb, frame, AC3_MAX_CODED_FRAME_SIZE); + + put_bits(&s->pb, 16, 0x0b77); /* frame header */ + put_bits(&s->pb, 16, 0); /* crc1: will be filled later */ + put_bits(&s->pb, 2, s->fscod); + put_bits(&s->pb, 6, s->frmsizecod + (s->frame_size - s->frame_size_min)); + put_bits(&s->pb, 5, s->bsid); + put_bits(&s->pb, 3, s->bsmod); + put_bits(&s->pb, 3, s->acmod); + if ((s->acmod & 0x01) && s->acmod != 0x01) + put_bits(&s->pb, 2, 1); /* XXX -4.5 dB */ + if (s->acmod & 0x04) + put_bits(&s->pb, 2, 1); /* XXX -6 dB */ + if (s->acmod == 0x02) + put_bits(&s->pb, 2, 0); /* surround not indicated */ + put_bits(&s->pb, 1, s->lfe); /* LFE */ + put_bits(&s->pb, 5, 31); /* dialog norm: -31 db */ + put_bits(&s->pb, 1, 0); /* no compression control word */ + put_bits(&s->pb, 1, 0); /* no lang code */ + put_bits(&s->pb, 1, 0); /* no audio production info */ + put_bits(&s->pb, 1, 0); /* no copyright */ + put_bits(&s->pb, 1, 1); /* original bitstream */ + put_bits(&s->pb, 1, 0); /* no time code 1 */ + put_bits(&s->pb, 1, 0); /* no time code 2 */ + put_bits(&s->pb, 1, 0); /* no addtional bit stream info */ +} + +/* symetric quantization on 'levels' levels */ +static inline int sym_quant(int c, int e, int levels) +{ + int v; + + if (c >= 0) { + v = (levels * (c << e)) >> 24; + v = (v + 1) >> 1; + v = (levels >> 1) + v; + } else { + v = (levels * ((-c) << e)) >> 24; + v = (v + 1) >> 1; + v = (levels >> 1) - v; + } + assert (v >= 0 && v < levels); + return v; +} + +/* asymetric quantization on 2^qbits levels */ +static inline int asym_quant(int c, int e, int qbits) +{ + int lshift, m, v; + + lshift = e + qbits - 24; + if (lshift >= 0) + v = c << lshift; + else + v = c >> (-lshift); + /* rounding */ + v = (v + 1) >> 1; + m = (1 << (qbits-1)); + if (v >= m) + v = m - 1; + assert(v >= -m); + return v & ((1 << qbits)-1); +} + +/* Output one audio block. There are NB_BLOCKS audio blocks in one AC3 + frame */ +static void output_audio_block(AC3EncodeContext *s, + uint8_t exp_strategy[AC3_MAX_CHANNELS], + uint8_t encoded_exp[AC3_MAX_CHANNELS][N/2], + uint8_t bap[AC3_MAX_CHANNELS][N/2], + int32_t mdct_coefs[AC3_MAX_CHANNELS][N/2], + int8_t global_exp[AC3_MAX_CHANNELS], + int block_num) +{ + int ch, nb_groups, group_size, i, baie, rbnd; + uint8_t *p; + uint16_t qmant[AC3_MAX_CHANNELS][N/2]; + int exp0, exp1; + int mant1_cnt, mant2_cnt, mant4_cnt; + uint16_t *qmant1_ptr, *qmant2_ptr, *qmant4_ptr; + int delta0, delta1, delta2; + + for(ch=0;chnb_channels;ch++) + put_bits(&s->pb, 1, 0); /* 512 point MDCT */ + for(ch=0;chnb_channels;ch++) + put_bits(&s->pb, 1, 1); /* no dither */ + put_bits(&s->pb, 1, 0); /* no dynamic range */ + if (block_num == 0) { + /* for block 0, even if no coupling, we must say it. This is a + waste of bit :-) */ + put_bits(&s->pb, 1, 1); /* coupling strategy present */ + put_bits(&s->pb, 1, 0); /* no coupling strategy */ + } else { + put_bits(&s->pb, 1, 0); /* no new coupling strategy */ + } + + if (s->acmod == 2) + { + if(block_num==0) + { + /* first block must define rematrixing (rematstr) */ + put_bits(&s->pb, 1, 1); + + /* dummy rematrixing rematflg(1:4)=0 */ + for (rbnd=0;rbnd<4;rbnd++) + put_bits(&s->pb, 1, 0); + } + else + { + /* no matrixing (but should be used in the future) */ + put_bits(&s->pb, 1, 0); + } + } + +#if defined(DEBUG) + { + static int count = 0; + av_log(NULL, AV_LOG_DEBUG, "Block #%d (%d)\n", block_num, count++); + } +#endif + /* exponent strategy */ + for(ch=0;chnb_channels;ch++) { + put_bits(&s->pb, 2, exp_strategy[ch]); + } + + if (s->lfe) { + put_bits(&s->pb, 1, exp_strategy[s->lfe_channel]); + } + + for(ch=0;chnb_channels;ch++) { + if (exp_strategy[ch] != EXP_REUSE) + put_bits(&s->pb, 6, s->chbwcod[ch]); + } + + /* exponents */ + for (ch = 0; ch < s->nb_all_channels; ch++) { + switch(exp_strategy[ch]) { + case EXP_REUSE: + continue; + case EXP_D15: + group_size = 1; + break; + case EXP_D25: + group_size = 2; + break; + default: + case EXP_D45: + group_size = 4; + break; + } + nb_groups = (s->nb_coefs[ch] + (group_size * 3) - 4) / (3 * group_size); + p = encoded_exp[ch]; + + /* first exponent */ + exp1 = *p++; + put_bits(&s->pb, 4, exp1); + + /* next ones are delta encoded */ + for(i=0;ipb, 7, ((delta0 * 5 + delta1) * 5) + delta2); + } + + if (ch != s->lfe_channel) + put_bits(&s->pb, 2, 0); /* no gain range info */ + } + + /* bit allocation info */ + baie = (block_num == 0); + put_bits(&s->pb, 1, baie); + if (baie) { + put_bits(&s->pb, 2, s->sdecaycod); + put_bits(&s->pb, 2, s->fdecaycod); + put_bits(&s->pb, 2, s->sgaincod); + put_bits(&s->pb, 2, s->dbkneecod); + put_bits(&s->pb, 3, s->floorcod); + } + + /* snr offset */ + put_bits(&s->pb, 1, baie); /* always present with bai */ + if (baie) { + put_bits(&s->pb, 6, s->csnroffst); + for(ch=0;chnb_all_channels;ch++) { + put_bits(&s->pb, 4, s->fsnroffst[ch]); + put_bits(&s->pb, 3, s->fgaincod[ch]); + } + } + + put_bits(&s->pb, 1, 0); /* no delta bit allocation */ + put_bits(&s->pb, 1, 0); /* no data to skip */ + + /* mantissa encoding : we use two passes to handle the grouping. A + one pass method may be faster, but it would necessitate to + modify the output stream. */ + + /* first pass: quantize */ + mant1_cnt = mant2_cnt = mant4_cnt = 0; + qmant1_ptr = qmant2_ptr = qmant4_ptr = NULL; + + for (ch = 0; ch < s->nb_all_channels; ch++) { + int b, c, e, v; + + for(i=0;inb_coefs[ch];i++) { + c = mdct_coefs[ch][i]; + e = encoded_exp[ch][i] - global_exp[ch]; + b = bap[ch][i]; + switch(b) { + case 0: + v = 0; + break; + case 1: + v = sym_quant(c, e, 3); + switch(mant1_cnt) { + case 0: + qmant1_ptr = &qmant[ch][i]; + v = 9 * v; + mant1_cnt = 1; + break; + case 1: + *qmant1_ptr += 3 * v; + mant1_cnt = 2; + v = 128; + break; + default: + *qmant1_ptr += v; + mant1_cnt = 0; + v = 128; + break; + } + break; + case 2: + v = sym_quant(c, e, 5); + switch(mant2_cnt) { + case 0: + qmant2_ptr = &qmant[ch][i]; + v = 25 * v; + mant2_cnt = 1; + break; + case 1: + *qmant2_ptr += 5 * v; + mant2_cnt = 2; + v = 128; + break; + default: + *qmant2_ptr += v; + mant2_cnt = 0; + v = 128; + break; + } + break; + case 3: + v = sym_quant(c, e, 7); + break; + case 4: + v = sym_quant(c, e, 11); + switch(mant4_cnt) { + case 0: + qmant4_ptr = &qmant[ch][i]; + v = 11 * v; + mant4_cnt = 1; + break; + default: + *qmant4_ptr += v; + mant4_cnt = 0; + v = 128; + break; + } + break; + case 5: + v = sym_quant(c, e, 15); + break; + case 14: + v = asym_quant(c, e, 14); + break; + case 15: + v = asym_quant(c, e, 16); + break; + default: + v = asym_quant(c, e, b - 1); + break; + } + qmant[ch][i] = v; + } + } + + /* second pass : output the values */ + for (ch = 0; ch < s->nb_all_channels; ch++) { + int b, q; + + for(i=0;inb_coefs[ch];i++) { + q = qmant[ch][i]; + b = bap[ch][i]; + switch(b) { + case 0: + break; + case 1: + if (q != 128) + put_bits(&s->pb, 5, q); + break; + case 2: + if (q != 128) + put_bits(&s->pb, 7, q); + break; + case 3: + put_bits(&s->pb, 3, q); + break; + case 4: + if (q != 128) + put_bits(&s->pb, 7, q); + break; + case 14: + put_bits(&s->pb, 14, q); + break; + case 15: + put_bits(&s->pb, 16, q); + break; + default: + put_bits(&s->pb, b - 1, q); + break; + } + } + } +} + +#define CRC16_POLY ((1 << 0) | (1 << 2) | (1 << 15) | (1 << 16)) + +static unsigned int mul_poly(unsigned int a, unsigned int b, unsigned int poly) +{ + unsigned int c; + + c = 0; + while (a) { + if (a & 1) + c ^= b; + a = a >> 1; + b = b << 1; + if (b & (1 << 16)) + b ^= poly; + } + return c; +} + +static unsigned int pow_poly(unsigned int a, unsigned int n, unsigned int poly) +{ + unsigned int r; + r = 1; + while (n) { + if (n & 1) + r = mul_poly(r, a, poly); + a = mul_poly(a, a, poly); + n >>= 1; + } + return r; +} + + +/* compute log2(max(abs(tab[]))) */ +static int log2_tab(int16_t *tab, int n) +{ + int i, v; + + v = 0; + for(i=0;i 0) { + for(i=0;i>= lshift; + } + } +} + +/* fill the end of the frame and compute the two crcs */ +static int output_frame_end(AC3EncodeContext *s) +{ + int frame_size, frame_size_58, n, crc1, crc2, crc_inv; + uint8_t *frame; + + frame_size = s->frame_size; /* frame size in words */ + /* align to 8 bits */ + flush_put_bits(&s->pb); + /* add zero bytes to reach the frame size */ + frame = s->pb.buf; + n = 2 * s->frame_size - (pbBufPtr(&s->pb) - frame) - 2; + assert(n >= 0); + if(n>0) + memset(pbBufPtr(&s->pb), 0, n); + + /* Now we must compute both crcs : this is not so easy for crc1 + because it is at the beginning of the data... */ + frame_size_58 = (frame_size >> 1) + (frame_size >> 3); + crc1 = bswap_16(av_crc(av_crc8005, 0, frame + 4, 2 * frame_size_58 - 4)); + /* XXX: could precompute crc_inv */ + crc_inv = pow_poly((CRC16_POLY >> 1), (16 * frame_size_58) - 16, CRC16_POLY); + crc1 = mul_poly(crc_inv, crc1, CRC16_POLY); + frame[2] = crc1 >> 8; + frame[3] = crc1; + + crc2 = bswap_16(av_crc(av_crc8005, 0, frame + 2 * frame_size_58, (frame_size - frame_size_58) * 2 - 2)); + frame[2*frame_size - 2] = crc2 >> 8; + frame[2*frame_size - 1] = crc2; + + // printf("n=%d frame_size=%d\n", n, frame_size); + return frame_size * 2; +} + +static int AC3_encode_frame(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) +{ + AC3EncodeContext *s = avctx->priv_data; + int16_t *samples = data; + int i, j, k, v, ch; + int16_t input_samples[N]; + int32_t mdct_coef[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; + uint8_t exp[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; + uint8_t exp_strategy[NB_BLOCKS][AC3_MAX_CHANNELS]; + uint8_t encoded_exp[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; + uint8_t bap[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; + int8_t exp_samples[NB_BLOCKS][AC3_MAX_CHANNELS]; + int frame_bits; + + frame_bits = 0; + for(ch=0;chnb_all_channels;ch++) { + /* fixed mdct to the six sub blocks & exponent computation */ + for(i=0;ilast_samples[ch], N/2 * sizeof(int16_t)); + sinc = s->nb_all_channels; + sptr = samples + (sinc * (N/2) * i) + ch; + for(j=0;jlast_samples[ch][j] = v; + sptr += sinc; + } + + /* apply the MDCT window */ + for(j=0;j> 15; + input_samples[N-j-1] = MUL16(input_samples[N-j-1], + ac3_window[j]) >> 15; + } + + /* Normalize the samples to use the maximum available + precision */ + v = 14 - log2_tab(input_samples, N); + if (v < 0) + v = 0; + exp_samples[i][ch] = v - 9; + lshift_tab(input_samples, N, v); + + /* do the MDCT */ + mdct512(mdct_coef[i][ch], input_samples); + + /* compute "exponents". We take into account the + normalization there */ + for(j=0;j= 24) { + e = 24; + mdct_coef[i][ch][j] = 0; + } + } + exp[i][ch][j] = e; + } + } + + compute_exp_strategy(exp_strategy, exp, ch, ch == s->lfe_channel); + + /* compute the exponents as the decoder will see them. The + EXP_REUSE case must be handled carefully : we select the + min of the exponents */ + i = 0; + while (i < NB_BLOCKS) { + j = i + 1; + while (j < NB_BLOCKS && exp_strategy[j][ch] == EXP_REUSE) { + exponent_min(exp[i][ch], exp[j][ch], s->nb_coefs[ch]); + j++; + } + frame_bits += encode_exp(encoded_exp[i][ch], + exp[i][ch], s->nb_coefs[ch], + exp_strategy[i][ch]); + /* copy encoded exponents for reuse case */ + for(k=i+1;knb_coefs[ch] * sizeof(uint8_t)); + } + i = j; + } + } + + /* adjust for fractional frame sizes */ + while(s->bits_written >= s->bit_rate*1000 && s->samples_written >= s->sample_rate) { + s->bits_written -= s->bit_rate*1000; + s->samples_written -= s->sample_rate; + } + s->frame_size = s->frame_size_min + (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate*1000); + s->bits_written += s->frame_size * 16; + s->samples_written += AC3_FRAME_SIZE; + + compute_bit_allocation(s, bap, encoded_exp, exp_strategy, frame_bits); + /* everything is known... let's output the frame */ + output_frame_header(s, frame); + + for(i=0;icoded_frame); + return 0; +} + +#if 0 +/*************************************************************************/ +/* TEST */ + +#define FN (N/4) + +void fft_test(void) +{ + IComplex in[FN], in1[FN]; + int k, n, i; + float sum_re, sum_im, a; + + /* FFT test */ + + for(i=0;i emax) + emax = e; + err += e * e; + } + printf("err2=%f emax=%f\n", err / (N/2), emax); +} + +void test_ac3(void) +{ + AC3EncodeContext ctx; + unsigned char frame[AC3_MAX_CODED_FRAME_SIZE]; + short samples[AC3_FRAME_SIZE]; + int ret, i; + + AC3_encode_init(&ctx, 44100, 64000, 1); + + fft_test(); + mdct_test(); + + for(i=0;i 32767) \ + value = 32767; \ +else if (value < -32768) \ + value = -32768; \ + +/* step_table[] and index_table[] are from the ADPCM reference source */ +/* This is the index table: */ +static const int index_table[16] = { + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8, +}; + +/** + * This is the step table. Note that many programs use slight deviations from + * this table, but such deviations are negligible: + */ +static const int step_table[89] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +/* These are for MS-ADPCM */ +/* AdaptationTable[], AdaptCoeff1[], and AdaptCoeff2[] are from libsndfile */ +static const int AdaptationTable[] = { + 230, 230, 230, 230, 307, 409, 512, 614, + 768, 614, 512, 409, 307, 230, 230, 230 +}; + +static const int AdaptCoeff1[] = { + 256, 512, 0, 192, 240, 460, 392 +}; + +static const int AdaptCoeff2[] = { + 0, -256, 0, 64, 0, -208, -232 +}; + +/* These are for CD-ROM XA ADPCM */ +static const int xa_adpcm_table[5][2] = { + { 0, 0 }, + { 60, 0 }, + { 115, -52 }, + { 98, -55 }, + { 122, -60 } +}; + +static const int ea_adpcm_table[] = { + 0, 240, 460, 392, 0, 0, -208, -220, 0, 1, + 3, 4, 7, 8, 10, 11, 0, -1, -3, -4 +}; + +static const int ct_adpcm_table[8] = { + 0x00E6, 0x00E6, 0x00E6, 0x00E6, + 0x0133, 0x0199, 0x0200, 0x0266 +}; + +// padded to zero where table size is less then 16 +static const int swf_index_tables[4][16] = { + /*2*/ { -1, 2 }, + /*3*/ { -1, -1, 2, 4 }, + /*4*/ { -1, -1, -1, -1, 2, 4, 6, 8 }, + /*5*/ { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 } +}; + +static const int yamaha_indexscale[] = { + 230, 230, 230, 230, 307, 409, 512, 614, + 230, 230, 230, 230, 307, 409, 512, 614 +}; + +static const int yamaha_difflookup[] = { + 1, 3, 5, 7, 9, 11, 13, 15, + -1, -3, -5, -7, -9, -11, -13, -15 +}; + +/* end of tables */ + +typedef struct ADPCMChannelStatus { + int predictor; + short int step_index; + int step; + /* for encoding */ + int prev_sample; + + /* MS version */ + short sample1; + short sample2; + int coeff1; + int coeff2; + int idelta; +} ADPCMChannelStatus; + +typedef struct ADPCMContext { + int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */ + ADPCMChannelStatus status[2]; + short sample_buffer[32]; /* hold left samples while waiting for right samples */ + + /* SWF only */ + int nb_bits; + int nb_samples; +} ADPCMContext; + +/* XXX: implement encoding */ + +#ifdef CONFIG_ENCODERS +static int adpcm_encode_init(AVCodecContext *avctx) +{ + if (avctx->channels > 2) + return -1; /* only stereo or mono =) */ + switch(avctx->codec->id) { + case CODEC_ID_ADPCM_IMA_QT: + av_log(avctx, AV_LOG_ERROR, "ADPCM: codec adpcm_ima_qt unsupported for encoding !\n"); + avctx->frame_size = 64; /* XXX: can multiple of avctx->channels * 64 (left and right blocks are interleaved) */ + return -1; + break; + case CODEC_ID_ADPCM_IMA_WAV: + avctx->frame_size = (BLKSIZE - 4 * avctx->channels) * 8 / (4 * avctx->channels) + 1; /* each 16 bits sample gives one nibble */ + /* and we have 4 bytes per channel overhead */ + avctx->block_align = BLKSIZE; + /* seems frame_size isn't taken into account... have to buffer the samples :-( */ + break; + case CODEC_ID_ADPCM_MS: + avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 / avctx->channels + 2; /* each 16 bits sample gives one nibble */ + /* and we have 7 bytes per channel overhead */ + avctx->block_align = BLKSIZE; + break; + case CODEC_ID_ADPCM_YAMAHA: + avctx->frame_size = BLKSIZE * avctx->channels; + avctx->block_align = BLKSIZE; + break; + default: + return -1; + break; + } + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + + return 0; +} + +static int adpcm_encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + + return 0; +} + + +static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, short sample) +{ + int step_index; + unsigned char nibble; + + int sign = 0; /* sign bit of the nibble (MSB) */ + int delta, predicted_delta; + + delta = sample - c->prev_sample; + + if (delta < 0) { + sign = 1; + delta = -delta; + } + + step_index = c->step_index; + + /* nibble = 4 * delta / step_table[step_index]; */ + nibble = (delta << 2) / step_table[step_index]; + + if (nibble > 7) + nibble = 7; + + step_index += index_table[nibble]; + if (step_index < 0) + step_index = 0; + if (step_index > 88) + step_index = 88; + + /* what the decoder will find */ + predicted_delta = ((step_table[step_index] * nibble) / 4) + (step_table[step_index] / 8); + + if (sign) + c->prev_sample -= predicted_delta; + else + c->prev_sample += predicted_delta; + + CLAMP_TO_SHORT(c->prev_sample); + + + nibble += sign << 3; /* sign * 8 */ + + /* save back */ + c->step_index = step_index; + + return nibble; +} + +static inline unsigned char adpcm_ms_compress_sample(ADPCMChannelStatus *c, short sample) +{ + int predictor, nibble, bias; + + predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256; + + nibble= sample - predictor; + if(nibble>=0) bias= c->idelta/2; + else bias=-c->idelta/2; + + nibble= (nibble + bias) / c->idelta; + nibble= clip(nibble, -8, 7)&0x0F; + + predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta; + CLAMP_TO_SHORT(predictor); + + c->sample2 = c->sample1; + c->sample1 = predictor; + + c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8; + if (c->idelta < 16) c->idelta = 16; + + return nibble; +} + +static inline unsigned char adpcm_yamaha_compress_sample(ADPCMChannelStatus *c, short sample) +{ + int i1 = 0, j1; + + if(!c->step) { + c->predictor = 0; + c->step = 127; + } + j1 = sample - c->predictor; + + j1 = (j1 * 8) / c->step; + i1 = abs(j1) / 2; + if (i1 > 7) + i1 = 7; + if (j1 < 0) + i1 += 8; + + c->predictor = c->predictor + ((c->step * yamaha_difflookup[i1]) / 8); + CLAMP_TO_SHORT(c->predictor); + c->step = (c->step * yamaha_indexscale[i1]) >> 8; + c->step = clip(c->step, 127, 24567); + + return i1; +} + +static int adpcm_encode_frame(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) +{ + int n, i, st; + short *samples; + unsigned char *dst; + ADPCMContext *c = avctx->priv_data; + + dst = frame; + samples = (short *)data; + st= avctx->channels == 2; +/* n = (BLKSIZE - 4 * avctx->channels) / (2 * 8 * avctx->channels); */ + + switch(avctx->codec->id) { + case CODEC_ID_ADPCM_IMA_QT: /* XXX: can't test until we get .mov writer */ + break; + case CODEC_ID_ADPCM_IMA_WAV: + n = avctx->frame_size / 8; + c->status[0].prev_sample = (signed short)samples[0]; /* XXX */ +/* c->status[0].step_index = 0; *//* XXX: not sure how to init the state machine */ + *dst++ = (c->status[0].prev_sample) & 0xFF; /* little endian */ + *dst++ = (c->status[0].prev_sample >> 8) & 0xFF; + *dst++ = (unsigned char)c->status[0].step_index; + *dst++ = 0; /* unknown */ + samples++; + if (avctx->channels == 2) { + c->status[1].prev_sample = (signed short)samples[1]; +/* c->status[1].step_index = 0; */ + *dst++ = (c->status[1].prev_sample) & 0xFF; + *dst++ = (c->status[1].prev_sample >> 8) & 0xFF; + *dst++ = (unsigned char)c->status[1].step_index; + *dst++ = 0; + samples++; + } + + /* stereo: 4 bytes (8 samples) for left, 4 bytes for right, 4 bytes left, ... */ + for (; n>0; n--) { + *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]) & 0x0F; + *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels]) << 4) & 0xF0; + dst++; + *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]) & 0x0F; + *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4) & 0xF0; + dst++; + *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]) & 0x0F; + *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4) & 0xF0; + dst++; + *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]) & 0x0F; + *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4) & 0xF0; + dst++; + /* right channel */ + if (avctx->channels == 2) { + *dst = adpcm_ima_compress_sample(&c->status[1], samples[1]); + *dst |= adpcm_ima_compress_sample(&c->status[1], samples[3]) << 4; + dst++; + *dst = adpcm_ima_compress_sample(&c->status[1], samples[5]); + *dst |= adpcm_ima_compress_sample(&c->status[1], samples[7]) << 4; + dst++; + *dst = adpcm_ima_compress_sample(&c->status[1], samples[9]); + *dst |= adpcm_ima_compress_sample(&c->status[1], samples[11]) << 4; + dst++; + *dst = adpcm_ima_compress_sample(&c->status[1], samples[13]); + *dst |= adpcm_ima_compress_sample(&c->status[1], samples[15]) << 4; + dst++; + } + samples += 8 * avctx->channels; + } + break; + case CODEC_ID_ADPCM_MS: + for(i=0; ichannels; i++){ + int predictor=0; + + *dst++ = predictor; + c->status[i].coeff1 = AdaptCoeff1[predictor]; + c->status[i].coeff2 = AdaptCoeff2[predictor]; + } + for(i=0; ichannels; i++){ + if (c->status[i].idelta < 16) + c->status[i].idelta = 16; + + *dst++ = c->status[i].idelta & 0xFF; + *dst++ = c->status[i].idelta >> 8; + } + for(i=0; ichannels; i++){ + c->status[i].sample1= *samples++; + + *dst++ = c->status[i].sample1 & 0xFF; + *dst++ = c->status[i].sample1 >> 8; + } + for(i=0; ichannels; i++){ + c->status[i].sample2= *samples++; + + *dst++ = c->status[i].sample2 & 0xFF; + *dst++ = c->status[i].sample2 >> 8; + } + + for(i=7*avctx->channels; iblock_align; i++) { + int nibble; + nibble = adpcm_ms_compress_sample(&c->status[ 0], *samples++)<<4; + nibble|= adpcm_ms_compress_sample(&c->status[st], *samples++); + *dst++ = nibble; + } + break; + case CODEC_ID_ADPCM_YAMAHA: + n = avctx->frame_size / 2; + for (; n>0; n--) { + for(i = 0; i < avctx->channels; i++) { + int nibble; + nibble = adpcm_yamaha_compress_sample(&c->status[i], samples[i]); + nibble |= adpcm_yamaha_compress_sample(&c->status[i], samples[i+avctx->channels]) << 4; + *dst++ = nibble; + } + samples += 2 * avctx->channels; + } + break; + default: + return -1; + } + return dst - frame; +} +#endif //CONFIG_ENCODERS + +static int adpcm_decode_init(AVCodecContext * avctx) +{ + ADPCMContext *c = avctx->priv_data; + + c->channel = 0; + c->status[0].predictor = c->status[1].predictor = 0; + c->status[0].step_index = c->status[1].step_index = 0; + c->status[0].step = c->status[1].step = 0; + + switch(avctx->codec->id) { + case CODEC_ID_ADPCM_CT: + c->status[0].step = c->status[1].step = 511; + break; + default: + break; + } + return 0; +} + +static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble, int shift) +{ + int step_index; + int predictor; + int sign, delta, diff, step; + + step = step_table[c->step_index]; + step_index = c->step_index + index_table[(unsigned)nibble]; + if (step_index < 0) step_index = 0; + else if (step_index > 88) step_index = 88; + + sign = nibble & 8; + delta = nibble & 7; + /* perform direct multiplication instead of series of jumps proposed by + * the reference ADPCM implementation since modern CPUs can do the mults + * quickly enough */ + diff = ((2 * delta + 1) * step) >> shift; + predictor = c->predictor; + if (sign) predictor -= diff; + else predictor += diff; + + CLAMP_TO_SHORT(predictor); + c->predictor = predictor; + c->step_index = step_index; + + return (short)predictor; +} + +static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble) +{ + int predictor; + + predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256; + predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta; + CLAMP_TO_SHORT(predictor); + + c->sample2 = c->sample1; + c->sample1 = predictor; + c->idelta = (AdaptationTable[(int)nibble] * c->idelta) >> 8; + if (c->idelta < 16) c->idelta = 16; + + return (short)predictor; +} + +static inline short adpcm_ct_expand_nibble(ADPCMChannelStatus *c, char nibble) +{ + int predictor; + int sign, delta, diff; + int new_step; + + sign = nibble & 8; + delta = nibble & 7; + /* perform direct multiplication instead of series of jumps proposed by + * the reference ADPCM implementation since modern CPUs can do the mults + * quickly enough */ + diff = ((2 * delta + 1) * c->step) >> 3; + predictor = c->predictor; + /* predictor update is not so trivial: predictor is multiplied on 254/256 before updating */ + if(sign) + predictor = ((predictor * 254) >> 8) - diff; + else + predictor = ((predictor * 254) >> 8) + diff; + /* calculate new step and clamp it to range 511..32767 */ + new_step = (ct_adpcm_table[nibble & 7] * c->step) >> 8; + c->step = new_step; + if(c->step < 511) + c->step = 511; + if(c->step > 32767) + c->step = 32767; + + CLAMP_TO_SHORT(predictor); + c->predictor = predictor; + return (short)predictor; +} + +static inline short adpcm_sbpro_expand_nibble(ADPCMChannelStatus *c, char nibble, int size, int shift) +{ + int sign, delta, diff; + + sign = nibble & (1<<(size-1)); + delta = nibble & ((1<<(size-1))-1); + diff = delta << (7 + c->step + shift); + + if (sign) + c->predictor -= diff; + else + c->predictor += diff; + + /* clamp result */ + if (c->predictor > 16256) + c->predictor = 16256; + else if (c->predictor < -16384) + c->predictor = -16384; + + /* calculate new step */ + if (delta >= (2*size - 3) && c->step < 3) + c->step++; + else if (delta == 0 && c->step > 0) + c->step--; + + return (short) c->predictor; +} + +static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned char nibble) +{ + if(!c->step) { + c->predictor = 0; + c->step = 127; + } + + c->predictor += (c->step * yamaha_difflookup[nibble]) / 8; + CLAMP_TO_SHORT(c->predictor); + c->step = (c->step * yamaha_indexscale[nibble]) >> 8; + c->step = clip(c->step, 127, 24567); + return c->predictor; +} + +static void xa_decode(short *out, const unsigned char *in, + ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc) +{ + int i, j; + int shift,filter,f0,f1; + int s_1,s_2; + int d,s,t; + + for(i=0;i<4;i++) { + + shift = 12 - (in[4+i*2] & 15); + filter = in[4+i*2] >> 4; + f0 = xa_adpcm_table[filter][0]; + f1 = xa_adpcm_table[filter][1]; + + s_1 = left->sample1; + s_2 = left->sample2; + + for(j=0;j<28;j++) { + d = in[16+i+j*4]; + + t = (signed char)(d<<4)>>4; + s = ( t<>6); + CLAMP_TO_SHORT(s); + *out = s; + out += inc; + s_2 = s_1; + s_1 = s; + } + + if (inc==2) { /* stereo */ + left->sample1 = s_1; + left->sample2 = s_2; + s_1 = right->sample1; + s_2 = right->sample2; + out = out + 1 - 28*2; + } + + shift = 12 - (in[5+i*2] & 15); + filter = in[5+i*2] >> 4; + + f0 = xa_adpcm_table[filter][0]; + f1 = xa_adpcm_table[filter][1]; + + for(j=0;j<28;j++) { + d = in[16+i+j*4]; + + t = (signed char)d >> 4; + s = ( t<>6); + CLAMP_TO_SHORT(s); + *out = s; + out += inc; + s_2 = s_1; + s_1 = s; + } + + if (inc==2) { /* stereo */ + right->sample1 = s_1; + right->sample2 = s_2; + out -= 1; + } else { + left->sample1 = s_1; + left->sample2 = s_2; + } + } +} + + +/* DK3 ADPCM support macro */ +#define DK3_GET_NEXT_NIBBLE() \ + if (decode_top_nibble_next) \ + { \ + nibble = (last_byte >> 4) & 0x0F; \ + decode_top_nibble_next = 0; \ + } \ + else \ + { \ + last_byte = *src++; \ + if (src >= buf + buf_size) break; \ + nibble = last_byte & 0x0F; \ + decode_top_nibble_next = 1; \ + } + +static int adpcm_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + ADPCMContext *c = avctx->priv_data; + ADPCMChannelStatus *cs; + int n, m, channel, i; + int block_predictor[2]; + short *samples; + uint8_t *src; + int st; /* stereo */ + + /* DK3 ADPCM accounting variables */ + unsigned char last_byte = 0; + unsigned char nibble; + int decode_top_nibble_next = 0; + int diff_channel; + + /* EA ADPCM state variables */ + uint32_t samples_in_chunk; + int32_t previous_left_sample, previous_right_sample; + int32_t current_left_sample, current_right_sample; + int32_t next_left_sample, next_right_sample; + int32_t coeff1l, coeff2l, coeff1r, coeff2r; + uint8_t shift_left, shift_right; + int count1, count2; + + if (!buf_size) + return 0; + + samples = data; + src = buf; + + st = avctx->channels == 2 ? 1 : 0; + + switch(avctx->codec->id) { + case CODEC_ID_ADPCM_IMA_QT: + n = (buf_size - 2);/* >> 2*avctx->channels;*/ + channel = c->channel; + cs = &(c->status[channel]); + /* (pppppp) (piiiiiii) */ + + /* Bits 15-7 are the _top_ 9 bits of the 16-bit initial predictor value */ + cs->predictor = (*src++) << 8; + cs->predictor |= (*src & 0x80); + cs->predictor &= 0xFF80; + + /* sign extension */ + if(cs->predictor & 0x8000) + cs->predictor -= 0x10000; + + CLAMP_TO_SHORT(cs->predictor); + + cs->step_index = (*src++) & 0x7F; + + if (cs->step_index > 88){ + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", cs->step_index); + cs->step_index = 88; + } + + cs->step = step_table[cs->step_index]; + + if (st && channel) + samples++; + + for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */ + *samples = adpcm_ima_expand_nibble(cs, src[0] & 0x0F, 3); + samples += avctx->channels; + *samples = adpcm_ima_expand_nibble(cs, (src[0] >> 4) & 0x0F, 3); + samples += avctx->channels; + src ++; + } + + if(st) { /* handle stereo interlacing */ + c->channel = (channel + 1) % 2; /* we get one packet for left, then one for right data */ + if(channel == 1) { /* wait for the other packet before outputing anything */ + return src - buf; + } + } + break; + case CODEC_ID_ADPCM_IMA_WAV: + if (avctx->block_align != 0 && buf_size > avctx->block_align) + buf_size = avctx->block_align; + +// samples_per_block= (block_align-4*chanels)*8 / (bits_per_sample * chanels) + 1; + + for(i=0; ichannels; i++){ + cs = &(c->status[i]); + cs->predictor = (int16_t)(src[0] + (src[1]<<8)); + src+=2; + + // XXX: is this correct ??: *samples++ = cs->predictor; + + cs->step_index = *src++; + if (cs->step_index > 88){ + av_log(avctx, AV_LOG_ERROR, "ERROR: step_index = %i\n", cs->step_index); + cs->step_index = 88; + } + if (*src++) av_log(avctx, AV_LOG_ERROR, "unused byte should be null but is %d!!\n", src[-1]); /* unused */ + } + + while(src < buf + buf_size){ + for(m=0; m<4; m++){ + for(i=0; i<=st; i++) + *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] & 0x0F, 3); + for(i=0; i<=st; i++) + *samples++ = adpcm_ima_expand_nibble(&c->status[i], src[4*i] >> 4 , 3); + src++; + } + src += 4*st; + } + break; + case CODEC_ID_ADPCM_4XM: + cs = &(c->status[0]); + c->status[0].predictor= (int16_t)(src[0] + (src[1]<<8)); src+=2; + if(st){ + c->status[1].predictor= (int16_t)(src[0] + (src[1]<<8)); src+=2; + } + c->status[0].step_index= (int16_t)(src[0] + (src[1]<<8)); src+=2; + if(st){ + c->status[1].step_index= (int16_t)(src[0] + (src[1]<<8)); src+=2; + } + if (cs->step_index < 0) cs->step_index = 0; + if (cs->step_index > 88) cs->step_index = 88; + + m= (buf_size - (src - buf))>>st; + for(i=0; istatus[0], src[i] & 0x0F, 4); + if (st) + *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] & 0x0F, 4); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[i] >> 4, 4); + if (st) + *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[i+m] >> 4, 4); + } + + src += m<block_align != 0 && buf_size > avctx->block_align) + buf_size = avctx->block_align; + n = buf_size - 7 * avctx->channels; + if (n < 0) + return -1; + block_predictor[0] = clip(*src++, 0, 7); + block_predictor[1] = 0; + if (st) + block_predictor[1] = clip(*src++, 0, 7); + c->status[0].idelta = (int16_t)((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); + src+=2; + if (st){ + c->status[1].idelta = (int16_t)((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); + src+=2; + } + c->status[0].coeff1 = AdaptCoeff1[block_predictor[0]]; + c->status[0].coeff2 = AdaptCoeff2[block_predictor[0]]; + c->status[1].coeff1 = AdaptCoeff1[block_predictor[1]]; + c->status[1].coeff2 = AdaptCoeff2[block_predictor[1]]; + + c->status[0].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); + src+=2; + if (st) c->status[1].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); + if (st) src+=2; + c->status[0].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); + src+=2; + if (st) c->status[1].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00)); + if (st) src+=2; + + *samples++ = c->status[0].sample1; + if (st) *samples++ = c->status[1].sample1; + *samples++ = c->status[0].sample2; + if (st) *samples++ = c->status[1].sample2; + for(;n>0;n--) { + *samples++ = adpcm_ms_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F); + *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F); + src ++; + } + break; + case CODEC_ID_ADPCM_IMA_DK4: + if (avctx->block_align != 0 && buf_size > avctx->block_align) + buf_size = avctx->block_align; + + c->status[0].predictor = (int16_t)(src[0] | (src[1] << 8)); + c->status[0].step_index = src[2]; + src += 4; + *samples++ = c->status[0].predictor; + if (st) { + c->status[1].predictor = (int16_t)(src[0] | (src[1] << 8)); + c->status[1].step_index = src[2]; + src += 4; + *samples++ = c->status[1].predictor; + } + while (src < buf + buf_size) { + + /* take care of the top nibble (always left or mono channel) */ + *samples++ = adpcm_ima_expand_nibble(&c->status[0], + (src[0] >> 4) & 0x0F, 3); + + /* take care of the bottom nibble, which is right sample for + * stereo, or another mono sample */ + if (st) + *samples++ = adpcm_ima_expand_nibble(&c->status[1], + src[0] & 0x0F, 3); + else + *samples++ = adpcm_ima_expand_nibble(&c->status[0], + src[0] & 0x0F, 3); + + src++; + } + break; + case CODEC_ID_ADPCM_IMA_DK3: + if (avctx->block_align != 0 && buf_size > avctx->block_align) + buf_size = avctx->block_align; + + c->status[0].predictor = (int16_t)(src[10] | (src[11] << 8)); + c->status[1].predictor = (int16_t)(src[12] | (src[13] << 8)); + c->status[0].step_index = src[14]; + c->status[1].step_index = src[15]; + /* sign extend the predictors */ + src += 16; + diff_channel = c->status[1].predictor; + + /* the DK3_GET_NEXT_NIBBLE macro issues the break statement when + * the buffer is consumed */ + while (1) { + + /* for this algorithm, c->status[0] is the sum channel and + * c->status[1] is the diff channel */ + + /* process the first predictor of the sum channel */ + DK3_GET_NEXT_NIBBLE(); + adpcm_ima_expand_nibble(&c->status[0], nibble, 3); + + /* process the diff channel predictor */ + DK3_GET_NEXT_NIBBLE(); + adpcm_ima_expand_nibble(&c->status[1], nibble, 3); + + /* process the first pair of stereo PCM samples */ + diff_channel = (diff_channel + c->status[1].predictor) / 2; + *samples++ = c->status[0].predictor + c->status[1].predictor; + *samples++ = c->status[0].predictor - c->status[1].predictor; + + /* process the second predictor of the sum channel */ + DK3_GET_NEXT_NIBBLE(); + adpcm_ima_expand_nibble(&c->status[0], nibble, 3); + + /* process the second pair of stereo PCM samples */ + diff_channel = (diff_channel + c->status[1].predictor) / 2; + *samples++ = c->status[0].predictor + c->status[1].predictor; + *samples++ = c->status[0].predictor - c->status[1].predictor; + } + break; + case CODEC_ID_ADPCM_IMA_WS: + /* no per-block initialization; just start decoding the data */ + while (src < buf + buf_size) { + + if (st) { + *samples++ = adpcm_ima_expand_nibble(&c->status[0], + (src[0] >> 4) & 0x0F, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[1], + src[0] & 0x0F, 3); + } else { + *samples++ = adpcm_ima_expand_nibble(&c->status[0], + (src[0] >> 4) & 0x0F, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], + src[0] & 0x0F, 3); + } + + src++; + } + break; + case CODEC_ID_ADPCM_XA: + c->status[0].sample1 = c->status[0].sample2 = + c->status[1].sample1 = c->status[1].sample2 = 0; + while (buf_size >= 128) { + xa_decode(samples, src, &c->status[0], &c->status[1], + avctx->channels); + src += 128; + samples += 28 * 8; + buf_size -= 128; + } + break; + case CODEC_ID_ADPCM_EA: + samples_in_chunk = LE_32(src); + if (samples_in_chunk >= ((buf_size - 12) * 2)) { + src += buf_size; + break; + } + src += 4; + current_left_sample = (int16_t)LE_16(src); + src += 2; + previous_left_sample = (int16_t)LE_16(src); + src += 2; + current_right_sample = (int16_t)LE_16(src); + src += 2; + previous_right_sample = (int16_t)LE_16(src); + src += 2; + + for (count1 = 0; count1 < samples_in_chunk/28;count1++) { + coeff1l = ea_adpcm_table[(*src >> 4) & 0x0F]; + coeff2l = ea_adpcm_table[((*src >> 4) & 0x0F) + 4]; + coeff1r = ea_adpcm_table[*src & 0x0F]; + coeff2r = ea_adpcm_table[(*src & 0x0F) + 4]; + src++; + + shift_left = ((*src >> 4) & 0x0F) + 8; + shift_right = (*src & 0x0F) + 8; + src++; + + for (count2 = 0; count2 < 28; count2++) { + next_left_sample = (((*src & 0xF0) << 24) >> shift_left); + next_right_sample = (((*src & 0x0F) << 28) >> shift_right); + src++; + + next_left_sample = (next_left_sample + + (current_left_sample * coeff1l) + + (previous_left_sample * coeff2l) + 0x80) >> 8; + next_right_sample = (next_right_sample + + (current_right_sample * coeff1r) + + (previous_right_sample * coeff2r) + 0x80) >> 8; + CLAMP_TO_SHORT(next_left_sample); + CLAMP_TO_SHORT(next_right_sample); + + previous_left_sample = current_left_sample; + current_left_sample = next_left_sample; + previous_right_sample = current_right_sample; + current_right_sample = next_right_sample; + *samples++ = (unsigned short)current_left_sample; + *samples++ = (unsigned short)current_right_sample; + } + } + break; + case CODEC_ID_ADPCM_IMA_SMJPEG: + c->status[0].predictor = *src; + src += 2; + c->status[0].step_index = *src++; + src++; /* skip another byte before getting to the meat */ + while (src < buf + buf_size) { + *samples++ = adpcm_ima_expand_nibble(&c->status[0], + *src & 0x0F, 3); + *samples++ = adpcm_ima_expand_nibble(&c->status[0], + (*src >> 4) & 0x0F, 3); + src++; + } + break; + case CODEC_ID_ADPCM_CT: + while (src < buf + buf_size) { + if (st) { + *samples++ = adpcm_ct_expand_nibble(&c->status[0], + (src[0] >> 4) & 0x0F); + *samples++ = adpcm_ct_expand_nibble(&c->status[1], + src[0] & 0x0F); + } else { + *samples++ = adpcm_ct_expand_nibble(&c->status[0], + (src[0] >> 4) & 0x0F); + *samples++ = adpcm_ct_expand_nibble(&c->status[0], + src[0] & 0x0F); + } + src++; + } + break; + case CODEC_ID_ADPCM_SBPRO_4: + case CODEC_ID_ADPCM_SBPRO_3: + case CODEC_ID_ADPCM_SBPRO_2: + if (!c->status[0].step_index) { + /* the first byte is a raw sample */ + *samples++ = 128 * (*src++ - 0x80); + if (st) + *samples++ = 128 * (*src++ - 0x80); + c->status[0].step_index = 1; + } + if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_4) { + while (src < buf + buf_size) { + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + (src[0] >> 4) & 0x0F, 4, 0); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[st], + src[0] & 0x0F, 4, 0); + src++; + } + } else if (avctx->codec->id == CODEC_ID_ADPCM_SBPRO_3) { + while (src < buf + buf_size) { + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + (src[0] >> 5) & 0x07, 3, 0); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + (src[0] >> 2) & 0x07, 3, 0); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + src[0] & 0x03, 2, 0); + src++; + } + } else { + while (src < buf + buf_size) { + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + (src[0] >> 6) & 0x03, 2, 2); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[st], + (src[0] >> 4) & 0x03, 2, 2); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], + (src[0] >> 2) & 0x03, 2, 2); + *samples++ = adpcm_sbpro_expand_nibble(&c->status[st], + src[0] & 0x03, 2, 2); + src++; + } + } + break; + case CODEC_ID_ADPCM_SWF: + { + GetBitContext gb; + const int *table; + int k0, signmask; + int size = buf_size*8; + + init_get_bits(&gb, buf, size); + + // first frame, read bits & inital values + if (!c->nb_bits) + { + c->nb_bits = get_bits(&gb, 2)+2; +// av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", c->nb_bits); + } + + table = swf_index_tables[c->nb_bits-2]; + k0 = 1 << (c->nb_bits-2); + signmask = 1 << (c->nb_bits-1); + + while (get_bits_count(&gb) <= size) + { + int i; + + c->nb_samples++; + // wrap around at every 4096 samples... + if ((c->nb_samples & 0xfff) == 1) + { + for (i = 0; i <= st; i++) + { + *samples++ = c->status[i].predictor = get_sbits(&gb, 16); + c->status[i].step_index = get_bits(&gb, 6); + } + } + + // similar to IMA adpcm + for (i = 0; i <= st; i++) + { + int delta = get_bits(&gb, c->nb_bits); + int step = step_table[c->status[i].step_index]; + long vpdiff = 0; // vpdiff = (delta+0.5)*step/4 + int k = k0; + + do { + if (delta & k) + vpdiff += step; + step >>= 1; + k >>= 1; + } while(k); + vpdiff += step; + + if (delta & signmask) + c->status[i].predictor -= vpdiff; + else + c->status[i].predictor += vpdiff; + + c->status[i].step_index += table[delta & (~signmask)]; + + c->status[i].step_index = clip(c->status[i].step_index, 0, 88); + c->status[i].predictor = clip(c->status[i].predictor, -32768, 32767); + + *samples++ = c->status[i].predictor; + } + } + +// src += get_bits_count(&gb)*8; + src += size; + + break; + } + case CODEC_ID_ADPCM_YAMAHA: + while (src < buf + buf_size) { + if (st) { + *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], + src[0] & 0x0F); + *samples++ = adpcm_yamaha_expand_nibble(&c->status[1], + (src[0] >> 4) & 0x0F); + } else { + *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], + src[0] & 0x0F); + *samples++ = adpcm_yamaha_expand_nibble(&c->status[0], + (src[0] >> 4) & 0x0F); + } + src++; + } + break; + default: + return -1; + } + *data_size = (uint8_t *)samples - (uint8_t *)data; + return src - buf; +} + + + +#ifdef CONFIG_ENCODERS +#define ADPCM_ENCODER(id,name) \ +AVCodec name ## _encoder = { \ + #name, \ + CODEC_TYPE_AUDIO, \ + id, \ + sizeof(ADPCMContext), \ + adpcm_encode_init, \ + adpcm_encode_frame, \ + adpcm_encode_close, \ + NULL, \ +}; +#else +#define ADPCM_ENCODER(id,name) +#endif + +#ifdef CONFIG_DECODERS +#define ADPCM_DECODER(id,name) \ +AVCodec name ## _decoder = { \ + #name, \ + CODEC_TYPE_AUDIO, \ + id, \ + sizeof(ADPCMContext), \ + adpcm_decode_init, \ + NULL, \ + NULL, \ + adpcm_decode_frame, \ +}; +#else +#define ADPCM_DECODER(id,name) +#endif + +#define ADPCM_CODEC(id, name) \ +ADPCM_ENCODER(id,name) ADPCM_DECODER(id,name) + +ADPCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); +ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); +ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); +ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); +ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws); +ADPCM_CODEC(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); +ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); +ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); +ADPCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); +ADPCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx); +ADPCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); +ADPCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct); +ADPCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf); +ADPCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); +ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4); +ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3); +ADPCM_CODEC(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2); + +#undef ADPCM_CODEC diff --git a/mpeg4/src/libavcodec/adx.c b/mpeg4/src/libavcodec/adx.c new file mode 100644 index 00000000..c841e4eb --- /dev/null +++ b/mpeg4/src/libavcodec/adx.c @@ -0,0 +1,410 @@ +/* + * ADX ADPCM codecs + * Copyright (c) 2001,2003 BERO + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avcodec.h" + +/** + * @file adx.c + * SEGA CRI adx codecs. + * + * Reference documents: + * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html + * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ + */ + +typedef struct { + int s1,s2; +} PREV; + +typedef struct { + PREV prev[2]; + int header_parsed; + unsigned char dec_temp[18*2]; + unsigned short enc_temp[32*2]; + int in_temp; +} ADXContext; + +//#define BASEVOL 0x11e0 +#define BASEVOL 0x4000 +#define SCALE1 0x7298 +#define SCALE2 0x3350 + +#define CLIP(s) if (s>32767) s=32767; else if (s<-32768) s=-32768 + +/* 18 bytes <-> 32 samples */ + +#ifdef CONFIG_ENCODERS +static void adx_encode(unsigned char *adx,const short *wav,PREV *prev) +{ + int scale; + int i; + int s0,s1,s2,d; + int max=0; + int min=0; + int data[32]; + + s1 = prev->s1; + s2 = prev->s2; + for(i=0;i<32;i++) { + s0 = wav[i]; + d = ((s0<<14) - SCALE1*s1 + SCALE2*s2)/BASEVOL; + data[i]=d; + if (maxd) min=d; + s2 = s1; + s1 = s0; + } + prev->s1 = s1; + prev->s2 = s2; + + /* -8..+7 */ + + if (max==0 && min==0) { + memset(adx,0,18); + return; + } + + if (max/7>-min/8) scale = max/7; + else scale = -min/8; + + if (scale==0) scale=1; + + adx[0] = scale>>8; + adx[1] = scale; + + for(i=0;i<16;i++) { + adx[i+2] = ((data[i*2]/scale)<<4) | ((data[i*2+1]/scale)&0xf); + } +} +#endif //CONFIG_ENCODERS + +static void adx_decode(short *out,const unsigned char *in,PREV *prev) +{ + int scale = ((in[0]<<8)|(in[1])); + int i; + int s0,s1,s2,d; + +// printf("%x ",scale); + + in+=2; + s1 = prev->s1; + s2 = prev->s2; + for(i=0;i<16;i++) { + d = in[i]; + // d>>=4; if (d&8) d-=16; + d = ((signed char)d >> 4); + s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; + CLIP(s0); + *out++=s0; + s2 = s1; + s1 = s0; + + d = in[i]; + //d&=15; if (d&8) d-=16; + d = ((signed char)(d<<4) >> 4); + s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; + CLIP(s0); + *out++=s0; + s2 = s1; + s1 = s0; + } + prev->s1 = s1; + prev->s2 = s2; + +} + +static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev) +{ + short tmp[32*2]; + int i; + + adx_decode(tmp ,in ,prev); + adx_decode(tmp+32,in+18,prev+1); + for(i=0;i<32;i++) { + out[i*2] = tmp[i]; + out[i*2+1] = tmp[i+32]; + } +} + +#ifdef CONFIG_ENCODERS + +static void write_long(unsigned char *p,uint32_t v) +{ + p[0] = v>>24; + p[1] = v>>16; + p[2] = v>>8; + p[3] = v; +} + +static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize) +{ +#if 0 + struct { + uint32_t offset; /* 0x80000000 + sample start - 4 */ + unsigned char unknown1[3]; /* 03 12 04 */ + unsigned char channel; /* 1 or 2 */ + uint32_t freq; + uint32_t size; + uint32_t unknown2; /* 01 f4 03 00 */ + uint32_t unknown3; /* 00 00 00 00 */ + uint32_t unknown4; /* 00 00 00 00 */ + + /* if loop + unknown3 00 15 00 01 + unknown4 00 00 00 01 + long loop_start_sample; + long loop_start_byte; + long loop_end_sample; + long loop_end_byte; + long + */ + } adxhdr; /* big endian */ + /* offset-6 "(c)CRI" */ +#endif + write_long(buf+0x00,0x80000000|0x20); + write_long(buf+0x04,0x03120400|avctx->channels); + write_long(buf+0x08,avctx->sample_rate); + write_long(buf+0x0c,0); /* FIXME: set after */ + write_long(buf+0x10,0x01040300); + write_long(buf+0x14,0x00000000); + write_long(buf+0x18,0x00000000); + memcpy(buf+0x1c,"\0\0(c)CRI",8); + return 0x20+4; +} + +static int adx_decode_init(AVCodecContext *avctx); +static int adx_encode_init(AVCodecContext *avctx) +{ + if (avctx->channels > 2) + return -1; /* only stereo or mono =) */ + avctx->frame_size = 32; + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + +// avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; + + av_log(avctx, AV_LOG_DEBUG, "adx encode init\n"); + adx_decode_init(avctx); + + return 0; +} + +static int adx_encode_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + + return 0; +} + +static int adx_encode_frame(AVCodecContext *avctx, + uint8_t *frame, int buf_size, void *data) +{ + ADXContext *c = avctx->priv_data; + const short *samples = data; + unsigned char *dst = frame; + int rest = avctx->frame_size; + +/* + input data size = + ffmpeg.c: do_audio_out() + frame_bytes = enc->frame_size * 2 * enc->channels; +*/ + +// printf("sz=%d ",buf_size); fflush(stdout); + if (!c->header_parsed) { + int hdrsize = adx_encode_header(avctx,dst,buf_size); + dst+=hdrsize; + c->header_parsed = 1; + } + + if (avctx->channels==1) { + while(rest>=32) { + adx_encode(dst,samples,c->prev); + dst+=18; + samples+=32; + rest-=32; + } + } else { + while(rest>=32*2) { + short tmpbuf[32*2]; + int i; + + for(i=0;i<32;i++) { + tmpbuf[i] = samples[i*2]; + tmpbuf[i+32] = samples[i*2+1]; + } + + adx_encode(dst,tmpbuf,c->prev); + adx_encode(dst+18,tmpbuf+32,c->prev+1); + dst+=18*2; + samples+=32*2; + rest-=32*2; + } + } + return dst-frame; +} + +#endif //CONFIG_ENCODERS + +static uint32_t read_long(const unsigned char *p) +{ + return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3]; +} + +int is_adx(const unsigned char *buf,size_t bufsize) +{ + int offset; + + if (buf[0]!=0x80) return 0; + offset = (read_long(buf)^0x80000000)+4; + if (bufsizesample_rate = freq; + avctx->channels = channels; + avctx->bit_rate = freq*channels*18*8/32; +// avctx->frame_size = 18*channels; + + return offset; +} + +static int adx_decode_init(AVCodecContext * avctx) +{ + ADXContext *c = avctx->priv_data; + +// printf("adx_decode_init\n"); fflush(stdout); + c->prev[0].s1 = 0; + c->prev[0].s2 = 0; + c->prev[1].s1 = 0; + c->prev[1].s2 = 0; + c->header_parsed = 0; + c->in_temp = 0; + return 0; +} + +#if 0 +static void dump(unsigned char *buf,size_t len) +{ + int i; + for(i=0;ipriv_data; + short *samples = data; + const uint8_t *buf = buf0; + int rest = buf_size; + + if (!c->header_parsed) { + int hdrsize = adx_decode_header(avctx,buf,rest); + if (hdrsize==0) return -1; + c->header_parsed = 1; + buf += hdrsize; + rest -= hdrsize; + } + + if (c->in_temp) { + int copysize = 18*avctx->channels - c->in_temp; + memcpy(c->dec_temp+c->in_temp,buf,copysize); + rest -= copysize; + buf += copysize; + if (avctx->channels==1) { + adx_decode(samples,c->dec_temp,c->prev); + samples += 32; + } else { + adx_decode_stereo(samples,c->dec_temp,c->prev); + samples += 32*2; + } + } + // + if (avctx->channels==1) { + while(rest>=18) { + adx_decode(samples,buf,c->prev); + rest-=18; + buf+=18; + samples+=32; + } + } else { + while(rest>=18*2) { + adx_decode_stereo(samples,buf,c->prev); + rest-=18*2; + buf+=18*2; + samples+=32*2; + } + } + // + c->in_temp = rest; + if (rest) { + memcpy(c->dec_temp,buf,rest); + buf+=rest; + } + *data_size = (uint8_t*)samples - (uint8_t*)data; +// printf("%d:%d ",buf-buf0,*data_size); fflush(stdout); + return buf-buf0; +} + +#ifdef CONFIG_ENCODERS +AVCodec adx_adpcm_encoder = { + "adx_adpcm", + CODEC_TYPE_AUDIO, + CODEC_ID_ADPCM_ADX, + sizeof(ADXContext), + adx_encode_init, + adx_encode_frame, + adx_encode_close, + NULL, +}; +#endif //CONFIG_ENCODERS + +AVCodec adx_adpcm_decoder = { + "adx_adpcm", + CODEC_TYPE_AUDIO, + CODEC_ID_ADPCM_ADX, + sizeof(ADXContext), + adx_decode_init, + NULL, + NULL, + adx_decode_frame, +}; + diff --git a/mpeg4/src/libavcodec/alac.c b/mpeg4/src/libavcodec/alac.c new file mode 100644 index 00000000..ab2ffb9e --- /dev/null +++ b/mpeg4/src/libavcodec/alac.c @@ -0,0 +1,849 @@ +/* + * ALAC (Apple Lossless Audio Codec) decoder + * Copyright (c) 2005 David Hammerton + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file alac.c + * ALAC (Apple Lossless Audio Codec) decoder + * @author 2005 David Hammerton + * + * For more information on the ALAC format, visit: + * http://crazney.net/programs/itunes/alac.html + * + * Note: This decoder expects a 36- (0x24-)byte QuickTime atom to be + * passed through the extradata[_size] fields. This atom is tacked onto + * the end of an 'alac' stsd atom and has the following format: + * bytes 0-3 atom size (0x24), big-endian + * bytes 4-7 atom type ('alac', not the 'alac' tag from start of stsd) + * bytes 8-35 data bytes needed by decoder + * + * Extradata: + * 32bit size + * 32bit tag (=alac) + * 32bit zero? + * 32bit max sample per frame + * 8bit ?? (zero?) + * 8bit sample size + * 8bit history mult + * 8bit initial history + * 8bit kmodifier + * 8bit channels? + * 16bit ?? + * 32bit max coded frame size + * 32bit bitrate? + * 32bit samplerate + */ + + +#include "avcodec.h" +#include "bitstream.h" + +#define ALAC_EXTRADATA_SIZE 36 + +typedef struct { + + AVCodecContext *avctx; + GetBitContext gb; + /* init to 0; first frame decode should initialize from extradata and + * set this to 1 */ + int context_initialized; + + int samplesize; + int numchannels; + int bytespersample; + + /* buffers */ + int32_t *predicterror_buffer_a; + int32_t *predicterror_buffer_b; + + int32_t *outputsamples_buffer_a; + int32_t *outputsamples_buffer_b; + + /* stuff from setinfo */ + uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */ + uint8_t setinfo_7a; /* 0x00 */ + uint8_t setinfo_sample_size; /* 0x10 */ + uint8_t setinfo_rice_historymult; /* 0x28 */ + uint8_t setinfo_rice_initialhistory; /* 0x0a */ + uint8_t setinfo_rice_kmodifier; /* 0x0e */ + uint8_t setinfo_7f; /* 0x02 */ + uint16_t setinfo_80; /* 0x00ff */ + uint32_t setinfo_82; /* 0x000020e7 */ + uint32_t setinfo_86; /* 0x00069fe4 */ + uint32_t setinfo_8a_rate; /* 0x0000ac44 */ + /* end setinfo stuff */ + +} ALACContext; + +static void allocate_buffers(ALACContext *alac) +{ + alac->predicterror_buffer_a = av_malloc(alac->setinfo_max_samples_per_frame * 4); + alac->predicterror_buffer_b = av_malloc(alac->setinfo_max_samples_per_frame * 4); + + alac->outputsamples_buffer_a = av_malloc(alac->setinfo_max_samples_per_frame * 4); + alac->outputsamples_buffer_b = av_malloc(alac->setinfo_max_samples_per_frame * 4); +} + +static void alac_set_info(ALACContext *alac) +{ + unsigned char *ptr = alac->avctx->extradata; + + ptr += 4; /* size */ + ptr += 4; /* alac */ + ptr += 4; /* 0 ? */ + + alac->setinfo_max_samples_per_frame = BE_32(ptr); /* buffer size / 2 ? */ + ptr += 4; + alac->setinfo_7a = *ptr++; + alac->setinfo_sample_size = *ptr++; + alac->setinfo_rice_historymult = *ptr++; + alac->setinfo_rice_initialhistory = *ptr++; + alac->setinfo_rice_kmodifier = *ptr++; + alac->setinfo_7f = *ptr++; // channels? + alac->setinfo_80 = BE_16(ptr); + ptr += 2; + alac->setinfo_82 = BE_32(ptr); // max coded frame size + ptr += 4; + alac->setinfo_86 = BE_32(ptr); // bitrate ? + ptr += 4; + alac->setinfo_8a_rate = BE_32(ptr); // samplerate + ptr += 4; + + allocate_buffers(alac); +} + +/* hideously inefficient. could use a bitmask search, + * alternatively bsr on x86, + */ +static int count_leading_zeros(int32_t input) +{ + int i = 0; + while (!(0x80000000 & input) && i < 32) { + i++; + input = input << 1; + } + return i; +} + +static void bastardized_rice_decompress(ALACContext *alac, + int32_t *output_buffer, + int output_size, + int readsamplesize, /* arg_10 */ + int rice_initialhistory, /* arg424->b */ + int rice_kmodifier, /* arg424->d */ + int rice_historymult, /* arg424->c */ + int rice_kmodifier_mask /* arg424->e */ + ) +{ + int output_count; + unsigned int history = rice_initialhistory; + int sign_modifier = 0; + + for (output_count = 0; output_count < output_size; output_count++) { + int32_t x = 0; + int32_t x_modified; + int32_t final_val; + + /* read x - number of 1s before 0 represent the rice */ + while (x <= 8 && get_bits1(&alac->gb)) { + x++; + } + + + if (x > 8) { /* RICE THRESHOLD */ + /* use alternative encoding */ + int32_t value; + + value = get_bits(&alac->gb, readsamplesize); + + /* mask value to readsamplesize size */ + if (readsamplesize != 32) + value &= (0xffffffff >> (32 - readsamplesize)); + + x = value; + } else { + /* standard rice encoding */ + int extrabits; + int k; /* size of extra bits */ + + /* read k, that is bits as is */ + k = 31 - rice_kmodifier - count_leading_zeros((history >> 9) + 3); + + if (k < 0) + k += rice_kmodifier; + else + k = rice_kmodifier; + + if (k != 1) { + extrabits = show_bits(&alac->gb, k); + + /* multiply x by 2^k - 1, as part of their strange algorithm */ + x = (x << k) - x; + + if (extrabits > 1) { + x += extrabits - 1; + get_bits(&alac->gb, k); + } else { + get_bits(&alac->gb, k - 1); + } + } + } + + x_modified = sign_modifier + x; + final_val = (x_modified + 1) / 2; + if (x_modified & 1) final_val *= -1; + + output_buffer[output_count] = final_val; + + sign_modifier = 0; + + /* now update the history */ + history += (x_modified * rice_historymult) + - ((history * rice_historymult) >> 9); + + if (x_modified > 0xffff) + history = 0xffff; + + /* special case: there may be compressed blocks of 0 */ + if ((history < 128) && (output_count+1 < output_size)) { + int block_size; + + sign_modifier = 1; + + x = 0; + while (x <= 8 && get_bits1(&alac->gb)) { + x++; + } + + if (x > 8) { + block_size = get_bits(&alac->gb, 16); + block_size &= 0xffff; + } else { + int k; + int extrabits; + + k = count_leading_zeros(history) + ((history + 16) >> 6 /* / 64 */) - 24; + + extrabits = show_bits(&alac->gb, k); + + block_size = (((1 << k) - 1) & rice_kmodifier_mask) * x + + extrabits - 1; + + if (extrabits < 2) { + x = 1 - extrabits; + block_size += x; + get_bits(&alac->gb, k - 1); + } else { + get_bits(&alac->gb, k); + } + } + + if (block_size > 0) { + memset(&output_buffer[output_count+1], 0, block_size * 4); + output_count += block_size; + + } + + if (block_size > 0xffff) + sign_modifier = 0; + + history = 0; + } + } +} + +#define SIGN_EXTENDED32(val, bits) ((val << (32 - bits)) >> (32 - bits)) + +#define SIGN_ONLY(v) \ + ((v < 0) ? (-1) : \ + ((v > 0) ? (1) : \ + (0))) + +static void predictor_decompress_fir_adapt(int32_t *error_buffer, + int32_t *buffer_out, + int output_size, + int readsamplesize, + int16_t *predictor_coef_table, + int predictor_coef_num, + int predictor_quantitization) +{ + int i; + + /* first sample always copies */ + *buffer_out = *error_buffer; + + if (!predictor_coef_num) { + if (output_size <= 1) return; + memcpy(buffer_out+1, error_buffer+1, (output_size-1) * 4); + return; + } + + if (predictor_coef_num == 0x1f) { /* 11111 - max value of predictor_coef_num */ + /* second-best case scenario for fir decompression, + * error describes a small difference from the previous sample only + */ + if (output_size <= 1) return; + for (i = 0; i < output_size - 1; i++) { + int32_t prev_value; + int32_t error_value; + + prev_value = buffer_out[i]; + error_value = error_buffer[i+1]; + buffer_out[i+1] = SIGN_EXTENDED32((prev_value + error_value), readsamplesize); + } + return; + } + + /* read warm-up samples */ + if (predictor_coef_num > 0) { + int i; + for (i = 0; i < predictor_coef_num; i++) { + int32_t val; + + val = buffer_out[i] + error_buffer[i+1]; + + val = SIGN_EXTENDED32(val, readsamplesize); + + buffer_out[i+1] = val; + } + } + +#if 0 + /* 4 and 8 are very common cases (the only ones i've seen). these + * should be unrolled and optimised + */ + if (predictor_coef_num == 4) { + /* FIXME: optimised general case */ + return; + } + + if (predictor_coef_table == 8) { + /* FIXME: optimised general case */ + return; + } +#endif + + + /* general case */ + if (predictor_coef_num > 0) { + for (i = predictor_coef_num + 1; + i < output_size; + i++) { + int j; + int sum = 0; + int outval; + int error_val = error_buffer[i]; + + for (j = 0; j < predictor_coef_num; j++) { + sum += (buffer_out[predictor_coef_num-j] - buffer_out[0]) * + predictor_coef_table[j]; + } + + outval = (1 << (predictor_quantitization-1)) + sum; + outval = outval >> predictor_quantitization; + outval = outval + buffer_out[0] + error_val; + outval = SIGN_EXTENDED32(outval, readsamplesize); + + buffer_out[predictor_coef_num+1] = outval; + + if (error_val > 0) { + int predictor_num = predictor_coef_num - 1; + + while (predictor_num >= 0 && error_val > 0) { + int val = buffer_out[0] - buffer_out[predictor_coef_num - predictor_num]; + int sign = SIGN_ONLY(val); + + predictor_coef_table[predictor_num] -= sign; + + val *= sign; /* absolute value */ + + error_val -= ((val >> predictor_quantitization) * + (predictor_coef_num - predictor_num)); + + predictor_num--; + } + } else if (error_val < 0) { + int predictor_num = predictor_coef_num - 1; + + while (predictor_num >= 0 && error_val < 0) { + int val = buffer_out[0] - buffer_out[predictor_coef_num - predictor_num]; + int sign = - SIGN_ONLY(val); + + predictor_coef_table[predictor_num] -= sign; + + val *= sign; /* neg value */ + + error_val -= ((val >> predictor_quantitization) * + (predictor_coef_num - predictor_num)); + + predictor_num--; + } + } + + buffer_out++; + } + } +} + +void deinterlace_16(int32_t *buffer_a, int32_t *buffer_b, + int16_t *buffer_out, + int numchannels, int numsamples, + uint8_t interlacing_shift, + uint8_t interlacing_leftweight) +{ + int i; + if (numsamples <= 0) return; + + /* weighted interlacing */ + if (interlacing_leftweight) { + for (i = 0; i < numsamples; i++) { + int32_t difference, midright; + int16_t left; + int16_t right; + + midright = buffer_a[i]; + difference = buffer_b[i]; + + + right = midright - ((difference * interlacing_leftweight) >> interlacing_shift); + left = (midright - ((difference * interlacing_leftweight) >> interlacing_shift)) + + difference; + + buffer_out[i*numchannels] = left; + buffer_out[i*numchannels + 1] = right; + } + + return; + } + + /* otherwise basic interlacing took place */ + for (i = 0; i < numsamples; i++) { + int16_t left, right; + + left = buffer_a[i]; + right = buffer_b[i]; + + buffer_out[i*numchannels] = left; + buffer_out[i*numchannels + 1] = right; + } +} + +static int alac_decode_frame(AVCodecContext *avctx, + void *outbuffer, int *outputsize, + uint8_t *inbuffer, int input_buffer_size) +{ + ALACContext *alac = avctx->priv_data; + + int channels; + int32_t outputsamples; + + /* short-circuit null buffers */ + if (!inbuffer || !input_buffer_size) + return input_buffer_size; + + /* initialize from the extradata */ + if (!alac->context_initialized) { + if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) { + av_log(avctx, AV_LOG_ERROR, "alac: expected %d extradata bytes\n", + ALAC_EXTRADATA_SIZE); + return input_buffer_size; + } + alac_set_info(alac); + alac->context_initialized = 1; + } + + outputsamples = alac->setinfo_max_samples_per_frame; + + init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8); + + channels = get_bits(&alac->gb, 3); + + *outputsize = outputsamples * alac->bytespersample; + + switch(channels) { + case 0: { /* 1 channel */ + int hassize; + int isnotcompressed; + int readsamplesize; + + int wasted_bytes; + int ricemodifier; + + + /* 2^result = something to do with output waiting. + * perhaps matters if we read > 1 frame in a pass? + */ + get_bits(&alac->gb, 4); + + get_bits(&alac->gb, 12); /* unknown, skip 12 bits */ + + hassize = get_bits(&alac->gb, 1); /* the output sample size is stored soon */ + + wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */ + + isnotcompressed = get_bits(&alac->gb, 1); /* whether the frame is compressed */ + + if (hassize) { + /* now read the number of samples, + * as a 32bit integer */ + outputsamples = get_bits(&alac->gb, 32); + *outputsize = outputsamples * alac->bytespersample; + } + + readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8); + + if (!isnotcompressed) { + /* so it is compressed */ + int16_t predictor_coef_table[32]; + int predictor_coef_num; + int prediction_type; + int prediction_quantitization; + int i; + + /* FIXME: skip 16 bits, not sure what they are. seem to be used in + * two channel case */ + get_bits(&alac->gb, 8); + get_bits(&alac->gb, 8); + + prediction_type = get_bits(&alac->gb, 4); + prediction_quantitization = get_bits(&alac->gb, 4); + + ricemodifier = get_bits(&alac->gb, 3); + predictor_coef_num = get_bits(&alac->gb, 5); + + /* read the predictor table */ + for (i = 0; i < predictor_coef_num; i++) { + predictor_coef_table[i] = (int16_t)get_bits(&alac->gb, 16); + } + + if (wasted_bytes) { + /* these bytes seem to have something to do with + * > 2 channel files. + */ + av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n"); + } + + bastardized_rice_decompress(alac, + alac->predicterror_buffer_a, + outputsamples, + readsamplesize, + alac->setinfo_rice_initialhistory, + alac->setinfo_rice_kmodifier, + ricemodifier * alac->setinfo_rice_historymult / 4, + (1 << alac->setinfo_rice_kmodifier) - 1); + + if (prediction_type == 0) { + /* adaptive fir */ + predictor_decompress_fir_adapt(alac->predicterror_buffer_a, + alac->outputsamples_buffer_a, + outputsamples, + readsamplesize, + predictor_coef_table, + predictor_coef_num, + prediction_quantitization); + } else { + av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type); + /* i think the only other prediction type (or perhaps this is just a + * boolean?) runs adaptive fir twice.. like: + * predictor_decompress_fir_adapt(predictor_error, tempout, ...) + * predictor_decompress_fir_adapt(predictor_error, outputsamples ...) + * little strange.. + */ + } + + } else { + /* not compressed, easy case */ + if (readsamplesize <= 16) { + int i; + for (i = 0; i < outputsamples; i++) { + int32_t audiobits = get_bits(&alac->gb, readsamplesize); + + audiobits = SIGN_EXTENDED32(audiobits, readsamplesize); + + alac->outputsamples_buffer_a[i] = audiobits; + } + } else { + int i; + for (i = 0; i < outputsamples; i++) { + int32_t audiobits; + + audiobits = get_bits(&alac->gb, 16); + /* special case of sign extension.. + * as we'll be ORing the low 16bits into this */ + audiobits = audiobits << 16; + audiobits = audiobits >> (32 - readsamplesize); + + audiobits |= get_bits(&alac->gb, readsamplesize - 16); + + alac->outputsamples_buffer_a[i] = audiobits; + } + } + /* wasted_bytes = 0; // unused */ + } + + switch(alac->setinfo_sample_size) { + case 16: { + int i; + for (i = 0; i < outputsamples; i++) { + int16_t sample = alac->outputsamples_buffer_a[i]; + sample = be2me_16(sample); + ((int16_t*)outbuffer)[i * alac->numchannels] = sample; + } + break; + } + case 20: + case 24: + case 32: + av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); + break; + default: + break; + } + break; + } + case 1: { /* 2 channels */ + int hassize; + int isnotcompressed; + int readsamplesize; + + int wasted_bytes; + + uint8_t interlacing_shift; + uint8_t interlacing_leftweight; + + /* 2^result = something to do with output waiting. + * perhaps matters if we read > 1 frame in a pass? + */ + get_bits(&alac->gb, 4); + + get_bits(&alac->gb, 12); /* unknown, skip 12 bits */ + + hassize = get_bits(&alac->gb, 1); /* the output sample size is stored soon */ + + wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */ + + isnotcompressed = get_bits(&alac->gb, 1); /* whether the frame is compressed */ + + if (hassize) { + /* now read the number of samples, + * as a 32bit integer */ + outputsamples = get_bits(&alac->gb, 32); + *outputsize = outputsamples * alac->bytespersample; + } + + readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + 1; + + if (!isnotcompressed) { + /* compressed */ + int16_t predictor_coef_table_a[32]; + int predictor_coef_num_a; + int prediction_type_a; + int prediction_quantitization_a; + int ricemodifier_a; + + int16_t predictor_coef_table_b[32]; + int predictor_coef_num_b; + int prediction_type_b; + int prediction_quantitization_b; + int ricemodifier_b; + + int i; + + interlacing_shift = get_bits(&alac->gb, 8); + interlacing_leftweight = get_bits(&alac->gb, 8); + + /******** channel 1 ***********/ + prediction_type_a = get_bits(&alac->gb, 4); + prediction_quantitization_a = get_bits(&alac->gb, 4); + + ricemodifier_a = get_bits(&alac->gb, 3); + predictor_coef_num_a = get_bits(&alac->gb, 5); + + /* read the predictor table */ + for (i = 0; i < predictor_coef_num_a; i++) { + predictor_coef_table_a[i] = (int16_t)get_bits(&alac->gb, 16); + } + + /******** channel 2 *********/ + prediction_type_b = get_bits(&alac->gb, 4); + prediction_quantitization_b = get_bits(&alac->gb, 4); + + ricemodifier_b = get_bits(&alac->gb, 3); + predictor_coef_num_b = get_bits(&alac->gb, 5); + + /* read the predictor table */ + for (i = 0; i < predictor_coef_num_b; i++) { + predictor_coef_table_b[i] = (int16_t)get_bits(&alac->gb, 16); + } + + /*********************/ + if (wasted_bytes) { + /* see mono case */ + av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n"); + } + + /* channel 1 */ + bastardized_rice_decompress(alac, + alac->predicterror_buffer_a, + outputsamples, + readsamplesize, + alac->setinfo_rice_initialhistory, + alac->setinfo_rice_kmodifier, + ricemodifier_a * alac->setinfo_rice_historymult / 4, + (1 << alac->setinfo_rice_kmodifier) - 1); + + if (prediction_type_a == 0) { + /* adaptive fir */ + predictor_decompress_fir_adapt(alac->predicterror_buffer_a, + alac->outputsamples_buffer_a, + outputsamples, + readsamplesize, + predictor_coef_table_a, + predictor_coef_num_a, + prediction_quantitization_a); + } else { + /* see mono case */ + av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type_a); + } + + /* channel 2 */ + bastardized_rice_decompress(alac, + alac->predicterror_buffer_b, + outputsamples, + readsamplesize, + alac->setinfo_rice_initialhistory, + alac->setinfo_rice_kmodifier, + ricemodifier_b * alac->setinfo_rice_historymult / 4, + (1 << alac->setinfo_rice_kmodifier) - 1); + + if (prediction_type_b == 0) { + /* adaptive fir */ + predictor_decompress_fir_adapt(alac->predicterror_buffer_b, + alac->outputsamples_buffer_b, + outputsamples, + readsamplesize, + predictor_coef_table_b, + predictor_coef_num_b, + prediction_quantitization_b); + } else { + av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type_b); + } + } else { + /* not compressed, easy case */ + if (alac->setinfo_sample_size <= 16) { + int i; + for (i = 0; i < outputsamples; i++) { + int32_t audiobits_a, audiobits_b; + + audiobits_a = get_bits(&alac->gb, alac->setinfo_sample_size); + audiobits_b = get_bits(&alac->gb, alac->setinfo_sample_size); + + audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size); + audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size); + + alac->outputsamples_buffer_a[i] = audiobits_a; + alac->outputsamples_buffer_b[i] = audiobits_b; + } + } else { + int i; + for (i = 0; i < outputsamples; i++) { + int32_t audiobits_a, audiobits_b; + + audiobits_a = get_bits(&alac->gb, 16); + audiobits_a = audiobits_a << 16; + audiobits_a = audiobits_a >> (32 - alac->setinfo_sample_size); + audiobits_a |= get_bits(&alac->gb, alac->setinfo_sample_size - 16); + + audiobits_b = get_bits(&alac->gb, 16); + audiobits_b = audiobits_b << 16; + audiobits_b = audiobits_b >> (32 - alac->setinfo_sample_size); + audiobits_b |= get_bits(&alac->gb, alac->setinfo_sample_size - 16); + + alac->outputsamples_buffer_a[i] = audiobits_a; + alac->outputsamples_buffer_b[i] = audiobits_b; + } + } + /* wasted_bytes = 0; */ + interlacing_shift = 0; + interlacing_leftweight = 0; + } + + switch(alac->setinfo_sample_size) { + case 16: { + deinterlace_16(alac->outputsamples_buffer_a, + alac->outputsamples_buffer_b, + (int16_t*)outbuffer, + alac->numchannels, + outputsamples, + interlacing_shift, + interlacing_leftweight); + break; + } + case 20: + case 24: + case 32: + av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); + break; + default: + break; + } + + break; + } + } + + return input_buffer_size; +} + +static int alac_decode_init(AVCodecContext * avctx) +{ + ALACContext *alac = avctx->priv_data; + alac->avctx = avctx; + alac->context_initialized = 0; + + alac->samplesize = alac->avctx->bits_per_sample; + alac->numchannels = alac->avctx->channels; + alac->bytespersample = (alac->samplesize / 8) * alac->numchannels; + + return 0; +} + +static int alac_decode_close(AVCodecContext *avctx) +{ + ALACContext *alac = avctx->priv_data; + + av_free(alac->predicterror_buffer_a); + av_free(alac->predicterror_buffer_b); + + av_free(alac->outputsamples_buffer_a); + av_free(alac->outputsamples_buffer_b); + + return 0; +} + +AVCodec alac_decoder = { + "alac", + CODEC_TYPE_AUDIO, + CODEC_ID_ALAC, + sizeof(ALACContext), + alac_decode_init, + NULL, + alac_decode_close, + alac_decode_frame, +}; diff --git a/mpeg4/src/libavcodec/allcodecs.c b/mpeg4/src/libavcodec/allcodecs.c new file mode 100644 index 00000000..f2d75209 --- /dev/null +++ b/mpeg4/src/libavcodec/allcodecs.c @@ -0,0 +1,655 @@ +/* + * Utils for libavcodec + * Copyright (c) 2002 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file allcodecs.c + * Utils for libavcodec. + */ + +#include "avcodec.h" + +/* If you do not call this function, then you can select exactly which + formats you want to support */ + +/** + * simple call to register all the codecs. + */ +void avcodec_register_all(void) +{ + static int inited = 0; + + if (inited != 0) + return; + inited = 1; + + /* encoders */ +#ifdef CONFIG_ENCODERS +#ifdef CONFIG_AC3_ENCODER + register_avcodec(&ac3_encoder); +#endif //CONFIG_AC3_ENCODER +#ifdef CONFIG_MP2_ENCODER + register_avcodec(&mp2_encoder); +#endif //CONFIG_MP2_ENCODER +#ifdef CONFIG_MP3LAME +#ifdef CONFIG_MP3LAME_ENCODER + register_avcodec(&mp3lame_encoder); +#endif //CONFIG_MP3LAME_ENCODER +#endif +#ifdef CONFIG_LIBVORBIS +#ifdef CONFIG_OGGVORBIS_ENCODER + register_avcodec(&oggvorbis_encoder); +#endif //CONFIG_OGGVORBIS_ENCODER +#if (defined CONFIG_OGGVORBIS_DECODER && !defined CONFIG_VORBIS_DECODER) + register_avcodec(&oggvorbis_decoder); +#endif //CONFIG_OGGVORBIS_DECODER +#endif +#ifdef CONFIG_LIBTHEORA +#ifdef CONFIG_OGGTHEORA_ENCODER +// register_avcodec(&oggtheora_encoder); +#endif //CONFIG_OGGTHEORA_ENCODER +#ifdef CONFIG_OGGTHEORA_DECODER + register_avcodec(&oggtheora_decoder); +#endif //CONFIG_OGGTHEORA_DECODER +#endif +#ifdef CONFIG_FAAC +#ifdef CONFIG_FAAC_ENCODER + register_avcodec(&faac_encoder); +#endif //CONFIG_FAAC_ENCODER +#endif +#ifdef CONFIG_XVID +#ifdef CONFIG_XVID_ENCODER + register_avcodec(&xvid_encoder); +#endif //CONFIG_XVID_ENCODER +#endif +#ifdef CONFIG_MPEG1VIDEO_ENCODER + register_avcodec(&mpeg1video_encoder); +#endif //CONFIG_MPEG1VIDEO_ENCODER +#ifdef CONFIG_H264_ENCODER +// register_avcodec(&h264_encoder); +#endif //CONFIG_H264_ENCODER +#ifdef CONFIG_MPEG2VIDEO_ENCODER + register_avcodec(&mpeg2video_encoder); +#endif //CONFIG_MPEG2VIDEO_ENCODER +#ifdef CONFIG_H261_ENCODER + register_avcodec(&h261_encoder); +#endif //CONFIG_H261_ENCODER +#ifdef CONFIG_H263_ENCODER + register_avcodec(&h263_encoder); +#endif //CONFIG_H263_ENCODER +#ifdef CONFIG_H263P_ENCODER + register_avcodec(&h263p_encoder); +#endif //CONFIG_H263P_ENCODER +#ifdef CONFIG_FLV_ENCODER + register_avcodec(&flv_encoder); +#endif //CONFIG_FLV_ENCODER +#ifdef CONFIG_RV10_ENCODER + register_avcodec(&rv10_encoder); +#endif //CONFIG_RV10_ENCODER +#ifdef CONFIG_RV20_ENCODER + register_avcodec(&rv20_encoder); +#endif //CONFIG_RV20_ENCODER +#ifdef CONFIG_MPEG4_ENCODER + register_avcodec(&mpeg4_encoder); +#endif //CONFIG_MPEG4_ENCODER +#ifdef CONFIG_MSMPEG4V1_ENCODER + register_avcodec(&msmpeg4v1_encoder); +#endif //CONFIG_MSMPEG4V1_ENCODER +#ifdef CONFIG_MSMPEG4V2_ENCODER + register_avcodec(&msmpeg4v2_encoder); +#endif //CONFIG_MSMPEG4V2_ENCODER +#ifdef CONFIG_MSMPEG4V3_ENCODER + register_avcodec(&msmpeg4v3_encoder); +#endif //CONFIG_MSMPEG4V3_ENCODER +#ifdef CONFIG_WMV1_ENCODER + register_avcodec(&wmv1_encoder); +#endif //CONFIG_WMV1_ENCODER +#ifdef CONFIG_WMV2_ENCODER + register_avcodec(&wmv2_encoder); +#endif //CONFIG_WMV2_ENCODER +#ifdef CONFIG_SVQ1_ENCODER + register_avcodec(&svq1_encoder); +#endif //CONFIG_SVQ1_ENCODER +#ifdef CONFIG_MJPEG_ENCODER + register_avcodec(&mjpeg_encoder); +#endif //CONFIG_MJPEG_ENCODER +#ifdef CONFIG_LJPEG_ENCODER + register_avcodec(&ljpeg_encoder); +#endif //CONFIG_LJPEG_ENCODER +#ifdef CONFIG_JPEGLS_ENCODER + register_avcodec(&jpegls_encoder); +#endif //CONFIG_JPEGLS_ENCODER +#ifdef CONFIG_ZLIB +#ifdef CONFIG_PNG_ENCODER + register_avcodec(&png_encoder); +#endif //CONFIG_PNG_ENCODER +#endif +#ifdef CONFIG_PPM_ENCODER + register_avcodec(&ppm_encoder); +#endif //CONFIG_PPM_ENCODER +#ifdef CONFIG_PGM_ENCODER + register_avcodec(&pgm_encoder); +#endif //CONFIG_PGM_ENCODER +#ifdef CONFIG_PGMYUV_ENCODER + register_avcodec(&pgmyuv_encoder); +#endif //CONFIG_PGMYUV_ENCODER +#ifdef CONFIG_PBM_ENCODER + register_avcodec(&pbm_encoder); +#endif //CONFIG_PBM_ENCODER +#ifdef CONFIG_PAM_ENCODER + register_avcodec(&pam_encoder); +#endif //CONFIG_PAM_ENCODER +#ifdef CONFIG_HUFFYUV_ENCODER + register_avcodec(&huffyuv_encoder); +#endif //CONFIG_HUFFYUV_ENCODER +#ifdef CONFIG_FFVHUFF_ENCODER + register_avcodec(&ffvhuff_encoder); +#endif //CONFIG_FFVHUFF_ENCODER +#ifdef CONFIG_ASV1_ENCODER + register_avcodec(&asv1_encoder); +#endif //CONFIG_ASV1_ENCODER +#ifdef CONFIG_ASV2_ENCODER + register_avcodec(&asv2_encoder); +#endif //CONFIG_ASV2_ENCODER +#ifdef CONFIG_FFV1_ENCODER + register_avcodec(&ffv1_encoder); +#endif //CONFIG_FFV1_ENCODER +#ifdef CONFIG_SNOW_ENCODER + register_avcodec(&snow_encoder); +#endif //CONFIG_SNOW_ENCODER +#ifdef CONFIG_ZLIB_ENCODER + register_avcodec(&zlib_encoder); +#endif //CONFIG_ZLIB_ENCODER +#ifdef CONFIG_DVVIDEO_ENCODER + register_avcodec(&dvvideo_encoder); +#endif //CONFIG_DVVIDEO_ENCODER +#ifdef CONFIG_SONIC_ENCODER + register_avcodec(&sonic_encoder); +#endif //CONFIG_SONIC_ENCODER +#ifdef CONFIG_SONIC_LS_ENCODER + register_avcodec(&sonic_ls_encoder); +#endif //CONFIG_SONIC_LS_ENCODER +#ifdef CONFIG_X264 +#ifdef CONFIG_X264_ENCODER + register_avcodec(&x264_encoder); +#endif //CONFIG_X264_ENCODER +#endif +#ifdef CONFIG_LIBGSM + register_avcodec(&libgsm_encoder); +#endif //CONFIG_LIBGSM +#ifdef CONFIG_RAWVIDEO_ENCODER + register_avcodec(&rawvideo_encoder); +#endif //CONFIG_RAWVIDEO_ENCODER +#endif /* CONFIG_ENCODERS */ + + /* decoders */ +#ifdef CONFIG_DECODERS +#ifdef CONFIG_H263_DECODER + register_avcodec(&h263_decoder); +#endif //CONFIG_H263_DECODER +#ifdef CONFIG_H261_DECODER + register_avcodec(&h261_decoder); +#endif //CONFIG_H261_DECODER +#ifdef CONFIG_MPEG4_DECODER + register_avcodec(&mpeg4_decoder); +#endif //CONFIG_MPEG4_DECODER +#ifdef CONFIG_MSMPEG4V1_DECODER + register_avcodec(&msmpeg4v1_decoder); +#endif //CONFIG_MSMPEG4V1_DECODER +#ifdef CONFIG_MSMPEG4V2_DECODER + register_avcodec(&msmpeg4v2_decoder); +#endif //CONFIG_MSMPEG4V2_DECODER +#ifdef CONFIG_MSMPEG4V3_DECODER + register_avcodec(&msmpeg4v3_decoder); +#endif //CONFIG_MSMPEG4V3_DECODER +#ifdef CONFIG_WMV1_DECODER + register_avcodec(&wmv1_decoder); +#endif //CONFIG_WMV1_DECODER +#ifdef CONFIG_WMV2_DECODER + register_avcodec(&wmv2_decoder); +#endif //CONFIG_WMV2_DECODER +#ifdef CONFIG_VC9_DECODER + register_avcodec(&vc9_decoder); +#endif //CONFIG_VC9_DECODER +/* Reenable when it stops crashing on every file, causing bug report spam. +#ifdef CONFIG_WMV3_DECODER + register_avcodec(&wmv3_decoder); +#endif //CONFIG_WMV3_DECODER +*/ +#ifdef CONFIG_H263I_DECODER + register_avcodec(&h263i_decoder); +#endif //CONFIG_H263I_DECODER +#ifdef CONFIG_FLV_DECODER + register_avcodec(&flv_decoder); +#endif //CONFIG_FLV_DECODER +#ifdef CONFIG_RV10_DECODER + register_avcodec(&rv10_decoder); +#endif //CONFIG_RV10_DECODER +#ifdef CONFIG_RV20_DECODER + register_avcodec(&rv20_decoder); +#endif //CONFIG_RV20_DECODER +#ifdef CONFIG_SVQ1_DECODER + register_avcodec(&svq1_decoder); +#endif //CONFIG_SVQ1_DECODER +#ifdef CONFIG_SVQ3_DECODER + register_avcodec(&svq3_decoder); +#endif //CONFIG_SVQ3_DECODER +#ifdef CONFIG_WMAV1_DECODER + register_avcodec(&wmav1_decoder); +#endif //CONFIG_WMAV1_DECODER +#ifdef CONFIG_WMAV2_DECODER + register_avcodec(&wmav2_decoder); +#endif //CONFIG_WMAV2_DECODER +#ifdef CONFIG_INDEO2_DECODER + register_avcodec(&indeo2_decoder); +#endif //CONFIG_INDEO2_DECODER +#ifdef CONFIG_INDEO3_DECODER + register_avcodec(&indeo3_decoder); +#endif //CONFIG_INDEO3_DECODER +#ifdef CONFIG_TSCC_DECODER + register_avcodec(&tscc_decoder); +#endif //CONFIG_TSCC_DECODER +#ifdef CONFIG_CSCD_DECODER + register_avcodec(&cscd_decoder); +#endif //CONFIG_CSCD_DECODER +#ifdef CONFIG_NUV_DECODER + register_avcodec(&nuv_decoder); +#endif //CONFIG_NUV_DECODER +#ifdef CONFIG_ULTI_DECODER + register_avcodec(&ulti_decoder); +#endif //CONFIG_ULTI_DECODER +#ifdef CONFIG_QDRAW_DECODER + register_avcodec(&qdraw_decoder); +#endif //CONFIG_QDRAW_DECODER +#ifdef CONFIG_XL_DECODER + register_avcodec(&xl_decoder); +#endif //CONFIG_XL_DECODER +#ifdef CONFIG_QPEG_DECODER + register_avcodec(&qpeg_decoder); +#endif //CONFIG_QPEG_DECODER +#ifdef CONFIG_LOCO_DECODER + register_avcodec(&loco_decoder); +#endif //CONFIG_LOCO_DECODER +#ifdef CONFIG_KMVC_DECODER + register_avcodec(&kmvc_decoder); +#endif //CONFIG_KMVC_DECODER +#ifdef CONFIG_WNV1_DECODER + register_avcodec(&wnv1_decoder); +#endif //CONFIG_WNV1_DECODER +#ifdef CONFIG_AASC_DECODER + register_avcodec(&aasc_decoder); +#endif //CONFIG_AASC_DECODER +#ifdef CONFIG_FRAPS_DECODER + register_avcodec(&fraps_decoder); +#endif //CONFIG_FRAPS_DECODER +#ifdef CONFIG_FAAD +#ifdef CONFIG_AAC_DECODER + register_avcodec(&aac_decoder); +#endif //CONFIG_AAC_DECODER +#ifdef CONFIG_MPEG4AAC_DECODER + register_avcodec(&mpeg4aac_decoder); +#endif //CONFIG_MPEG4AAC_DECODER +#endif +#ifdef CONFIG_MPEG1VIDEO_DECODER + register_avcodec(&mpeg1video_decoder); +#endif //CONFIG_MPEG1VIDEO_DECODER +#ifdef CONFIG_MPEG2VIDEO_DECODER + register_avcodec(&mpeg2video_decoder); +#endif //CONFIG_MPEG2VIDEO_DECODER +#ifdef CONFIG_MPEGVIDEO_DECODER + register_avcodec(&mpegvideo_decoder); +#endif //CONFIG_MPEGVIDEO_DECODER +#ifdef HAVE_XVMC +#ifdef CONFIG_MPEG_XVMC_DECODER + register_avcodec(&mpeg_xvmc_decoder); +#endif //CONFIG_MPEG_XVMC_DECODER +#endif +#ifdef CONFIG_DVVIDEO_DECODER + register_avcodec(&dvvideo_decoder); +#endif //CONFIG_DVVIDEO_DECODER +#ifdef CONFIG_MJPEG_DECODER + register_avcodec(&mjpeg_decoder); +#endif //CONFIG_MJPEG_DECODER +#ifdef CONFIG_MJPEGB_DECODER + register_avcodec(&mjpegb_decoder); +#endif //CONFIG_MJPEGB_DECODER +#ifdef CONFIG_SP5X_DECODER + register_avcodec(&sp5x_decoder); +#endif //CONFIG_SP5X_DECODER +#ifdef CONFIG_ZLIB +#ifdef CONFIG_PNG_DECODER + register_avcodec(&png_decoder); +#endif //CONFIG_PNG_DECODER +#endif +#ifdef CONFIG_MP2_DECODER + register_avcodec(&mp2_decoder); +#endif //CONFIG_MP2_DECODER +#ifdef CONFIG_MP3_DECODER + register_avcodec(&mp3_decoder); +#endif //CONFIG_MP3_DECODER +#ifdef CONFIG_MP3ADU_DECODER + register_avcodec(&mp3adu_decoder); +#endif //CONFIG_MP3ADU_DECODER +#ifdef CONFIG_MP3ON4_DECODER + register_avcodec(&mp3on4_decoder); +#endif //CONFIG_MP3ON4_DECODER +#ifdef CONFIG_MACE3_DECODER + register_avcodec(&mace3_decoder); +#endif //CONFIG_MACE3_DECODER +#ifdef CONFIG_MACE6_DECODER + register_avcodec(&mace6_decoder); +#endif //CONFIG_MACE6_DECODER +#ifdef CONFIG_HUFFYUV_DECODER + register_avcodec(&huffyuv_decoder); +#endif //CONFIG_HUFFYUV_DECODER +#ifdef CONFIG_FFVHUFF_DECODER + register_avcodec(&ffvhuff_decoder); +#endif //CONFIG_FFVHUFF_DECODER +#ifdef CONFIG_FFV1_DECODER + register_avcodec(&ffv1_decoder); +#endif //CONFIG_FFV1_DECODER +#ifdef CONFIG_SNOW_DECODER + register_avcodec(&snow_decoder); +#endif //CONFIG_SNOW_DECODER +#ifdef CONFIG_CYUV_DECODER + register_avcodec(&cyuv_decoder); +#endif //CONFIG_CYUV_DECODER +#ifdef CONFIG_H264_DECODER + register_avcodec(&h264_decoder); +#endif //CONFIG_H264_DECODER +#ifdef CONFIG_VP3_DECODER + register_avcodec(&vp3_decoder); +#endif //CONFIG_VP3_DECODER +#if (defined CONFIG_THEORA_DECODER && !defined CONFIG_LIBTHEORA) + register_avcodec(&theora_decoder); +#endif //CONFIG_THEORA_DECODER +#ifdef CONFIG_ASV1_DECODER + register_avcodec(&asv1_decoder); +#endif //CONFIG_ASV1_DECODER +#ifdef CONFIG_ASV2_DECODER + register_avcodec(&asv2_decoder); +#endif //CONFIG_ASV2_DECODER +#ifdef CONFIG_VCR1_DECODER + register_avcodec(&vcr1_decoder); +#endif //CONFIG_VCR1_DECODER +#ifdef CONFIG_CLJR_DECODER + register_avcodec(&cljr_decoder); +#endif //CONFIG_CLJR_DECODER +#ifdef CONFIG_FOURXM_DECODER + register_avcodec(&fourxm_decoder); +#endif //CONFIG_FOURXM_DECODER +#ifdef CONFIG_MDEC_DECODER + register_avcodec(&mdec_decoder); +#endif //CONFIG_MDEC_DECODER +#ifdef CONFIG_ROQ_DECODER + register_avcodec(&roq_decoder); +#endif //CONFIG_ROQ_DECODER +#ifdef CONFIG_INTERPLAY_VIDEO_DECODER + register_avcodec(&interplay_video_decoder); +#endif //CONFIG_INTERPLAY_VIDEO_DECODER +#ifdef CONFIG_XAN_WC3_DECODER + register_avcodec(&xan_wc3_decoder); +#endif //CONFIG_XAN_WC3_DECODER +#ifdef CONFIG_RPZA_DECODER + register_avcodec(&rpza_decoder); +#endif //CONFIG_RPZA_DECODER +#ifdef CONFIG_CINEPAK_DECODER + register_avcodec(&cinepak_decoder); +#endif //CONFIG_CINEPAK_DECODER +#ifdef CONFIG_MSRLE_DECODER + register_avcodec(&msrle_decoder); +#endif //CONFIG_MSRLE_DECODER +#ifdef CONFIG_MSVIDEO1_DECODER + register_avcodec(&msvideo1_decoder); +#endif //CONFIG_MSVIDEO1_DECODER +#ifdef CONFIG_VQA_DECODER + register_avcodec(&vqa_decoder); +#endif //CONFIG_VQA_DECODER +#ifdef CONFIG_IDCIN_DECODER + register_avcodec(&idcin_decoder); +#endif //CONFIG_IDCIN_DECODER +#ifdef CONFIG_EIGHTBPS_DECODER + register_avcodec(&eightbps_decoder); +#endif //CONFIG_EIGHTBPS_DECODER +#ifdef CONFIG_SMC_DECODER + register_avcodec(&smc_decoder); +#endif //CONFIG_SMC_DECODER +#ifdef CONFIG_FLIC_DECODER + register_avcodec(&flic_decoder); +#endif //CONFIG_FLIC_DECODER +#ifdef CONFIG_TRUEMOTION1_DECODER + register_avcodec(&truemotion1_decoder); +#endif //CONFIG_TRUEMOTION1_DECODER +#ifdef CONFIG_TRUEMOTION2_DECODER + register_avcodec(&truemotion2_decoder); +#endif //CONFIG_TRUEMOTION2_DECODER +#ifdef CONFIG_VMDVIDEO_DECODER + register_avcodec(&vmdvideo_decoder); +#endif //CONFIG_VMDVIDEO_DECODER +#ifdef CONFIG_VMDAUDIO_DECODER + register_avcodec(&vmdaudio_decoder); +#endif //CONFIG_VMDAUDIO_DECODER +#ifdef CONFIG_MSZH_DECODER + register_avcodec(&mszh_decoder); +#endif //CONFIG_MSZH_DECODER +#ifdef CONFIG_ZLIB_DECODER + register_avcodec(&zlib_decoder); +#endif //CONFIG_ZLIB_DECODER +#ifdef CONFIG_ZMBV_DECODER + register_avcodec(&zmbv_decoder); +#endif //CONFIG_ZMBV_DECODER +#ifdef CONFIG_SMACKER_DECODER + register_avcodec(&smacker_decoder); +#endif //CONFIG_SMACKER_DECODER +#ifdef CONFIG_SMACKAUD_DECODER + register_avcodec(&smackaud_decoder); +#endif //CONFIG_SMACKAUD_DECODER +#ifdef CONFIG_SONIC_DECODER + register_avcodec(&sonic_decoder); +#endif //CONFIG_SONIC_DECODER +#ifdef CONFIG_AC3 +#ifdef CONFIG_AC3_DECODER + register_avcodec(&ac3_decoder); +#endif //CONFIG_AC3_DECODER +#endif +#ifdef CONFIG_DTS +#ifdef CONFIG_DTS_DECODER + register_avcodec(&dts_decoder); +#endif //CONFIG_DTS_DECODER +#endif +#ifdef CONFIG_RA_144_DECODER + register_avcodec(&ra_144_decoder); +#endif //CONFIG_RA_144_DECODER +#ifdef CONFIG_RA_288_DECODER + register_avcodec(&ra_288_decoder); +#endif //CONFIG_RA_288_DECODER +#ifdef CONFIG_ROQ_DPCM_DECODER + register_avcodec(&roq_dpcm_decoder); +#endif //CONFIG_ROQ_DPCM_DECODER +#ifdef CONFIG_INTERPLAY_DPCM_DECODER + register_avcodec(&interplay_dpcm_decoder); +#endif //CONFIG_INTERPLAY_DPCM_DECODER +#ifdef CONFIG_XAN_DPCM_DECODER + register_avcodec(&xan_dpcm_decoder); +#endif //CONFIG_XAN_DPCM_DECODER +#ifdef CONFIG_SOL_DPCM_DECODER + register_avcodec(&sol_dpcm_decoder); +#endif //CONFIG_SOL_DPCM_DECODER +#ifdef CONFIG_QTRLE_DECODER + register_avcodec(&qtrle_decoder); +#endif //CONFIG_QTRLE_DECODER +#ifdef CONFIG_FLAC_DECODER + register_avcodec(&flac_decoder); +#endif //CONFIG_FLAC_DECODER +#ifdef CONFIG_SHORTEN_DECODER + register_avcodec(&shorten_decoder); +#endif //CONFIG_SHORTEN_DECODER +#ifdef CONFIG_ALAC_DECODER + register_avcodec(&alac_decoder); +#endif //CONFIG_ALAC_DECODER +#ifdef CONFIG_WS_SND1_DECODER + register_avcodec(&ws_snd1_decoder); +#endif //CONFIG_WS_SND1_DECODER +#ifdef CONFIG_VORBIS_DECODER + register_avcodec(&vorbis_decoder); +#endif +#ifdef CONFIG_LIBGSM + register_avcodec(&libgsm_decoder); +#endif //CONFIG_LIBGSM +#ifdef CONFIG_QDM2_DECODER + register_avcodec(&qdm2_decoder); +#endif //CONFIG_QDM2_DECODER +#ifdef CONFIG_COOK_DECODER + register_avcodec(&cook_decoder); +#endif //CONFIG_COOK_DECODER +#ifdef CONFIG_TRUESPEECH_DECODER + register_avcodec(&truespeech_decoder); +#endif //CONFIG_TRUESPEECH_DECODER +#ifdef CONFIG_TTA_DECODER + register_avcodec(&tta_decoder); +#endif //CONFIG_TTA_DECODER +#ifdef CONFIG_AVS_DECODER + register_avcodec(&avs_decoder); +#endif //CONFIG_AVS_DECODER +#ifdef CONFIG_RAWVIDEO_DECODER + register_avcodec(&rawvideo_decoder); +#endif //CONFIG_RAWVIDEO_DECODER +#endif /* CONFIG_DECODERS */ + +#ifdef AMR_NB +#ifdef CONFIG_AMR_NB_DECODER + register_avcodec(&amr_nb_decoder); +#endif //CONFIG_AMR_NB_DECODER +#ifdef CONFIG_ENCODERS +#ifdef CONFIG_AMR_NB_ENCODER + register_avcodec(&amr_nb_encoder); +#endif //CONFIG_AMR_NB_ENCODER +#endif //CONFIG_ENCODERS +#endif /* AMR_NB */ + +#ifdef AMR_WB +#ifdef CONFIG_AMR_WB_DECODER + register_avcodec(&amr_wb_decoder); +#endif //CONFIG_AMR_WB_DECODER +#ifdef CONFIG_ENCODERS +#ifdef CONFIG_AMR_WB_ENCODER + register_avcodec(&amr_wb_encoder); +#endif //CONFIG_AMR_WB_ENCODER +#endif //CONFIG_ENCODERS +#endif /* AMR_WB */ + +#ifdef CONFIG_BMP_DECODER + register_avcodec(&bmp_decoder); +#endif + +#if CONFIG_MMVIDEO_DECODER + register_avcodec(&mmvideo_decoder); +#endif //CONFIG_MMVIDEO_DECODER + + /* pcm codecs */ +#if defined (CONFIG_ENCODERS) && defined (CONFIG_DECODERS) + #define PCM_CODEC(id, name) \ + register_avcodec(& name ## _encoder); \ + register_avcodec(& name ## _decoder); +#elif defined (CONFIG_ENCODERS) + #define PCM_CODEC(id, name) \ + register_avcodec(& name ## _encoder); +#elif defined (CONFIG_DECODERS) + #define PCM_CODEC(id, name) \ + register_avcodec(& name ## _decoder); +#endif + +PCM_CODEC(CODEC_ID_PCM_S32LE, pcm_s32le); +PCM_CODEC(CODEC_ID_PCM_S32BE, pcm_s32be); +PCM_CODEC(CODEC_ID_PCM_U32LE, pcm_u32le); +PCM_CODEC(CODEC_ID_PCM_U32BE, pcm_u32be); +PCM_CODEC(CODEC_ID_PCM_S24LE, pcm_s24le); +PCM_CODEC(CODEC_ID_PCM_S24BE, pcm_s24be); +PCM_CODEC(CODEC_ID_PCM_U24LE, pcm_u24le); +PCM_CODEC(CODEC_ID_PCM_U24BE, pcm_u24be); +PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); +PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); +PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); +PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); +PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); +PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); +PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); +PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); +PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); + + /* adpcm codecs */ +PCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); +PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); +PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); +PCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); +PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws); +PCM_CODEC(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg); +PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); +PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); +PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); +PCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx); +PCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); +PCM_CODEC(CODEC_ID_ADPCM_G726, adpcm_g726); +PCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct); +PCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf); +PCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); +PCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4); +PCM_CODEC(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3); +PCM_CODEC(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2); +#undef PCM_CODEC + + /* subtitles */ +#ifdef CONFIG_DVDSUB_DECODER + register_avcodec(&dvdsub_decoder); +#endif +#ifdef CONFIG_DVDSUB_ENCODER + register_avcodec(&dvdsub_encoder); +#endif + +#ifdef CONFIG_DVBSUB_DECODER + register_avcodec(&dvbsub_decoder); +#endif +#ifdef CONFIG_DVBSUB_ENCODER + register_avcodec(&dvbsub_encoder); +#endif + + /* parsers */ + av_register_codec_parser(&mpegvideo_parser); + av_register_codec_parser(&mpeg4video_parser); +#if defined(CONFIG_H261_DECODER) || defined(CONFIG_H261_ENCODER) + av_register_codec_parser(&h261_parser); +#endif + av_register_codec_parser(&h263_parser); +#ifdef CONFIG_H264_DECODER + av_register_codec_parser(&h264_parser); +#endif + av_register_codec_parser(&mjpeg_parser); + av_register_codec_parser(&pnm_parser); + + av_register_codec_parser(&mpegaudio_parser); + av_register_codec_parser(&ac3_parser); + +#ifdef CONFIG_DVDSUB_DECODER + av_register_codec_parser(&dvdsub_parser); +#endif +#ifdef CONFIG_DVBSUB_DECODER + av_register_codec_parser(&dvbsub_parser); +#endif + av_register_codec_parser(&aac_parser); +} + diff --git a/mpeg4/src/libavcodec/alpha/asm.h b/mpeg4/src/libavcodec/alpha/asm.h new file mode 100644 index 00000000..056e043f --- /dev/null +++ b/mpeg4/src/libavcodec/alpha/asm.h @@ -0,0 +1,189 @@ +/* + * Alpha optimized DSP utils + * Copyright (c) 2002 Falk Hueffner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBAVCODEC_ALPHA_ASM_H +#define LIBAVCODEC_ALPHA_ASM_H + +#include + +#if defined __GNUC__ +# define GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +# define GNUC_PREREQ(maj, min) 0 +#endif + +#if GNUC_PREREQ(2,96) +# define likely(x) __builtin_expect((x) != 0, 1) +# define unlikely(x) __builtin_expect((x) != 0, 0) +#else +# define likely(x) (x) +# define unlikely(x) (x) +#endif + +#define AMASK_BWX (1 << 0) +#define AMASK_FIX (1 << 1) +#define AMASK_CIX (1 << 2) +#define AMASK_MVI (1 << 8) + +static inline uint64_t BYTE_VEC(uint64_t x) +{ + x |= x << 8; + x |= x << 16; + x |= x << 32; + return x; +} +static inline uint64_t WORD_VEC(uint64_t x) +{ + x |= x << 16; + x |= x << 32; + return x; +} + +#define sextw(x) ((int16_t) (x)) + +#ifdef __GNUC__ +#define ldq(p) \ + (((union { \ + uint64_t __l; \ + __typeof__(*(p)) __s[sizeof (uint64_t) / sizeof *(p)]; \ + } *) (p))->__l) +#define ldl(p) \ + (((union { \ + int32_t __l; \ + __typeof__(*(p)) __s[sizeof (int32_t) / sizeof *(p)]; \ + } *) (p))->__l) +#define stq(l, p) \ + do { \ + (((union { \ + uint64_t __l; \ + __typeof__(*(p)) __s[sizeof (uint64_t) / sizeof *(p)]; \ + } *) (p))->__l) = l; \ + } while (0) +#define stl(l, p) \ + do { \ + (((union { \ + int32_t __l; \ + __typeof__(*(p)) __s[sizeof (int32_t) / sizeof *(p)]; \ + } *) (p))->__l) = l; \ + } while (0) +struct unaligned_long { uint64_t l; } __attribute__((packed)); +#define ldq_u(p) (*(const uint64_t *) (((uint64_t) (p)) & ~7ul)) +#define uldq(a) (((const struct unaligned_long *) (a))->l) + +#if GNUC_PREREQ(3,3) +#define prefetch(p) __builtin_prefetch((p), 0, 1) +#define prefetch_en(p) __builtin_prefetch((p), 0, 0) +#define prefetch_m(p) __builtin_prefetch((p), 1, 1) +#define prefetch_men(p) __builtin_prefetch((p), 1, 0) +#define cmpbge __builtin_alpha_cmpbge +/* Avoid warnings. */ +#define extql(a, b) __builtin_alpha_extql(a, (uint64_t) (b)) +#define extwl(a, b) __builtin_alpha_extwl(a, (uint64_t) (b)) +#define extqh(a, b) __builtin_alpha_extqh(a, (uint64_t) (b)) +#define zap __builtin_alpha_zap +#define zapnot __builtin_alpha_zapnot +#define amask __builtin_alpha_amask +#define implver __builtin_alpha_implver +#define rpcc __builtin_alpha_rpcc +#else +#define prefetch(p) asm volatile("ldl $31,%0" : : "m"(*(const char *) (p)) : "memory") +#define prefetch_en(p) asm volatile("ldq $31,%0" : : "m"(*(const char *) (p)) : "memory") +#define prefetch_m(p) asm volatile("lds $f31,%0" : : "m"(*(const char *) (p)) : "memory") +#define prefetch_men(p) asm volatile("ldt $f31,%0" : : "m"(*(const char *) (p)) : "memory") +#define cmpbge(a, b) ({ uint64_t __r; asm ("cmpbge %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define extql(a, b) ({ uint64_t __r; asm ("extql %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define extwl(a, b) ({ uint64_t __r; asm ("extwl %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define extqh(a, b) ({ uint64_t __r; asm ("extqh %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define zap(a, b) ({ uint64_t __r; asm ("zap %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define zapnot(a, b) ({ uint64_t __r; asm ("zapnot %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) +#define amask(a) ({ uint64_t __r; asm ("amask %1,%0" : "=r" (__r) : "rI" (a)); __r; }) +#define implver() ({ uint64_t __r; asm ("implver %0" : "=r" (__r)); __r; }) +#define rpcc() ({ uint64_t __r; asm volatile ("rpcc %0" : "=r" (__r)); __r; }) +#endif +#define wh64(p) asm volatile("wh64 (%0)" : : "r"(p) : "memory") + +#if GNUC_PREREQ(3,3) && defined(__alpha_max__) +#define minub8 __builtin_alpha_minub8 +#define minsb8 __builtin_alpha_minsb8 +#define minuw4 __builtin_alpha_minuw4 +#define minsw4 __builtin_alpha_minsw4 +#define maxub8 __builtin_alpha_maxub8 +#define maxsb8 __builtin_alpha_maxsb8 +#define maxuw4 __builtin_alpha_maxuw4 +#define maxsw4 __builtin_alpha_maxsw4 +#define perr __builtin_alpha_perr +#define pklb __builtin_alpha_pklb +#define pkwb __builtin_alpha_pkwb +#define unpkbl __builtin_alpha_unpkbl +#define unpkbw __builtin_alpha_unpkbw +#else +#define minub8(a, b) ({ uint64_t __r; asm (".arch ev6; minub8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define minsb8(a, b) ({ uint64_t __r; asm (".arch ev6; minsb8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define minuw4(a, b) ({ uint64_t __r; asm (".arch ev6; minuw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define minsw4(a, b) ({ uint64_t __r; asm (".arch ev6; minsw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define maxub8(a, b) ({ uint64_t __r; asm (".arch ev6; maxub8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define maxsb8(a, b) ({ uint64_t __r; asm (".arch ev6; maxsb8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define maxuw4(a, b) ({ uint64_t __r; asm (".arch ev6; maxuw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define maxsw4(a, b) ({ uint64_t __r; asm (".arch ev6; maxsw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) +#define perr(a, b) ({ uint64_t __r; asm (".arch ev6; perr %r1,%r2,%0" : "=r" (__r) : "%rJ" (a), "rJ" (b)); __r; }) +#define pklb(a) ({ uint64_t __r; asm (".arch ev6; pklb %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) +#define pkwb(a) ({ uint64_t __r; asm (".arch ev6; pkwb %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) +#define unpkbl(a) ({ uint64_t __r; asm (".arch ev6; unpkbl %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) +#define unpkbw(a) ({ uint64_t __r; asm (".arch ev6; unpkbw %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) +#endif + +#elif defined(__DECC) /* Digital/Compaq/hp "ccc" compiler */ + +#include +#define ldq(p) (*(const uint64_t *) (p)) +#define ldl(p) (*(const int32_t *) (p)) +#define stq(l, p) do { *(uint64_t *) (p) = (l); } while (0) +#define stl(l, p) do { *(int32_t *) (p) = (l); } while (0) +#define ldq_u(a) asm ("ldq_u %v0,0(%a0)", a) +#define uldq(a) (*(const __unaligned uint64_t *) (a)) +#define cmpbge(a, b) asm ("cmpbge %a0,%a1,%v0", a, b) +#define extql(a, b) asm ("extql %a0,%a1,%v0", a, b) +#define extwl(a, b) asm ("extwl %a0,%a1,%v0", a, b) +#define extqh(a, b) asm ("extqh %a0,%a1,%v0", a, b) +#define zap(a, b) asm ("zap %a0,%a1,%v0", a, b) +#define zapnot(a, b) asm ("zapnot %a0,%a1,%v0", a, b) +#define amask(a) asm ("amask %a0,%v0", a) +#define implver() asm ("implver %v0") +#define rpcc() asm ("rpcc %v0") +#define minub8(a, b) asm ("minub8 %a0,%a1,%v0", a, b) +#define minsb8(a, b) asm ("minsb8 %a0,%a1,%v0", a, b) +#define minuw4(a, b) asm ("minuw4 %a0,%a1,%v0", a, b) +#define minsw4(a, b) asm ("minsw4 %a0,%a1,%v0", a, b) +#define maxub8(a, b) asm ("maxub8 %a0,%a1,%v0", a, b) +#define maxsb8(a, b) asm ("maxsb8 %a0,%a1,%v0", a, b) +#define maxuw4(a, b) asm ("maxuw4 %a0,%a1,%v0", a, b) +#define maxsw4(a, b) asm ("maxsw4 %a0,%a1,%v0", a, b) +#define perr(a, b) asm ("perr %a0,%a1,%v0", a, b) +#define pklb(a) asm ("pklb %a0,%v0", a) +#define pkwb(a) asm ("pkwb %a0,%v0", a) +#define unpkbl(a) asm ("unpkbl %a0,%v0", a) +#define unpkbw(a) asm ("unpkbw %a0,%v0", a) +#define wh64(a) asm ("wh64 %a0", a) + +#else +#error "Unknown compiler!" +#endif + +#endif /* LIBAVCODEC_ALPHA_ASM_H */ diff --git a/mpeg4/src/libavcodec/alpha/dsputil_alpha.c b/mpeg4/src/libavcodec/alpha/dsputil_alpha.c new file mode 100644 index 00000000..299a25dc --- /dev/null +++ b/mpeg4/src/libavcodec/alpha/dsputil_alpha.c @@ -0,0 +1,360 @@ +/* + * Alpha optimized DSP utils + * Copyright (c) 2002 Falk Hueffner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "asm.h" +#include "../dsputil.h" + +extern void simple_idct_axp(DCTELEM *block); +extern void simple_idct_put_axp(uint8_t *dest, int line_size, DCTELEM *block); +extern void simple_idct_add_axp(uint8_t *dest, int line_size, DCTELEM *block); + +void put_pixels_axp_asm(uint8_t *block, const uint8_t *pixels, + int line_size, int h); +void put_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels, + int line_size); +void add_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels, + int line_size); +void (*put_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels, + int line_size); +void (*add_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels, + int line_size); + +void get_pixels_mvi(DCTELEM *restrict block, + const uint8_t *restrict pixels, int line_size); +void diff_pixels_mvi(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, + int stride); +int pix_abs8x8_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h); +int pix_abs16x16_mvi_asm(uint8_t *pix1, uint8_t *pix2, int line_size); +int pix_abs16x16_x2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h); +int pix_abs16x16_y2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h); +int pix_abs16x16_xy2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h); + +#if 0 +/* These functions were the base for the optimized assembler routines, + and remain here for documentation purposes. */ +static void put_pixels_clamped_mvi(const DCTELEM *block, uint8_t *pixels, + int line_size) +{ + int i = 8; + uint64_t clampmask = zap(-1, 0xaa); /* 0x00ff00ff00ff00ff */ + + do { + uint64_t shorts0, shorts1; + + shorts0 = ldq(block); + shorts0 = maxsw4(shorts0, 0); + shorts0 = minsw4(shorts0, clampmask); + stl(pkwb(shorts0), pixels); + + shorts1 = ldq(block + 4); + shorts1 = maxsw4(shorts1, 0); + shorts1 = minsw4(shorts1, clampmask); + stl(pkwb(shorts1), pixels + 4); + + pixels += line_size; + block += 8; + } while (--i); +} + +void add_pixels_clamped_mvi(const DCTELEM *block, uint8_t *pixels, + int line_size) +{ + int h = 8; + /* Keep this function a leaf function by generating the constants + manually (mainly for the hack value ;-). */ + uint64_t clampmask = zap(-1, 0xaa); /* 0x00ff00ff00ff00ff */ + uint64_t signmask = zap(-1, 0x33); + signmask ^= signmask >> 1; /* 0x8000800080008000 */ + + do { + uint64_t shorts0, pix0, signs0; + uint64_t shorts1, pix1, signs1; + + shorts0 = ldq(block); + shorts1 = ldq(block + 4); + + pix0 = unpkbw(ldl(pixels)); + /* Signed subword add (MMX paddw). */ + signs0 = shorts0 & signmask; + shorts0 &= ~signmask; + shorts0 += pix0; + shorts0 ^= signs0; + /* Clamp. */ + shorts0 = maxsw4(shorts0, 0); + shorts0 = minsw4(shorts0, clampmask); + + /* Next 4. */ + pix1 = unpkbw(ldl(pixels + 4)); + signs1 = shorts1 & signmask; + shorts1 &= ~signmask; + shorts1 += pix1; + shorts1 ^= signs1; + shorts1 = maxsw4(shorts1, 0); + shorts1 = minsw4(shorts1, clampmask); + + stl(pkwb(shorts0), pixels); + stl(pkwb(shorts1), pixels + 4); + + pixels += line_size; + block += 8; + } while (--h); +} +#endif + +static void clear_blocks_axp(DCTELEM *blocks) { + uint64_t *p = (uint64_t *) blocks; + int n = sizeof(DCTELEM) * 6 * 64; + + do { + p[0] = 0; + p[1] = 0; + p[2] = 0; + p[3] = 0; + p[4] = 0; + p[5] = 0; + p[6] = 0; + p[7] = 0; + p += 8; + n -= 8 * 8; + } while (n); +} + +static inline uint64_t avg2_no_rnd(uint64_t a, uint64_t b) +{ + return (a & b) + (((a ^ b) & BYTE_VEC(0xfe)) >> 1); +} + +static inline uint64_t avg2(uint64_t a, uint64_t b) +{ + return (a | b) - (((a ^ b) & BYTE_VEC(0xfe)) >> 1); +} + +#if 0 +/* The XY2 routines basically utilize this scheme, but reuse parts in + each iteration. */ +static inline uint64_t avg4(uint64_t l1, uint64_t l2, uint64_t l3, uint64_t l4) +{ + uint64_t r1 = ((l1 & ~BYTE_VEC(0x03)) >> 2) + + ((l2 & ~BYTE_VEC(0x03)) >> 2) + + ((l3 & ~BYTE_VEC(0x03)) >> 2) + + ((l4 & ~BYTE_VEC(0x03)) >> 2); + uint64_t r2 = (( (l1 & BYTE_VEC(0x03)) + + (l2 & BYTE_VEC(0x03)) + + (l3 & BYTE_VEC(0x03)) + + (l4 & BYTE_VEC(0x03)) + + BYTE_VEC(0x02)) >> 2) & BYTE_VEC(0x03); + return r1 + r2; +} +#endif + +#define OP(LOAD, STORE) \ + do { \ + STORE(LOAD(pixels), block); \ + pixels += line_size; \ + block += line_size; \ + } while (--h) + +#define OP_X2(LOAD, STORE) \ + do { \ + uint64_t pix1, pix2; \ + \ + pix1 = LOAD(pixels); \ + pix2 = pix1 >> 8 | ((uint64_t) pixels[8] << 56); \ + STORE(AVG2(pix1, pix2), block); \ + pixels += line_size; \ + block += line_size; \ + } while (--h) + +#define OP_Y2(LOAD, STORE) \ + do { \ + uint64_t pix = LOAD(pixels); \ + do { \ + uint64_t next_pix; \ + \ + pixels += line_size; \ + next_pix = LOAD(pixels); \ + STORE(AVG2(pix, next_pix), block); \ + block += line_size; \ + pix = next_pix; \ + } while (--h); \ + } while (0) + +#define OP_XY2(LOAD, STORE) \ + do { \ + uint64_t pix1 = LOAD(pixels); \ + uint64_t pix2 = pix1 >> 8 | ((uint64_t) pixels[8] << 56); \ + uint64_t pix_l = (pix1 & BYTE_VEC(0x03)) \ + + (pix2 & BYTE_VEC(0x03)); \ + uint64_t pix_h = ((pix1 & ~BYTE_VEC(0x03)) >> 2) \ + + ((pix2 & ~BYTE_VEC(0x03)) >> 2); \ + \ + do { \ + uint64_t npix1, npix2; \ + uint64_t npix_l, npix_h; \ + uint64_t avg; \ + \ + pixels += line_size; \ + npix1 = LOAD(pixels); \ + npix2 = npix1 >> 8 | ((uint64_t) pixels[8] << 56); \ + npix_l = (npix1 & BYTE_VEC(0x03)) \ + + (npix2 & BYTE_VEC(0x03)); \ + npix_h = ((npix1 & ~BYTE_VEC(0x03)) >> 2) \ + + ((npix2 & ~BYTE_VEC(0x03)) >> 2); \ + avg = (((pix_l + npix_l + AVG4_ROUNDER) >> 2) & BYTE_VEC(0x03)) \ + + pix_h + npix_h; \ + STORE(avg, block); \ + \ + block += line_size; \ + pix_l = npix_l; \ + pix_h = npix_h; \ + } while (--h); \ + } while (0) + +#define MAKE_OP(OPNAME, SUFF, OPKIND, STORE) \ +static void OPNAME ## _pixels ## SUFF ## _axp \ + (uint8_t *restrict block, const uint8_t *restrict pixels, \ + int line_size, int h) \ +{ \ + if ((size_t) pixels & 0x7) { \ + OPKIND(uldq, STORE); \ + } else { \ + OPKIND(ldq, STORE); \ + } \ +} \ + \ +static void OPNAME ## _pixels16 ## SUFF ## _axp \ + (uint8_t *restrict block, const uint8_t *restrict pixels, \ + int line_size, int h) \ +{ \ + OPNAME ## _pixels ## SUFF ## _axp(block, pixels, line_size, h); \ + OPNAME ## _pixels ## SUFF ## _axp(block + 8, pixels + 8, line_size, h); \ +} + +#define PIXOP(OPNAME, STORE) \ + MAKE_OP(OPNAME, , OP, STORE) \ + MAKE_OP(OPNAME, _x2, OP_X2, STORE) \ + MAKE_OP(OPNAME, _y2, OP_Y2, STORE) \ + MAKE_OP(OPNAME, _xy2, OP_XY2, STORE) + +/* Rounding primitives. */ +#define AVG2 avg2 +#define AVG4 avg4 +#define AVG4_ROUNDER BYTE_VEC(0x02) +#define STORE(l, b) stq(l, b) +PIXOP(put, STORE); + +#undef STORE +#define STORE(l, b) stq(AVG2(l, ldq(b)), b); +PIXOP(avg, STORE); + +/* Not rounding primitives. */ +#undef AVG2 +#undef AVG4 +#undef AVG4_ROUNDER +#undef STORE +#define AVG2 avg2_no_rnd +#define AVG4 avg4_no_rnd +#define AVG4_ROUNDER BYTE_VEC(0x01) +#define STORE(l, b) stq(l, b) +PIXOP(put_no_rnd, STORE); + +#undef STORE +#define STORE(l, b) stq(AVG2(l, ldq(b)), b); +PIXOP(avg_no_rnd, STORE); + +void put_pixels16_axp_asm(uint8_t *block, const uint8_t *pixels, + int line_size, int h) +{ + put_pixels_axp_asm(block, pixels, line_size, h); + put_pixels_axp_asm(block + 8, pixels + 8, line_size, h); +} + +static int sad16x16_mvi(void *s, uint8_t *a, uint8_t *b, int stride) +{ + return pix_abs16x16_mvi_asm(a, b, stride); +} + +void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx) +{ + c->put_pixels_tab[0][0] = put_pixels16_axp_asm; + c->put_pixels_tab[0][1] = put_pixels16_x2_axp; + c->put_pixels_tab[0][2] = put_pixels16_y2_axp; + c->put_pixels_tab[0][3] = put_pixels16_xy2_axp; + + c->put_no_rnd_pixels_tab[0][0] = put_pixels16_axp_asm; + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_axp; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_axp; + c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_axp; + + c->avg_pixels_tab[0][0] = avg_pixels16_axp; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_axp; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_axp; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_axp; + + c->avg_no_rnd_pixels_tab[0][0] = avg_no_rnd_pixels16_axp; + c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x2_axp; + c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y2_axp; + c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy2_axp; + + c->put_pixels_tab[1][0] = put_pixels_axp_asm; + c->put_pixels_tab[1][1] = put_pixels_x2_axp; + c->put_pixels_tab[1][2] = put_pixels_y2_axp; + c->put_pixels_tab[1][3] = put_pixels_xy2_axp; + + c->put_no_rnd_pixels_tab[1][0] = put_pixels_axp_asm; + c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels_x2_axp; + c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels_y2_axp; + c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels_xy2_axp; + + c->avg_pixels_tab[1][0] = avg_pixels_axp; + c->avg_pixels_tab[1][1] = avg_pixels_x2_axp; + c->avg_pixels_tab[1][2] = avg_pixels_y2_axp; + c->avg_pixels_tab[1][3] = avg_pixels_xy2_axp; + + c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels_axp; + c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels_x2_axp; + c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels_y2_axp; + c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels_xy2_axp; + + c->clear_blocks = clear_blocks_axp; + + /* amask clears all bits that correspond to present features. */ + if (amask(AMASK_MVI) == 0) { + c->put_pixels_clamped = put_pixels_clamped_mvi_asm; + c->add_pixels_clamped = add_pixels_clamped_mvi_asm; + + c->get_pixels = get_pixels_mvi; + c->diff_pixels = diff_pixels_mvi; + c->sad[0] = sad16x16_mvi; + c->sad[1] = pix_abs8x8_mvi; +// c->pix_abs[0][0] = pix_abs16x16_mvi_asm; //FIXME function arguments for the asm must be fixed + c->pix_abs[0][0] = sad16x16_mvi; + c->pix_abs[1][0] = pix_abs8x8_mvi; + c->pix_abs[0][1] = pix_abs16x16_x2_mvi; + c->pix_abs[0][2] = pix_abs16x16_y2_mvi; + c->pix_abs[0][3] = pix_abs16x16_xy2_mvi; + } + + put_pixels_clamped_axp_p = c->put_pixels_clamped; + add_pixels_clamped_axp_p = c->add_pixels_clamped; + + c->idct_put = simple_idct_put_axp; + c->idct_add = simple_idct_add_axp; + c->idct = simple_idct_axp; +} diff --git a/mpeg4/src/libavcodec/alpha/dsputil_alpha_asm.S b/mpeg4/src/libavcodec/alpha/dsputil_alpha_asm.S new file mode 100644 index 00000000..29ba9dc0 --- /dev/null +++ b/mpeg4/src/libavcodec/alpha/dsputil_alpha_asm.S @@ -0,0 +1,283 @@ +/* + * Alpha optimized DSP utils + * Copyright (c) 2002 Falk Hueffner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * These functions are scheduled for pca56. They should work + * reasonably on ev6, though. + */ + +#include "regdef.h" + +/* Some nicer register names. */ +#define ta t10 +#define tb t11 +#define tc t12 +#define td AT +/* Danger: these overlap with the argument list and the return value */ +#define te a5 +#define tf a4 +#define tg a3 +#define th v0 + + .set noat + .set noreorder + .arch pca56 + .text + +/************************************************************************ + * void put_pixels_axp_asm(uint8_t *block, const uint8_t *pixels, + * int line_size, int h) + */ + .align 6 + .globl put_pixels_axp_asm + .ent put_pixels_axp_asm +put_pixels_axp_asm: + .frame sp, 0, ra + .prologue 0 + +#ifdef HAVE_GPROF + lda AT, _mcount + jsr AT, (AT), _mcount +#endif + + and a1, 7, t0 + beq t0, $aligned + + .align 4 +$unaligned: + ldq_u t0, 0(a1) + ldq_u t1, 8(a1) + addq a1, a2, a1 + nop + + ldq_u t2, 0(a1) + ldq_u t3, 8(a1) + addq a1, a2, a1 + nop + + ldq_u t4, 0(a1) + ldq_u t5, 8(a1) + addq a1, a2, a1 + nop + + ldq_u t6, 0(a1) + ldq_u t7, 8(a1) + extql t0, a1, t0 + addq a1, a2, a1 + + extqh t1, a1, t1 + addq a0, a2, t8 + extql t2, a1, t2 + addq t8, a2, t9 + + extqh t3, a1, t3 + addq t9, a2, ta + extql t4, a1, t4 + or t0, t1, t0 + + extqh t5, a1, t5 + or t2, t3, t2 + extql t6, a1, t6 + or t4, t5, t4 + + extqh t7, a1, t7 + or t6, t7, t6 + stq t0, 0(a0) + stq t2, 0(t8) + + stq t4, 0(t9) + subq a3, 4, a3 + stq t6, 0(ta) + addq ta, a2, a0 + + bne a3, $unaligned + ret + + .align 4 +$aligned: + ldq t0, 0(a1) + addq a1, a2, a1 + ldq t1, 0(a1) + addq a1, a2, a1 + + ldq t2, 0(a1) + addq a1, a2, a1 + ldq t3, 0(a1) + + addq a0, a2, t4 + addq a1, a2, a1 + addq t4, a2, t5 + subq a3, 4, a3 + + stq t0, 0(a0) + addq t5, a2, t6 + stq t1, 0(t4) + addq t6, a2, a0 + + stq t2, 0(t5) + stq t3, 0(t6) + + bne a3, $aligned + ret + .end put_pixels_axp_asm + +/************************************************************************ + * void put_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels, + * int line_size) + */ + .align 6 + .globl put_pixels_clamped_mvi_asm + .ent put_pixels_clamped_mvi_asm +put_pixels_clamped_mvi_asm: + .frame sp, 0, ra + .prologue 0 + +#ifdef HAVE_GPROF + lda AT, _mcount + jsr AT, (AT), _mcount +#endif + + lda t8, -1 + lda t9, 8 # loop counter + zap t8, 0xaa, t8 # 00ff00ff00ff00ff + + .align 4 +1: ldq t0, 0(a0) + ldq t1, 8(a0) + ldq t2, 16(a0) + ldq t3, 24(a0) + + maxsw4 t0, zero, t0 + subq t9, 2, t9 + maxsw4 t1, zero, t1 + lda a0, 32(a0) + + maxsw4 t2, zero, t2 + addq a1, a2, ta + maxsw4 t3, zero, t3 + minsw4 t0, t8, t0 + + minsw4 t1, t8, t1 + minsw4 t2, t8, t2 + minsw4 t3, t8, t3 + pkwb t0, t0 + + pkwb t1, t1 + pkwb t2, t2 + pkwb t3, t3 + stl t0, 0(a1) + + stl t1, 4(a1) + addq ta, a2, a1 + stl t2, 0(ta) + stl t3, 4(ta) + + bne t9, 1b + ret + .end put_pixels_clamped_mvi_asm + +/************************************************************************ + * void add_pixels_clamped_mvi_asm(const DCTELEM *block, uint8_t *pixels, + * int line_size) + */ + .align 6 + .globl add_pixels_clamped_mvi_asm + .ent add_pixels_clamped_mvi_asm +add_pixels_clamped_mvi_asm: + .frame sp, 0, ra + .prologue 0 + +#ifdef HAVE_GPROF + lda AT, _mcount + jsr AT, (AT), _mcount +#endif + + lda t1, -1 + lda th, 8 + zap t1, 0x33, tg + nop + + srl tg, 1, t0 + xor tg, t0, tg # 0x8000800080008000 + zap t1, 0xaa, tf # 0x00ff00ff00ff00ff + + .align 4 +1: ldl t1, 0(a1) # pix0 (try to hit cache line soon) + ldl t4, 4(a1) # pix1 + addq a1, a2, te # pixels += line_size + ldq t0, 0(a0) # shorts0 + + ldl t7, 0(te) # pix2 (try to hit cache line soon) + ldl ta, 4(te) # pix3 + ldq t3, 8(a0) # shorts1 + ldq t6, 16(a0) # shorts2 + + ldq t9, 24(a0) # shorts3 + unpkbw t1, t1 # 0 0 (quarter/op no.) + and t0, tg, t2 # 0 1 + unpkbw t4, t4 # 1 0 + + bic t0, tg, t0 # 0 2 + unpkbw t7, t7 # 2 0 + and t3, tg, t5 # 1 1 + addq t0, t1, t0 # 0 3 + + xor t0, t2, t0 # 0 4 + unpkbw ta, ta # 3 0 + and t6, tg, t8 # 2 1 + maxsw4 t0, zero, t0 # 0 5 + + bic t3, tg, t3 # 1 2 + bic t6, tg, t6 # 2 2 + minsw4 t0, tf, t0 # 0 6 + addq t3, t4, t3 # 1 3 + + pkwb t0, t0 # 0 7 + xor t3, t5, t3 # 1 4 + maxsw4 t3, zero, t3 # 1 5 + addq t6, t7, t6 # 2 3 + + xor t6, t8, t6 # 2 4 + and t9, tg, tb # 3 1 + minsw4 t3, tf, t3 # 1 6 + bic t9, tg, t9 # 3 2 + + maxsw4 t6, zero, t6 # 2 5 + addq t9, ta, t9 # 3 3 + stl t0, 0(a1) # 0 8 + minsw4 t6, tf, t6 # 2 6 + + xor t9, tb, t9 # 3 4 + maxsw4 t9, zero, t9 # 3 5 + lda a0, 32(a0) # block += 16; + pkwb t3, t3 # 1 7 + + minsw4 t9, tf, t9 # 3 6 + subq th, 2, th + pkwb t6, t6 # 2 7 + pkwb t9, t9 # 3 7 + + stl t3, 4(a1) # 1 8 + addq te, a2, a1 # pixels += line_size + stl t6, 0(te) # 2 8 + stl t9, 4(te) # 3 8 + + bne th, 1b + ret + .end add_pixels_clamped_mvi_asm diff --git a/mpeg4/src/libavcodec/alpha/motion_est_alpha.c b/mpeg4/src/libavcodec/alpha/motion_est_alpha.c new file mode 100644 index 00000000..ea8580be --- /dev/null +++ b/mpeg4/src/libavcodec/alpha/motion_est_alpha.c @@ -0,0 +1,343 @@ +/* + * Alpha optimized DSP utils + * Copyright (c) 2002 Falk Hueffner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "asm.h" +#include "../dsputil.h" + +void get_pixels_mvi(DCTELEM *restrict block, + const uint8_t *restrict pixels, int line_size) +{ + int h = 8; + + do { + uint64_t p; + + p = ldq(pixels); + stq(unpkbw(p), block); + stq(unpkbw(p >> 32), block + 4); + + pixels += line_size; + block += 8; + } while (--h); +} + +void diff_pixels_mvi(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, + int stride) { + int h = 8; + uint64_t mask = 0x4040; + + mask |= mask << 16; + mask |= mask << 32; + do { + uint64_t x, y, c, d, a; + uint64_t signs; + + x = ldq(s1); + y = ldq(s2); + c = cmpbge(x, y); + d = x - y; + a = zap(mask, c); /* We use 0x4040404040404040 here... */ + d += 4 * a; /* ...so we can use s4addq here. */ + signs = zap(-1, c); + + stq(unpkbw(d) | (unpkbw(signs) << 8), block); + stq(unpkbw(d >> 32) | (unpkbw(signs >> 32) << 8), block + 4); + + s1 += stride; + s2 += stride; + block += 8; + } while (--h); +} + +static inline uint64_t avg2(uint64_t a, uint64_t b) +{ + return (a | b) - (((a ^ b) & BYTE_VEC(0xfe)) >> 1); +} + +static inline uint64_t avg4(uint64_t l1, uint64_t l2, uint64_t l3, uint64_t l4) +{ + uint64_t r1 = ((l1 & ~BYTE_VEC(0x03)) >> 2) + + ((l2 & ~BYTE_VEC(0x03)) >> 2) + + ((l3 & ~BYTE_VEC(0x03)) >> 2) + + ((l4 & ~BYTE_VEC(0x03)) >> 2); + uint64_t r2 = (( (l1 & BYTE_VEC(0x03)) + + (l2 & BYTE_VEC(0x03)) + + (l3 & BYTE_VEC(0x03)) + + (l4 & BYTE_VEC(0x03)) + + BYTE_VEC(0x02)) >> 2) & BYTE_VEC(0x03); + return r1 + r2; +} + +int pix_abs8x8_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) +{ + int result = 0; + + if ((size_t) pix2 & 0x7) { + /* works only when pix2 is actually unaligned */ + do { /* do 8 pixel a time */ + uint64_t p1, p2; + + p1 = ldq(pix1); + p2 = uldq(pix2); + result += perr(p1, p2); + + pix1 += line_size; + pix2 += line_size; + } while (--h); + } else { + do { + uint64_t p1, p2; + + p1 = ldq(pix1); + p2 = ldq(pix2); + result += perr(p1, p2); + + pix1 += line_size; + pix2 += line_size; + } while (--h); + } + + return result; +} + +#if 0 /* now done in assembly */ +int pix_abs16x16_mvi(uint8_t *pix1, uint8_t *pix2, int line_size) +{ + int result = 0; + int h = 16; + + if ((size_t) pix2 & 0x7) { + /* works only when pix2 is actually unaligned */ + do { /* do 16 pixel a time */ + uint64_t p1_l, p1_r, p2_l, p2_r; + uint64_t t; + + p1_l = ldq(pix1); + p1_r = ldq(pix1 + 8); + t = ldq_u(pix2 + 8); + p2_l = extql(ldq_u(pix2), pix2) | extqh(t, pix2); + p2_r = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2); + pix1 += line_size; + pix2 += line_size; + + result += perr(p1_l, p2_l) + + perr(p1_r, p2_r); + } while (--h); + } else { + do { + uint64_t p1_l, p1_r, p2_l, p2_r; + + p1_l = ldq(pix1); + p1_r = ldq(pix1 + 8); + p2_l = ldq(pix2); + p2_r = ldq(pix2 + 8); + pix1 += line_size; + pix2 += line_size; + + result += perr(p1_l, p2_l) + + perr(p1_r, p2_r); + } while (--h); + } + + return result; +} +#endif + +int pix_abs16x16_x2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) +{ + int result = 0; + uint64_t disalign = (size_t) pix2 & 0x7; + + switch (disalign) { + case 0: + do { + uint64_t p1_l, p1_r, p2_l, p2_r; + uint64_t l, r; + + p1_l = ldq(pix1); + p1_r = ldq(pix1 + 8); + l = ldq(pix2); + r = ldq(pix2 + 8); + p2_l = avg2(l, (l >> 8) | ((uint64_t) r << 56)); + p2_r = avg2(r, (r >> 8) | ((uint64_t) pix2[16] << 56)); + pix1 += line_size; + pix2 += line_size; + + result += perr(p1_l, p2_l) + + perr(p1_r, p2_r); + } while (--h); + break; + case 7: + /* |.......l|lllllllr|rrrrrrr*| + This case is special because disalign1 would be 8, which + gets treated as 0 by extqh. At least it is a bit faster + that way :) */ + do { + uint64_t p1_l, p1_r, p2_l, p2_r; + uint64_t l, m, r; + + p1_l = ldq(pix1); + p1_r = ldq(pix1 + 8); + l = ldq_u(pix2); + m = ldq_u(pix2 + 8); + r = ldq_u(pix2 + 16); + p2_l = avg2(extql(l, disalign) | extqh(m, disalign), m); + p2_r = avg2(extql(m, disalign) | extqh(r, disalign), r); + pix1 += line_size; + pix2 += line_size; + + result += perr(p1_l, p2_l) + + perr(p1_r, p2_r); + } while (--h); + break; + default: + do { + uint64_t disalign1 = disalign + 1; + uint64_t p1_l, p1_r, p2_l, p2_r; + uint64_t l, m, r; + + p1_l = ldq(pix1); + p1_r = ldq(pix1 + 8); + l = ldq_u(pix2); + m = ldq_u(pix2 + 8); + r = ldq_u(pix2 + 16); + p2_l = avg2(extql(l, disalign) | extqh(m, disalign), + extql(l, disalign1) | extqh(m, disalign1)); + p2_r = avg2(extql(m, disalign) | extqh(r, disalign), + extql(m, disalign1) | extqh(r, disalign1)); + pix1 += line_size; + pix2 += line_size; + + result += perr(p1_l, p2_l) + + perr(p1_r, p2_r); + } while (--h); + break; + } + return result; +} + +int pix_abs16x16_y2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) +{ + int result = 0; + + if ((size_t) pix2 & 0x7) { + uint64_t t, p2_l, p2_r; + t = ldq_u(pix2 + 8); + p2_l = extql(ldq_u(pix2), pix2) | extqh(t, pix2); + p2_r = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2); + + do { + uint64_t p1_l, p1_r, np2_l, np2_r; + uint64_t t; + + p1_l = ldq(pix1); + p1_r = ldq(pix1 + 8); + pix2 += line_size; + t = ldq_u(pix2 + 8); + np2_l = extql(ldq_u(pix2), pix2) | extqh(t, pix2); + np2_r = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2); + + result += perr(p1_l, avg2(p2_l, np2_l)) + + perr(p1_r, avg2(p2_r, np2_r)); + + pix1 += line_size; + p2_l = np2_l; + p2_r = np2_r; + + } while (--h); + } else { + uint64_t p2_l, p2_r; + p2_l = ldq(pix2); + p2_r = ldq(pix2 + 8); + do { + uint64_t p1_l, p1_r, np2_l, np2_r; + + p1_l = ldq(pix1); + p1_r = ldq(pix1 + 8); + pix2 += line_size; + np2_l = ldq(pix2); + np2_r = ldq(pix2 + 8); + + result += perr(p1_l, avg2(p2_l, np2_l)) + + perr(p1_r, avg2(p2_r, np2_r)); + + pix1 += line_size; + p2_l = np2_l; + p2_r = np2_r; + } while (--h); + } + return result; +} + +int pix_abs16x16_xy2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) +{ + int result = 0; + + uint64_t p1_l, p1_r; + uint64_t p2_l, p2_r, p2_x; + + p1_l = ldq(pix1); + p1_r = ldq(pix1 + 8); + + if ((size_t) pix2 & 0x7) { /* could be optimized a lot */ + p2_l = uldq(pix2); + p2_r = uldq(pix2 + 8); + p2_x = (uint64_t) pix2[16] << 56; + } else { + p2_l = ldq(pix2); + p2_r = ldq(pix2 + 8); + p2_x = ldq(pix2 + 16) << 56; + } + + do { + uint64_t np1_l, np1_r; + uint64_t np2_l, np2_r, np2_x; + + pix1 += line_size; + pix2 += line_size; + + np1_l = ldq(pix1); + np1_r = ldq(pix1 + 8); + + if ((size_t) pix2 & 0x7) { /* could be optimized a lot */ + np2_l = uldq(pix2); + np2_r = uldq(pix2 + 8); + np2_x = (uint64_t) pix2[16] << 56; + } else { + np2_l = ldq(pix2); + np2_r = ldq(pix2 + 8); + np2_x = ldq(pix2 + 16) << 56; + } + + result += perr(p1_l, + avg4( p2_l, ( p2_l >> 8) | ((uint64_t) p2_r << 56), + np2_l, (np2_l >> 8) | ((uint64_t) np2_r << 56))) + + perr(p1_r, + avg4( p2_r, ( p2_r >> 8) | ((uint64_t) p2_x), + np2_r, (np2_r >> 8) | ((uint64_t) np2_x))); + + p1_l = np1_l; + p1_r = np1_r; + p2_l = np2_l; + p2_r = np2_r; + p2_x = np2_x; + } while (--h); + + return result; +} diff --git a/mpeg4/src/libavcodec/alpha/motion_est_mvi_asm.S b/mpeg4/src/libavcodec/alpha/motion_est_mvi_asm.S new file mode 100644 index 00000000..e043f437 --- /dev/null +++ b/mpeg4/src/libavcodec/alpha/motion_est_mvi_asm.S @@ -0,0 +1,183 @@ +/* + * Alpha optimized DSP utils + * Copyright (c) 2002 Falk Hueffner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "regdef.h" + +/* Some nicer register names. */ +#define ta t10 +#define tb t11 +#define tc t12 +#define td AT +/* Danger: these overlap with the argument list and the return value */ +#define te a5 +#define tf a4 +#define tg a3 +#define th v0 + + .set noat + .set noreorder + .arch pca56 + .text + +/***************************************************************************** + * int pix_abs16x16_mvi_asm(uint8_t *pix1, uint8_t *pix2, int line_size) + * + * This code is written with a pca56 in mind. For ev6, one should + * really take the increased latency of 3 cycles for MVI instructions + * into account. + * + * It is important to keep the loading and first use of a register as + * far apart as possible, because if a register is accessed before it + * has been fetched from memory, the CPU will stall. + */ + .align 4 + .globl pix_abs16x16_mvi_asm + .ent pix_abs16x16_mvi_asm +pix_abs16x16_mvi_asm: + .frame sp, 0, ra, 0 + .prologue 0 + +#ifdef HAVE_GPROF + lda AT, _mcount + jsr AT, (AT), _mcount +#endif + + and a1, 7, t0 + clr v0 + lda a3, 16 + beq t0, $aligned + .align 4 +$unaligned: + /* Registers: + line 0: + t0: left_u -> left lo -> left + t1: mid + t2: right_u -> right hi -> right + t3: ref left + t4: ref right + line 1: + t5: left_u -> left lo -> left + t6: mid + t7: right_u -> right hi -> right + t8: ref left + t9: ref right + temp: + ta: left hi + tb: right lo + tc: error left + td: error right */ + + /* load line 0 */ + ldq_u t0, 0(a1) # left_u + ldq_u t1, 8(a1) # mid + ldq_u t2, 16(a1) # right_u + ldq t3, 0(a0) # ref left + ldq t4, 8(a0) # ref right + addq a0, a2, a0 # pix1 + addq a1, a2, a1 # pix2 + /* load line 1 */ + ldq_u t5, 0(a1) # left_u + ldq_u t6, 8(a1) # mid + ldq_u t7, 16(a1) # right_u + ldq t8, 0(a0) # ref left + ldq t9, 8(a0) # ref right + addq a0, a2, a0 # pix1 + addq a1, a2, a1 # pix2 + /* calc line 0 */ + extql t0, a1, t0 # left lo + extqh t1, a1, ta # left hi + extql t1, a1, tb # right lo + or t0, ta, t0 # left + extqh t2, a1, t2 # right hi + perr t3, t0, tc # error left + or t2, tb, t2 # right + perr t4, t2, td # error right + addq v0, tc, v0 # add error left + addq v0, td, v0 # add error left + /* calc line 1 */ + extql t5, a1, t5 # left lo + extqh t6, a1, ta # left hi + extql t6, a1, tb # right lo + or t5, ta, t5 # left + extqh t7, a1, t7 # right hi + perr t8, t5, tc # error left + or t7, tb, t7 # right + perr t9, t7, td # error right + addq v0, tc, v0 # add error left + addq v0, td, v0 # add error left + /* loop */ + subq a3, 2, a3 # h -= 2 + bne a3, $unaligned + ret + + .align 4 +$aligned: + /* load line 0 */ + ldq t0, 0(a1) # left + ldq t1, 8(a1) # right + addq a1, a2, a1 # pix2 + ldq t2, 0(a0) # ref left + ldq t3, 8(a0) # ref right + addq a0, a2, a0 # pix1 + /* load line 1 */ + ldq t4, 0(a1) # left + ldq t5, 8(a1) # right + addq a1, a2, a1 # pix2 + ldq t6, 0(a0) # ref left + ldq t7, 8(a0) # ref right + addq a0, a2, a0 # pix1 + /* load line 2 */ + ldq t8, 0(a1) # left + ldq t9, 8(a1) # right + addq a1, a2, a1 # pix2 + ldq ta, 0(a0) # ref left + ldq tb, 8(a0) # ref right + addq a0, a2, a0 # pix1 + /* load line 3 */ + ldq tc, 0(a1) # left + ldq td, 8(a1) # right + addq a1, a2, a1 # pix2 + ldq te, 0(a0) # ref left + ldq tf, 8(a0) # ref right + /* calc line 0 */ + perr t0, t2, t0 # error left + addq a0, a2, a0 # pix1 + perr t1, t3, t1 # error right + addq v0, t0, v0 # add error left + /* calc line 1 */ + perr t4, t6, t0 # error left + addq v0, t1, v0 # add error right + perr t5, t7, t1 # error right + addq v0, t0, v0 # add error left + /* calc line 2 */ + perr t8, ta, t0 # error left + addq v0, t1, v0 # add error right + perr t9, tb, t1 # error right + addq v0, t0, v0 # add error left + /* calc line 3 */ + perr tc, te, t0 # error left + addq v0, t1, v0 # add error right + perr td, tf, t1 # error right + addq v0, t0, v0 # add error left + addq v0, t1, v0 # add error right + /* loop */ + subq a3, 4, a3 # h -= 4 + bne a3, $aligned + ret + .end pix_abs16x16_mvi_asm diff --git a/mpeg4/src/libavcodec/alpha/mpegvideo_alpha.c b/mpeg4/src/libavcodec/alpha/mpegvideo_alpha.c new file mode 100644 index 00000000..4c512451 --- /dev/null +++ b/mpeg4/src/libavcodec/alpha/mpegvideo_alpha.c @@ -0,0 +1,145 @@ +/* + * Alpha optimized DSP utils + * Copyright (c) 2002 Falk Hueffner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "asm.h" +#include "../dsputil.h" +#include "../mpegvideo.h" + +static void dct_unquantize_h263_intra_axp(MpegEncContext *s, DCTELEM *block, + int n, int qscale) +{ + int i, n_coeffs; + uint64_t qmul, qadd; + uint64_t correction; + DCTELEM *orig_block = block; + DCTELEM block0; /* might not be used uninitialized */ + + qadd = WORD_VEC((qscale - 1) | 1); + qmul = qscale << 1; + /* This mask kills spill from negative subwords to the next subword. */ + correction = WORD_VEC((qmul - 1) + 1); /* multiplication / addition */ + + if (!s->h263_aic) { + if (n < 4) + block0 = block[0] * s->y_dc_scale; + else + block0 = block[0] * s->c_dc_scale; + } else { + qadd = 0; + } + n_coeffs = 63; // does not always use zigzag table + + for(i = 0; i <= n_coeffs; block += 4, i += 4) { + uint64_t levels, negmask, zeros, add; + + levels = ldq(block); + if (levels == 0) + continue; + +#ifdef __alpha_max__ + /* I don't think the speed difference justifies runtime + detection. */ + negmask = maxsw4(levels, -1); /* negative -> ffff (-1) */ + negmask = minsw4(negmask, 0); /* positive -> 0000 (0) */ +#else + negmask = cmpbge(WORD_VEC(0x7fff), levels); + negmask &= (negmask >> 1) | (1 << 7); + negmask = zap(-1, negmask); +#endif + + zeros = cmpbge(0, levels); + zeros &= zeros >> 1; + /* zeros |= zeros << 1 is not needed since qadd <= 255, so + zapping the lower byte suffices. */ + + levels *= qmul; + levels -= correction & (negmask << 16); + + /* Negate qadd for negative levels. */ + add = qadd ^ negmask; + add += WORD_VEC(0x0001) & negmask; + /* Set qadd to 0 for levels == 0. */ + add = zap(add, zeros); + + levels += add; + + stq(levels, block); + } + + if (s->mb_intra && !s->h263_aic) + orig_block[0] = block0; +} + +static void dct_unquantize_h263_inter_axp(MpegEncContext *s, DCTELEM *block, + int n, int qscale) +{ + int i, n_coeffs; + uint64_t qmul, qadd; + uint64_t correction; + + qadd = WORD_VEC((qscale - 1) | 1); + qmul = qscale << 1; + /* This mask kills spill from negative subwords to the next subword. */ + correction = WORD_VEC((qmul - 1) + 1); /* multiplication / addition */ + + n_coeffs = s->intra_scantable.raster_end[s->block_last_index[n]]; + + for(i = 0; i <= n_coeffs; block += 4, i += 4) { + uint64_t levels, negmask, zeros, add; + + levels = ldq(block); + if (levels == 0) + continue; + +#ifdef __alpha_max__ + /* I don't think the speed difference justifies runtime + detection. */ + negmask = maxsw4(levels, -1); /* negative -> ffff (-1) */ + negmask = minsw4(negmask, 0); /* positive -> 0000 (0) */ +#else + negmask = cmpbge(WORD_VEC(0x7fff), levels); + negmask &= (negmask >> 1) | (1 << 7); + negmask = zap(-1, negmask); +#endif + + zeros = cmpbge(0, levels); + zeros &= zeros >> 1; + /* zeros |= zeros << 1 is not needed since qadd <= 255, so + zapping the lower byte suffices. */ + + levels *= qmul; + levels -= correction & (negmask << 16); + + /* Negate qadd for negative levels. */ + add = qadd ^ negmask; + add += WORD_VEC(0x0001) & negmask; + /* Set qadd to 0 for levels == 0. */ + add = zap(add, zeros); + + levels += add; + + stq(levels, block); + } +} + +void MPV_common_init_axp(MpegEncContext *s) +{ + s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_axp; + s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_axp; +} diff --git a/mpeg4/src/libavcodec/alpha/regdef.h b/mpeg4/src/libavcodec/alpha/regdef.h new file mode 100644 index 00000000..7e7fc06b --- /dev/null +++ b/mpeg4/src/libavcodec/alpha/regdef.h @@ -0,0 +1,45 @@ +/* Some BSDs don't seem to have regdef.h... sigh */ +#ifndef alpha_regdef_h +#define alpha_regdef_h + +#define v0 $0 /* function return value */ + +#define t0 $1 /* temporary registers (caller-saved) */ +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define t4 $5 +#define t5 $6 +#define t6 $7 +#define t7 $8 + +#define s0 $9 /* saved-registers (callee-saved registers) */ +#define s1 $10 +#define s2 $11 +#define s3 $12 +#define s4 $13 +#define s5 $14 +#define s6 $15 +#define fp s6 /* frame-pointer (s6 in frame-less procedures) */ + +#define a0 $16 /* argument registers (caller-saved) */ +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 + +#define t8 $22 /* more temps (caller-saved) */ +#define t9 $23 +#define t10 $24 +#define t11 $25 +#define ra $26 /* return address register */ +#define t12 $27 + +#define pv t12 /* procedure-variable register */ +#define AT $at /* assembler temporary */ +#define gp $29 /* global pointer */ +#define sp $30 /* stack pointer */ +#define zero $31 /* reads as zero, writes are noops */ + +#endif /* alpha_regdef_h */ diff --git a/mpeg4/src/libavcodec/alpha/simple_idct_alpha.c b/mpeg4/src/libavcodec/alpha/simple_idct_alpha.c new file mode 100644 index 00000000..3a5db009 --- /dev/null +++ b/mpeg4/src/libavcodec/alpha/simple_idct_alpha.c @@ -0,0 +1,306 @@ +/* + * Simple IDCT (Alpha optimized) + * + * Copyright (c) 2001 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * based upon some outcommented c code from mpeg2dec (idct_mmx.c + * written by Aaron Holtzman ) + * + * Alpha optimiziations by Måns Rullgård + * and Falk Hueffner + */ + +#include "asm.h" +#include "../dsputil.h" + +extern void (*put_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels, + int line_size); +extern void (*add_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels, + int line_size); + +// cos(i * M_PI / 16) * sqrt(2) * (1 << 14) +// W4 is actually exactly 16384, but using 16383 works around +// accumulating rounding errors for some encoders +#define W1 ((int_fast32_t) 22725) +#define W2 ((int_fast32_t) 21407) +#define W3 ((int_fast32_t) 19266) +#define W4 ((int_fast32_t) 16383) +#define W5 ((int_fast32_t) 12873) +#define W6 ((int_fast32_t) 8867) +#define W7 ((int_fast32_t) 4520) +#define ROW_SHIFT 11 +#define COL_SHIFT 20 + +/* 0: all entries 0, 1: only first entry nonzero, 2: otherwise */ +static inline int idct_row(DCTELEM *row) +{ + int_fast32_t a0, a1, a2, a3, b0, b1, b2, b3, t; + uint64_t l, r, t2; + l = ldq(row); + r = ldq(row + 4); + + if (l == 0 && r == 0) + return 0; + + a0 = W4 * sextw(l) + (1 << (ROW_SHIFT - 1)); + + if (((l & ~0xffffUL) | r) == 0) { + a0 >>= ROW_SHIFT; + t2 = (uint16_t) a0; + t2 |= t2 << 16; + t2 |= t2 << 32; + + stq(t2, row); + stq(t2, row + 4); + return 1; + } + + a1 = a0; + a2 = a0; + a3 = a0; + + t = extwl(l, 4); /* row[2] */ + if (t != 0) { + t = sextw(t); + a0 += W2 * t; + a1 += W6 * t; + a2 -= W6 * t; + a3 -= W2 * t; + } + + t = extwl(r, 0); /* row[4] */ + if (t != 0) { + t = sextw(t); + a0 += W4 * t; + a1 -= W4 * t; + a2 -= W4 * t; + a3 += W4 * t; + } + + t = extwl(r, 4); /* row[6] */ + if (t != 0) { + t = sextw(t); + a0 += W6 * t; + a1 -= W2 * t; + a2 += W2 * t; + a3 -= W6 * t; + } + + t = extwl(l, 2); /* row[1] */ + if (t != 0) { + t = sextw(t); + b0 = W1 * t; + b1 = W3 * t; + b2 = W5 * t; + b3 = W7 * t; + } else { + b0 = 0; + b1 = 0; + b2 = 0; + b3 = 0; + } + + t = extwl(l, 6); /* row[3] */ + if (t) { + t = sextw(t); + b0 += W3 * t; + b1 -= W7 * t; + b2 -= W1 * t; + b3 -= W5 * t; + } + + + t = extwl(r, 2); /* row[5] */ + if (t) { + t = sextw(t); + b0 += W5 * t; + b1 -= W1 * t; + b2 += W7 * t; + b3 += W3 * t; + } + + t = extwl(r, 6); /* row[7] */ + if (t) { + t = sextw(t); + b0 += W7 * t; + b1 -= W5 * t; + b2 += W3 * t; + b3 -= W1 * t; + } + + row[0] = (a0 + b0) >> ROW_SHIFT; + row[1] = (a1 + b1) >> ROW_SHIFT; + row[2] = (a2 + b2) >> ROW_SHIFT; + row[3] = (a3 + b3) >> ROW_SHIFT; + row[4] = (a3 - b3) >> ROW_SHIFT; + row[5] = (a2 - b2) >> ROW_SHIFT; + row[6] = (a1 - b1) >> ROW_SHIFT; + row[7] = (a0 - b0) >> ROW_SHIFT; + + return 2; +} + +static inline void idct_col(DCTELEM *col) +{ + int_fast32_t a0, a1, a2, a3, b0, b1, b2, b3; + + col[0] += (1 << (COL_SHIFT - 1)) / W4; + + a0 = W4 * col[8 * 0]; + a1 = W4 * col[8 * 0]; + a2 = W4 * col[8 * 0]; + a3 = W4 * col[8 * 0]; + + if (col[8 * 2]) { + a0 += W2 * col[8 * 2]; + a1 += W6 * col[8 * 2]; + a2 -= W6 * col[8 * 2]; + a3 -= W2 * col[8 * 2]; + } + + if (col[8 * 4]) { + a0 += W4 * col[8 * 4]; + a1 -= W4 * col[8 * 4]; + a2 -= W4 * col[8 * 4]; + a3 += W4 * col[8 * 4]; + } + + if (col[8 * 6]) { + a0 += W6 * col[8 * 6]; + a1 -= W2 * col[8 * 6]; + a2 += W2 * col[8 * 6]; + a3 -= W6 * col[8 * 6]; + } + + if (col[8 * 1]) { + b0 = W1 * col[8 * 1]; + b1 = W3 * col[8 * 1]; + b2 = W5 * col[8 * 1]; + b3 = W7 * col[8 * 1]; + } else { + b0 = 0; + b1 = 0; + b2 = 0; + b3 = 0; + } + + if (col[8 * 3]) { + b0 += W3 * col[8 * 3]; + b1 -= W7 * col[8 * 3]; + b2 -= W1 * col[8 * 3]; + b3 -= W5 * col[8 * 3]; + } + + if (col[8 * 5]) { + b0 += W5 * col[8 * 5]; + b1 -= W1 * col[8 * 5]; + b2 += W7 * col[8 * 5]; + b3 += W3 * col[8 * 5]; + } + + if (col[8 * 7]) { + b0 += W7 * col[8 * 7]; + b1 -= W5 * col[8 * 7]; + b2 += W3 * col[8 * 7]; + b3 -= W1 * col[8 * 7]; + } + + col[8 * 0] = (a0 + b0) >> COL_SHIFT; + col[8 * 7] = (a0 - b0) >> COL_SHIFT; + col[8 * 1] = (a1 + b1) >> COL_SHIFT; + col[8 * 6] = (a1 - b1) >> COL_SHIFT; + col[8 * 2] = (a2 + b2) >> COL_SHIFT; + col[8 * 5] = (a2 - b2) >> COL_SHIFT; + col[8 * 3] = (a3 + b3) >> COL_SHIFT; + col[8 * 4] = (a3 - b3) >> COL_SHIFT; +} + +/* If all rows but the first one are zero after row transformation, + all rows will be identical after column transformation. */ +static inline void idct_col2(DCTELEM *col) +{ + int i; + uint64_t l, r; + + for (i = 0; i < 8; ++i) { + int_fast32_t a0 = col[i] + (1 << (COL_SHIFT - 1)) / W4; + + a0 *= W4; + col[i] = a0 >> COL_SHIFT; + } + + l = ldq(col + 0 * 4); r = ldq(col + 1 * 4); + stq(l, col + 2 * 4); stq(r, col + 3 * 4); + stq(l, col + 4 * 4); stq(r, col + 5 * 4); + stq(l, col + 6 * 4); stq(r, col + 7 * 4); + stq(l, col + 8 * 4); stq(r, col + 9 * 4); + stq(l, col + 10 * 4); stq(r, col + 11 * 4); + stq(l, col + 12 * 4); stq(r, col + 13 * 4); + stq(l, col + 14 * 4); stq(r, col + 15 * 4); +} + +void simple_idct_axp(DCTELEM *block) +{ + + int i; + int rowsZero = 1; /* all rows except row 0 zero */ + int rowsConstant = 1; /* all rows consist of a constant value */ + + for (i = 0; i < 8; i++) { + int sparseness = idct_row(block + 8 * i); + + if (i > 0 && sparseness > 0) + rowsZero = 0; + if (sparseness == 2) + rowsConstant = 0; + } + + if (rowsZero) { + idct_col2(block); + } else if (rowsConstant) { + idct_col(block); + for (i = 0; i < 8; i += 2) { + uint64_t v = (uint16_t) block[0]; + uint64_t w = (uint16_t) block[8]; + + v |= v << 16; + w |= w << 16; + v |= v << 32; + w |= w << 32; + stq(v, block + 0 * 4); + stq(v, block + 1 * 4); + stq(w, block + 2 * 4); + stq(w, block + 3 * 4); + block += 4 * 4; + } + } else { + for (i = 0; i < 8; i++) + idct_col(block + i); + } +} + +void simple_idct_put_axp(uint8_t *dest, int line_size, DCTELEM *block) +{ + simple_idct_axp(block); + put_pixels_clamped_axp_p(block, dest, line_size); +} + +void simple_idct_add_axp(uint8_t *dest, int line_size, DCTELEM *block) +{ + simple_idct_axp(block); + add_pixels_clamped_axp_p(block, dest, line_size); +} diff --git a/mpeg4/src/libavcodec/amr.c b/mpeg4/src/libavcodec/amr.c new file mode 100644 index 00000000..6a354130 --- /dev/null +++ b/mpeg4/src/libavcodec/amr.c @@ -0,0 +1,664 @@ +/* + * AMR Audio decoder stub + * Copyright (c) 2003 the ffmpeg project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + /* + This code implements amr-nb and amr-wb audio encoder/decoder through external reference + code from www.3gpp.org. The licence of the code from 3gpp is unclear so you + have to download the code separately. Two versions exists: One fixed-point + and one with floats. For some reason the float-encoder is significant faster + atleast on a P4 1.5GHz (0.9s instead of 9.9s on a 30s audio clip at MR102). + Both float and fixed point is supported for amr-nb, but only float for + amr-wb. + + --AMR-NB-- + The fixed-point (TS26.073) can be downloaded from: + http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-510.zip + Extract the soure into ffmpeg/libavcodec/amr + To use the fixed version run "./configure" with "--enable-amr_nb-fixed" + + The float version (default) can be downloaded from: + http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-510.zip + Extract the soure into ffmpeg/libavcodec/amr_float + + The specification for amr-nb can be found in TS 26.071 + (http://www.3gpp.org/ftp/Specs/html-info/26071.htm) and some other + info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm + + --AMR-WB-- + The reference code can be downloaded from: + http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-510.zip + It should be extracted to "libavcodec/amrwb_float". Enable it with + "--enable-amr_wb". + + The specification for amr-wb can be downloaded from: + http://www.3gpp.org/ftp/Specs/archive/26_series/26.171/26171-500.zip + + If someone want to use the fixed point version it can be downloaded + from: http://www.3gpp.org/ftp/Specs/archive/26_series/26.173/26173-571.zip + + */ + +#include "avcodec.h" + +#ifdef AMR_NB_FIXED + +#define MMS_IO + +#include "amr/sp_dec.h" +#include "amr/d_homing.h" +#include "amr/typedef.h" +#include "amr/sp_enc.h" +#include "amr/sid_sync.h" +#include "amr/e_homing.h" + +#else +#include "amr_float/interf_dec.h" +#include "amr_float/interf_enc.h" +#endif + +/* Common code for fixed and float version*/ +typedef struct AMR_bitrates +{ + int startrate; + int stoprate; + enum Mode mode; + +} AMR_bitrates; + +/* Match desired bitrate with closest one*/ +static enum Mode getBitrateMode(int bitrate) +{ + /* Adjusted so that all bitrates can be used from commandline where + only a multiple of 1000 can be specified*/ + AMR_bitrates rates[]={ {0,4999,MR475}, //4 + {5000,5899,MR515},//5 + {5900,6699,MR59},//6 + {6700,7000,MR67},//7 + {7001,7949,MR74},//8 + {7950,9999,MR795},//9 + {10000,11999,MR102},//10 + {12000,64000,MR122},//12 + + }; + int i; + for(i=0;i<8;i++) + { + if(rates[i].startrate<=bitrate && rates[i].stoprate>=bitrate) + { + return(rates[i].mode); + } + } + /*Return highest possible*/ + return(MR122); +} + +#ifdef AMR_NB_FIXED +/* fixed point version*/ +/* frame size in serial bitstream file (frame type + serial stream + flags) */ +#define SERIAL_FRAMESIZE (1+MAX_SERIAL_SIZE+5) + +typedef struct AMRContext { + int frameCount; + Speech_Decode_FrameState *speech_decoder_state; + enum RXFrameType rx_type; + enum Mode mode; + Word16 reset_flag; + Word16 reset_flag_old; + + enum Mode enc_bitrate; + Speech_Encode_FrameState *enstate; + sid_syncState *sidstate; + enum TXFrameType tx_frametype; + + +} AMRContext; + +static int amr_nb_decode_init(AVCodecContext * avctx) +{ + AMRContext *s = avctx->priv_data; + s->frameCount=0; + s->speech_decoder_state=NULL; + s->rx_type = (enum RXFrameType)0; + s->mode= (enum Mode)0; + s->reset_flag=0; + s->reset_flag_old=1; + + if(Speech_Decode_Frame_init(&s->speech_decoder_state, "Decoder")) + { + av_log(avctx, AV_LOG_ERROR, "Speech_Decode_Frame_init error\n"); + return -1; + } + return 0; +} + +static int amr_nb_encode_init(AVCodecContext * avctx) +{ + AMRContext *s = avctx->priv_data; + s->frameCount=0; + s->speech_decoder_state=NULL; + s->rx_type = (enum RXFrameType)0; + s->mode= (enum Mode)0; + s->reset_flag=0; + s->reset_flag_old=1; + + if(avctx->sample_rate!=8000) + { + if(avctx->debug) + { + av_log(avctx, AV_LOG_DEBUG, "Only 8000Hz sample rate supported\n"); + } + return -1; + } + + if(avctx->channels!=1) + { + if(avctx->debug) + { + av_log(avctx, AV_LOG_DEBUG, "Only mono supported\n"); + } + return -1; + } + + avctx->frame_size=160; + avctx->coded_frame= avcodec_alloc_frame(); + + if(Speech_Encode_Frame_init(&s->enstate, 0, "encoder") || sid_sync_init (&s->sidstate)) + { + if(avctx->debug) + { + av_log(avctx, AV_LOG_DEBUG, "Speech_Encode_Frame_init error\n"); + } + return -1; + } + + s->enc_bitrate=getBitrateMode(avctx->bit_rate); + + return 0; +} + +static int amr_nb_encode_close(AVCodecContext * avctx) +{ + AMRContext *s = avctx->priv_data; + Speech_Encode_Frame_exit(&s->enstate); + sid_sync_exit (&s->sidstate); + av_freep(&avctx->coded_frame); + return 0; +} + +static int amr_nb_decode_close(AVCodecContext * avctx) +{ + AMRContext *s = avctx->priv_data; + Speech_Decode_Frame_exit(&s->speech_decoder_state); + return 0; +} + +static int amr_nb_decode_frame(AVCodecContext * avctx, + void *data, int *data_size, + uint8_t * buf, int buf_size) +{ + AMRContext *s = avctx->priv_data; + + uint8_t*amrData=buf; + int offset=0; + + UWord8 toc, q, ft; + + Word16 serial[SERIAL_FRAMESIZE]; /* coded bits */ + Word16 *synth; + UWord8 *packed_bits; + + static Word16 packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0}; + int i; + + //printf("amr_decode_frame data_size=%i buf=0x%X buf_size=%d frameCount=%d!!\n",*data_size,buf,buf_size,s->frameCount); + + synth=data; + +// while(offset> 2) & 0x01; + ft = (toc >> 3) & 0x0F; + + //printf("offset=%d, packet_size=%d amrData= 0x%X %X %X %X\n",offset,packed_size[ft],amrData[offset],amrData[offset+1],amrData[offset+2],amrData[offset+3]); + + offset++; + + packed_bits=amrData+offset; + + offset+=packed_size[ft]; + + //Unsort and unpack bits + s->rx_type = UnpackBits(q, ft, packed_bits, &s->mode, &serial[1]); + + //We have a new frame + s->frameCount++; + + if (s->rx_type == RX_NO_DATA) + { + s->mode = s->speech_decoder_state->prev_mode; + } + else { + s->speech_decoder_state->prev_mode = s->mode; + } + + /* if homed: check if this frame is another homing frame */ + if (s->reset_flag_old == 1) + { + /* only check until end of first subframe */ + s->reset_flag = decoder_homing_frame_test_first(&serial[1], s->mode); + } + /* produce encoder homing frame if homed & input=decoder homing frame */ + if ((s->reset_flag != 0) && (s->reset_flag_old != 0)) + { + for (i = 0; i < L_FRAME; i++) + { + synth[i] = EHF_MASK; + } + } + else + { + /* decode frame */ + Speech_Decode_Frame(s->speech_decoder_state, s->mode, &serial[1], s->rx_type, synth); + } + + //Each AMR-frame results in 160 16-bit samples + *data_size+=160*2; + synth+=160; + + /* if not homed: check whether current frame is a homing frame */ + if (s->reset_flag_old == 0) + { + /* check whole frame */ + s->reset_flag = decoder_homing_frame_test(&serial[1], s->mode); + } + /* reset decoder if current frame is a homing frame */ + if (s->reset_flag != 0) + { + Speech_Decode_Frame_reset(s->speech_decoder_state); + } + s->reset_flag_old = s->reset_flag; + + } + return offset; +} + + +static int amr_nb_encode_frame(AVCodecContext *avctx, + unsigned char *frame/*out*/, int buf_size, void *data/*in*/) +{ + short serial_data[250] = {0}; + + AMRContext *s = avctx->priv_data; + int written; + + s->reset_flag = encoder_homing_frame_test(data); + + Speech_Encode_Frame(s->enstate, s->enc_bitrate, data, &serial_data[1], &s->mode); + + /* add frame type and mode */ + sid_sync (s->sidstate, s->mode, &s->tx_frametype); + + written = PackBits(s->mode, s->enc_bitrate, s->tx_frametype, &serial_data[1], frame); + + if (s->reset_flag != 0) + { + Speech_Encode_Frame_reset(s->enstate); + sid_sync_reset(s->sidstate); + } + return written; +} + + +#elif defined(AMR_NB) /* Float point version*/ + +typedef struct AMRContext { + int frameCount; + void * decState; + int *enstate; + enum Mode enc_bitrate; +} AMRContext; + +static int amr_nb_decode_init(AVCodecContext * avctx) +{ + AMRContext *s = avctx->priv_data; + s->frameCount=0; + s->decState=Decoder_Interface_init(); + if(!s->decState) + { + av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\r\n"); + return -1; + } + return 0; +} + +static int amr_nb_encode_init(AVCodecContext * avctx) +{ + AMRContext *s = avctx->priv_data; + s->frameCount=0; + + if(avctx->sample_rate!=8000) + { + if(avctx->debug) + { + av_log(avctx, AV_LOG_DEBUG, "Only 8000Hz sample rate supported\n"); + } + return -1; + } + + if(avctx->channels!=1) + { + if(avctx->debug) + { + av_log(avctx, AV_LOG_DEBUG, "Only mono supported\n"); + } + return -1; + } + + avctx->frame_size=160; + avctx->coded_frame= avcodec_alloc_frame(); + + s->enstate=Encoder_Interface_init(0); + if(!s->enstate) + { + if(avctx->debug) + { + av_log(avctx, AV_LOG_DEBUG, "Encoder_Interface_init error\n"); + } + return -1; + } + + s->enc_bitrate=getBitrateMode(avctx->bit_rate); + + return 0; +} + +static int amr_nb_decode_close(AVCodecContext * avctx) +{ + AMRContext *s = avctx->priv_data; + Decoder_Interface_exit(s->decState); + return 0; +} + +static int amr_nb_encode_close(AVCodecContext * avctx) +{ + AMRContext *s = avctx->priv_data; + Encoder_Interface_exit(s->enstate); + av_freep(&avctx->coded_frame); + return 0; +} + +static int amr_nb_decode_frame(AVCodecContext * avctx, + void *data, int *data_size, + uint8_t * buf, int buf_size) +{ + AMRContext *s = (AMRContext*)avctx->priv_data; + + uint8_t*amrData=buf; + static short block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 }; + enum Mode dec_mode; + int packet_size; + + /* av_log(NULL,AV_LOG_DEBUG,"amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",buf,buf_size,s->frameCount); */ + + if(buf_size==0) { + /* nothing to do */ + return 0; + } + + dec_mode = (buf[0] >> 3) & 0x000F; + packet_size = block_size[dec_mode]+1; + + if(packet_size > buf_size) { + av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size); + return -1; + } + + s->frameCount++; + /* av_log(NULL,AV_LOG_DEBUG,"packet_size=%d amrData= 0x%X %X %X %X\n",packet_size,amrData[0],amrData[1],amrData[2],amrData[3]); */ + /* call decoder */ + Decoder_Interface_Decode(s->decState, amrData, data, 0); + *data_size=160*2; + + return packet_size; +} + +static int amr_nb_encode_frame(AVCodecContext *avctx, + unsigned char *frame/*out*/, int buf_size, void *data/*in*/) +{ + AMRContext *s = (AMRContext*)avctx->priv_data; + int written; + + written = Encoder_Interface_Encode(s->enstate, + s->enc_bitrate, + data, + frame, + 0); + /* av_log(NULL,AV_LOG_DEBUG,"amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n",written, s->enc_bitrate, frame[0] ); */ + + return written; +} + +#endif + +#if defined(AMR_NB) || defined(AMR_NB_FIXED) + +AVCodec amr_nb_decoder = +{ + "amr_nb", + CODEC_TYPE_AUDIO, + CODEC_ID_AMR_NB, + sizeof(AMRContext), + amr_nb_decode_init, + NULL, + amr_nb_decode_close, + amr_nb_decode_frame, +}; + +AVCodec amr_nb_encoder = +{ + "amr_nb", + CODEC_TYPE_AUDIO, + CODEC_ID_AMR_NB, + sizeof(AMRContext), + amr_nb_encode_init, + amr_nb_encode_frame, + amr_nb_encode_close, + NULL, +}; + +#endif + +/* -----------AMR wideband ------------*/ +#ifdef AMR_WB + +#ifdef _TYPEDEF_H +//To avoid duplicate typedefs from typdef in amr-nb +#define typedef_h +#endif + +#include "amrwb_float/enc_if.h" +#include "amrwb_float/dec_if.h" + +/* Common code for fixed and float version*/ +typedef struct AMRWB_bitrates +{ + int startrate; + int stoprate; + int mode; + +} AMRWB_bitrates; + +static int getWBBitrateMode(int bitrate) +{ + /* Adjusted so that all bitrates can be used from commandline where + only a multiple of 1000 can be specified*/ + AMRWB_bitrates rates[]={ {0,7999,0}, //6.6kHz + {8000,9999,1},//8.85 + {10000,13000,2},//12.65 + {13001,14999,3},//14.25 + {15000,17000,4},//15.85 + {17001,18000,5},//18.25 + {18001,22000,6},//19.85 + {22001,23000,7},//23.05 + {23001,24000,8},//23.85 + + }; + int i; + + for(i=0;i<9;i++) + { + if(rates[i].startrate<=bitrate && rates[i].stoprate>=bitrate) + { + return(rates[i].mode); + } + } + /*Return highest possible*/ + return(8); +} + + +typedef struct AMRWBContext { + int frameCount; + void *state; + int mode; + Word16 allow_dtx; +} AMRWBContext; + +static int amr_wb_encode_init(AVCodecContext * avctx) +{ + AMRWBContext *s = (AMRWBContext*)avctx->priv_data; + s->frameCount=0; + + if(avctx->sample_rate!=16000) + { + if(avctx->debug) + { + av_log(avctx, AV_LOG_DEBUG, "Only 16000Hz sample rate supported\n"); + } + return -1; + } + + if(avctx->channels!=1) + { + if(avctx->debug) + { + av_log(avctx, AV_LOG_DEBUG, "Only mono supported\n"); + } + return -1; + } + + avctx->frame_size=320; + avctx->coded_frame= avcodec_alloc_frame(); + + s->state = E_IF_init(); + s->mode=getWBBitrateMode(avctx->bit_rate); + s->allow_dtx=0; + + return 0; +} + +static int amr_wb_encode_close(AVCodecContext * avctx) +{ + AMRWBContext *s = (AMRWBContext*) avctx->priv_data; + E_IF_exit(s->state); + av_freep(&avctx->coded_frame); + s->frameCount++; + return 0; +} + +static int amr_wb_encode_frame(AVCodecContext *avctx, + unsigned char *frame/*out*/, int buf_size, void *data/*in*/) +{ + AMRWBContext *s = (AMRWBContext*) avctx->priv_data; + int size = E_IF_encode(s->state, s->mode, data, frame, s->allow_dtx); + return size; +} + +static int amr_wb_decode_init(AVCodecContext * avctx) +{ + AMRWBContext *s = (AMRWBContext *)avctx->priv_data; + s->frameCount=0; + s->state = D_IF_init(); + return 0; +} + +extern const UWord8 block_size[]; + +static int amr_wb_decode_frame(AVCodecContext * avctx, + void *data, int *data_size, + uint8_t * buf, int buf_size) +{ + AMRWBContext *s = (AMRWBContext*)avctx->priv_data; + + uint8_t*amrData=buf; + int mode; + int packet_size; + + if(buf_size==0) { + /* nothing to do */ + return 0; + } + + mode = (amrData[0] >> 3) & 0x000F; + packet_size = block_size[mode]; + + if(packet_size > buf_size) { + av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size+1); + return -1; + } + + s->frameCount++; + D_IF_decode( s->state, amrData, data, _good_frame); + *data_size=320*2; + return packet_size; +} + +static int amr_wb_decode_close(AVCodecContext * avctx) +{ + AMRWBContext *s = (AMRWBContext *)avctx->priv_data; + D_IF_exit(s->state); + return 0; +} + +AVCodec amr_wb_decoder = +{ + "amr_wb", + CODEC_TYPE_AUDIO, + CODEC_ID_AMR_WB, + sizeof(AMRWBContext), + amr_wb_decode_init, + NULL, + amr_wb_decode_close, + amr_wb_decode_frame, +}; + +AVCodec amr_wb_encoder = +{ + "amr_wb", + CODEC_TYPE_AUDIO, + CODEC_ID_AMR_WB, + sizeof(AMRWBContext), + amr_wb_encode_init, + amr_wb_encode_frame, + amr_wb_encode_close, + NULL, +}; + +#endif //AMR_WB diff --git a/mpeg4/src/libavcodec/apiexample.c b/mpeg4/src/libavcodec/apiexample.c new file mode 100644 index 00000000..7fe1c119 --- /dev/null +++ b/mpeg4/src/libavcodec/apiexample.c @@ -0,0 +1,437 @@ +/** + * @file apiexample.c + * avcodec API use example. + * + * Note that this library only handles codecs (mpeg, mpeg4, etc...), + * not file formats (avi, vob, etc...). See library 'libavformat' for the + * format handling + */ + +#include +#include +#include +#include + +#ifdef HAVE_AV_CONFIG_H +#undef HAVE_AV_CONFIG_H +#endif + +#include "avcodec.h" + +#define INBUF_SIZE 4096 + +/* + * Audio encoding example + */ +void audio_encode_example(const char *filename) +{ + AVCodec *codec; + AVCodecContext *c= NULL; + int frame_size, i, j, out_size, outbuf_size; + FILE *f; + short *samples; + float t, tincr; + uint8_t *outbuf; + + printf("Audio encoding\n"); + + /* find the MP2 encoder */ + codec = avcodec_find_encoder(CODEC_ID_MP2); + if (!codec) { + fprintf(stderr, "codec not found\n"); + exit(1); + } + + c= avcodec_alloc_context(); + + /* put sample parameters */ + c->bit_rate = 64000; + c->sample_rate = 44100; + c->channels = 2; + + /* open it */ + if (avcodec_open(c, codec) < 0) { + fprintf(stderr, "could not open codec\n"); + exit(1); + } + + /* the codec gives us the frame size, in samples */ + frame_size = c->frame_size; + samples = malloc(frame_size * 2 * c->channels); + outbuf_size = 10000; + outbuf = malloc(outbuf_size); + + f = fopen(filename, "wb"); + if (!f) { + fprintf(stderr, "could not open %s\n", filename); + exit(1); + } + + /* encode a single tone sound */ + t = 0; + tincr = 2 * M_PI * 440.0 / c->sample_rate; + for(i=0;i<200;i++) { + for(j=0;j 0) { + len = avcodec_decode_audio(c, (short *)outbuf, &out_size, + inbuf_ptr, size); + if (len < 0) { + fprintf(stderr, "Error while decoding\n"); + exit(1); + } + if (out_size > 0) { + /* if a frame has been decoded, output it */ + fwrite(outbuf, 1, out_size, outfile); + } + size -= len; + inbuf_ptr += len; + } + } + + fclose(outfile); + fclose(f); + free(outbuf); + + avcodec_close(c); + av_free(c); +} + +/* + * Video encoding example + */ +void video_encode_example(const char *filename) +{ + AVCodec *codec; + AVCodecContext *c= NULL; + int i, out_size, size, x, y, outbuf_size; + FILE *f; + AVFrame *picture; + uint8_t *outbuf, *picture_buf; + + printf("Video encoding\n"); + + /* find the mpeg1 video encoder */ + codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); + if (!codec) { + fprintf(stderr, "codec not found\n"); + exit(1); + } + + c= avcodec_alloc_context(); + picture= avcodec_alloc_frame(); + + /* put sample parameters */ + c->bit_rate = 400000; + /* resolution must be a multiple of two */ + c->width = 352; + c->height = 288; + /* frames per second */ + c->time_base= (AVRational){1,25}; + c->gop_size = 10; /* emit one intra frame every ten frames */ + c->max_b_frames=1; + c->pix_fmt = PIX_FMT_YUV420P; + + /* open it */ + if (avcodec_open(c, codec) < 0) { + fprintf(stderr, "could not open codec\n"); + exit(1); + } + + /* the codec gives us the frame size, in samples */ + + f = fopen(filename, "wb"); + if (!f) { + fprintf(stderr, "could not open %s\n", filename); + exit(1); + } + + /* alloc image and output buffer */ + outbuf_size = 100000; + outbuf = malloc(outbuf_size); + size = c->width * c->height; + picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ + + picture->data[0] = picture_buf; + picture->data[1] = picture->data[0] + size; + picture->data[2] = picture->data[1] + size / 4; + picture->linesize[0] = c->width; + picture->linesize[1] = c->width / 2; + picture->linesize[2] = c->width / 2; + + /* encode 1 second of video */ + for(i=0;i<25;i++) { + fflush(stdout); + /* prepare a dummy image */ + /* Y */ + for(y=0;yheight;y++) { + for(x=0;xwidth;x++) { + picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; + } + } + + /* Cb and Cr */ + for(y=0;yheight/2;y++) { + for(x=0;xwidth/2;x++) { + picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; + picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; + } + } + + /* encode the image */ + out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); + printf("encoding frame %3d (size=%5d)\n", i, out_size); + fwrite(outbuf, 1, out_size, f); + } + + /* get the delayed frames */ + for(; out_size; i++) { + fflush(stdout); + + out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); + printf("write frame %3d (size=%5d)\n", i, out_size); + fwrite(outbuf, 1, out_size, f); + } + + /* add sequence end code to have a real mpeg file */ + outbuf[0] = 0x00; + outbuf[1] = 0x00; + outbuf[2] = 0x01; + outbuf[3] = 0xb7; + fwrite(outbuf, 1, 4, f); + fclose(f); + free(picture_buf); + free(outbuf); + + avcodec_close(c); + av_free(c); + av_free(picture); + printf("\n"); +} + +/* + * Video decoding example + */ + +void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) +{ + FILE *f; + int i; + + f=fopen(filename,"w"); + fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255); + for(i=0;icapabilities&CODEC_CAP_TRUNCATED) + c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */ + + /* for some codecs, such as msmpeg4 and mpeg4, width and height + MUST be initialized there because these info are not available + in the bitstream */ + + /* open it */ + if (avcodec_open(c, codec) < 0) { + fprintf(stderr, "could not open codec\n"); + exit(1); + } + + /* the codec gives us the frame size, in samples */ + + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, "could not open %s\n", filename); + exit(1); + } + + frame = 0; + for(;;) { + size = fread(inbuf, 1, INBUF_SIZE, f); + if (size == 0) + break; + + /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) + and this is the only method to use them because you cannot + know the compressed data size before analysing it. + + BUT some other codecs (msmpeg4, mpeg4) are inherently frame + based, so you must call them with all the data for one + frame exactly. You must also initialize 'width' and + 'height' before initializing them. */ + + /* NOTE2: some codecs allow the raw parameters (frame size, + sample rate) to be changed at any frame. We handle this, so + you should also take care of it */ + + /* here, we use a stream based decoder (mpeg1video), so we + feed decoder and see if it could decode a frame */ + inbuf_ptr = inbuf; + while (size > 0) { + len = avcodec_decode_video(c, picture, &got_picture, + inbuf_ptr, size); + if (len < 0) { + fprintf(stderr, "Error while decoding frame %d\n", frame); + exit(1); + } + if (got_picture) { + printf("saving frame %3d\n", frame); + fflush(stdout); + + /* the picture is allocated by the decoder. no need to + free it */ + snprintf(buf, sizeof(buf), outfilename, frame); + pgm_save(picture->data[0], picture->linesize[0], + c->width, c->height, buf); + frame++; + } + size -= len; + inbuf_ptr += len; + } + } + + /* some codecs, such as MPEG, transmit the I and P frame with a + latency of one frame. You must do the following to have a + chance to get the last frame of the video */ + len = avcodec_decode_video(c, picture, &got_picture, + NULL, 0); + if (got_picture) { + printf("saving last frame %3d\n", frame); + fflush(stdout); + + /* the picture is allocated by the decoder. no need to + free it */ + snprintf(buf, sizeof(buf), outfilename, frame); + pgm_save(picture->data[0], picture->linesize[0], + c->width, c->height, buf); + frame++; + } + + fclose(f); + + avcodec_close(c); + av_free(c); + av_free(picture); + printf("\n"); +} + +int main(int argc, char **argv) +{ + const char *filename; + + /* must be called before using avcodec lib */ + avcodec_init(); + + /* register all the codecs (you can also register only the codec + you wish to have smaller code */ + avcodec_register_all(); + + if (argc <= 1) { + audio_encode_example("/tmp/test.mp2"); + audio_decode_example("/tmp/test.sw", "/tmp/test.mp2"); + + video_encode_example("/tmp/test.mpg"); + filename = "/tmp/test.mpg"; + } else { + filename = argv[1]; + } + + // audio_decode_example("/tmp/test.sw", filename); + video_decode_example("/tmp/test%d.pgm", filename); + + return 0; +} diff --git a/mpeg4/src/libavcodec/armv4l/dsputil_arm.c b/mpeg4/src/libavcodec/armv4l/dsputil_arm.c new file mode 100644 index 00000000..cebd176b --- /dev/null +++ b/mpeg4/src/libavcodec/armv4l/dsputil_arm.c @@ -0,0 +1,246 @@ +/* + * ARMv4L optimized DSP utils + * Copyright (c) 2001 Lionel Ulmer. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../dsputil.h" +#ifdef HAVE_IPP +#include "ipp.h" +#endif + +extern void dsputil_init_iwmmxt(DSPContext* c, AVCodecContext *avctx); + +extern void j_rev_dct_ARM(DCTELEM *data); +extern void simple_idct_ARM(DCTELEM *data); + +/* XXX: local hack */ +static void (*ff_put_pixels_clamped)(const DCTELEM *block, uint8_t *pixels, int line_size); +static void (*ff_add_pixels_clamped)(const DCTELEM *block, uint8_t *pixels, int line_size); + +void put_pixels8_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); +void put_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); +void put_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); +void put_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); + +void put_no_rnd_pixels8_x2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); +void put_no_rnd_pixels8_y2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); +void put_no_rnd_pixels8_xy2_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); + +void put_pixels16_arm(uint8_t *block, const uint8_t *pixels, int line_size, int h); + +CALL_2X_PIXELS(put_pixels16_x2_arm , put_pixels8_x2_arm , 8) +CALL_2X_PIXELS(put_pixels16_y2_arm , put_pixels8_y2_arm , 8) +CALL_2X_PIXELS(put_pixels16_xy2_arm, put_pixels8_xy2_arm, 8) +CALL_2X_PIXELS(put_no_rnd_pixels16_x2_arm , put_no_rnd_pixels8_x2_arm , 8) +CALL_2X_PIXELS(put_no_rnd_pixels16_y2_arm , put_no_rnd_pixels8_y2_arm , 8) +CALL_2X_PIXELS(put_no_rnd_pixels16_xy2_arm, put_no_rnd_pixels8_xy2_arm, 8) + +static void add_pixels_clamped_ARM(short *block, unsigned char *dest, int line_size) +{ + asm volatile ( + "mov r10, #8 \n\t" + + "1: \n\t" + + /* load dest */ + "ldr r4, [%1] \n\t" + /* block[0] and block[1]*/ + "ldrsh r5, [%0] \n\t" + "ldrsh r7, [%0, #2] \n\t" + "and r6, r4, #0xFF \n\t" + "and r8, r4, #0xFF00 \n\t" + "add r6, r5, r6 \n\t" + "add r8, r7, r8, lsr #8 \n\t" + "mvn r5, r5 \n\t" + "mvn r7, r7 \n\t" + "tst r6, #0x100 \n\t" + "movne r6, r5, lsr #24 \n\t" + "tst r8, #0x100 \n\t" + "movne r8, r7, lsr #24 \n\t" + "mov r9, r6 \n\t" + "ldrsh r5, [%0, #4] \n\t" /* moved form [A] */ + "orr r9, r9, r8, lsl #8 \n\t" + /* block[2] and block[3] */ + /* [A] */ + "ldrsh r7, [%0, #6] \n\t" + "and r6, r4, #0xFF0000 \n\t" + "and r8, r4, #0xFF000000 \n\t" + "add r6, r5, r6, lsr #16 \n\t" + "add r8, r7, r8, lsr #24 \n\t" + "mvn r5, r5 \n\t" + "mvn r7, r7 \n\t" + "tst r6, #0x100 \n\t" + "movne r6, r5, lsr #24 \n\t" + "tst r8, #0x100 \n\t" + "movne r8, r7, lsr #24 \n\t" + "orr r9, r9, r6, lsl #16 \n\t" + "ldr r4, [%1, #4] \n\t" /* moved form [B] */ + "orr r9, r9, r8, lsl #24 \n\t" + /* store dest */ + "ldrsh r5, [%0, #8] \n\t" /* moved form [C] */ + "str r9, [%1] \n\t" + + /* load dest */ + /* [B] */ + /* block[4] and block[5] */ + /* [C] */ + "ldrsh r7, [%0, #10] \n\t" + "and r6, r4, #0xFF \n\t" + "and r8, r4, #0xFF00 \n\t" + "add r6, r5, r6 \n\t" + "add r8, r7, r8, lsr #8 \n\t" + "mvn r5, r5 \n\t" + "mvn r7, r7 \n\t" + "tst r6, #0x100 \n\t" + "movne r6, r5, lsr #24 \n\t" + "tst r8, #0x100 \n\t" + "movne r8, r7, lsr #24 \n\t" + "mov r9, r6 \n\t" + "ldrsh r5, [%0, #12] \n\t" /* moved from [D] */ + "orr r9, r9, r8, lsl #8 \n\t" + /* block[6] and block[7] */ + /* [D] */ + "ldrsh r7, [%0, #14] \n\t" + "and r6, r4, #0xFF0000 \n\t" + "and r8, r4, #0xFF000000 \n\t" + "add r6, r5, r6, lsr #16 \n\t" + "add r8, r7, r8, lsr #24 \n\t" + "mvn r5, r5 \n\t" + "mvn r7, r7 \n\t" + "tst r6, #0x100 \n\t" + "movne r6, r5, lsr #24 \n\t" + "tst r8, #0x100 \n\t" + "movne r8, r7, lsr #24 \n\t" + "orr r9, r9, r6, lsl #16 \n\t" + "add %0, %0, #16 \n\t" /* moved from [E] */ + "orr r9, r9, r8, lsl #24 \n\t" + "subs r10, r10, #1 \n\t" /* moved from [F] */ + /* store dest */ + "str r9, [%1, #4] \n\t" + + /* [E] */ + /* [F] */ + "add %1, %1, %2 \n\t" + "bne 1b \n\t" + : "+r"(block), + "+r"(dest) + : "r"(line_size) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc", "memory" ); +} + +/* XXX: those functions should be suppressed ASAP when all IDCTs are + converted */ +static void j_rev_dct_ARM_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct_ARM (block); + ff_put_pixels_clamped(block, dest, line_size); +} +static void j_rev_dct_ARM_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + j_rev_dct_ARM (block); + ff_add_pixels_clamped(block, dest, line_size); +} +static void simple_idct_ARM_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + simple_idct_ARM (block); + ff_put_pixels_clamped(block, dest, line_size); +} +static void simple_idct_ARM_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + simple_idct_ARM (block); + ff_add_pixels_clamped(block, dest, line_size); +} +static void simple_idct_ipp(DCTELEM *block) +{ +#ifdef HAVE_IPP + ippiDCT8x8Inv_Video_16s_C1I(block); +#endif +} +static void simple_idct_ipp_put(uint8_t *dest, int line_size, DCTELEM *block) +{ +#ifdef HAVE_IPP + ippiDCT8x8Inv_Video_16s8u_C1R(block, dest, line_size); +#endif +} + +void add_pixels_clamped_iwmmxt(const DCTELEM *block, uint8_t *pixels, int line_size); + +static void simple_idct_ipp_add(uint8_t *dest, int line_size, DCTELEM *block) +{ +#ifdef HAVE_IPP + ippiDCT8x8Inv_Video_16s_C1I(block); +#ifdef HAVE_IWMMXT + add_pixels_clamped_iwmmxt(block, dest, line_size); +#else + add_pixels_clamped_ARM(block, dest, line_size); +#endif +#endif +} + +void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx) +{ + const int idct_algo= avctx->idct_algo; + + ff_put_pixels_clamped = c->put_pixels_clamped; + ff_add_pixels_clamped = c->add_pixels_clamped; + +#ifdef HAVE_IPP + if(idct_algo==FF_IDCT_ARM){ +#else + if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_ARM){ +#endif + c->idct_put= j_rev_dct_ARM_put; + c->idct_add= j_rev_dct_ARM_add; + c->idct = j_rev_dct_ARM; + c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;/* FF_NO_IDCT_PERM */ + } else if (idct_algo==FF_IDCT_SIMPLEARM){ + c->idct_put= simple_idct_ARM_put; + c->idct_add= simple_idct_ARM_add; + c->idct = simple_idct_ARM; + c->idct_permutation_type= FF_NO_IDCT_PERM; +#ifdef HAVE_IPP + } else if (idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_IPP){ +#else + } else if (idct_algo==FF_IDCT_IPP){ +#endif + c->idct_put= simple_idct_ipp_put; + c->idct_add= simple_idct_ipp_add; + c->idct = simple_idct_ipp; + c->idct_permutation_type= FF_NO_IDCT_PERM; + } + +/* c->put_pixels_tab[0][0] = put_pixels16_arm; */ // NG! + c->put_pixels_tab[0][1] = put_pixels16_x2_arm; //OK! + c->put_pixels_tab[0][2] = put_pixels16_y2_arm; //OK! +/* c->put_pixels_tab[0][3] = put_pixels16_xy2_arm; /\* NG *\/ */ +/* c->put_no_rnd_pixels_tab[0][0] = put_pixels16_arm; // ?(»È¤ï¤ì¤Ê¤¤) */ + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_arm; // OK + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_arm; //OK +/* c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_arm; //NG */ + c->put_pixels_tab[1][0] = put_pixels8_arm; //OK + c->put_pixels_tab[1][1] = put_pixels8_x2_arm; //OK +/* c->put_pixels_tab[1][2] = put_pixels8_y2_arm; //NG */ +/* c->put_pixels_tab[1][3] = put_pixels8_xy2_arm; //NG */ + c->put_no_rnd_pixels_tab[1][0] = put_pixels8_arm;//OK + c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_arm; //OK + c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_arm; //OK +/* c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_arm;//NG */ + +#ifdef HAVE_IWMMXT + dsputil_init_iwmmxt(c, avctx); +#endif +} diff --git a/mpeg4/src/libavcodec/armv4l/dsputil_arm_s.S b/mpeg4/src/libavcodec/armv4l/dsputil_arm_s.S new file mode 100644 index 00000000..8d64a1af --- /dev/null +++ b/mpeg4/src/libavcodec/armv4l/dsputil_arm_s.S @@ -0,0 +1,694 @@ +@ +@ ARMv4L optimized DSP utils +@ Copyright (c) 2004 AGAWA Koji +@ +@ This library is free software; you can redistribute it and/or +@ modify it under the terms of the GNU Lesser General Public +@ License as published by the Free Software Foundation; either +@ version 2 of the License, or (at your option) any later version. +@ +@ This library is distributed in the hope that it will be useful, +@ but WITHOUT ANY WARRANTY; without even the implied warranty of +@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@ Lesser General Public License for more details. +@ +@ You should have received a copy of the GNU Lesser General Public +@ License along with this library; if not, write to the Free Software +@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +@ + +.macro ADJ_ALIGN_QUADWORD_D shift, Rd0, Rd1, Rd2, Rd3, Rn0, Rn1, Rn2, Rn3, Rn4 + mov \Rd0, \Rn0, lsr #(\shift * 8) + mov \Rd1, \Rn1, lsr #(\shift * 8) + mov \Rd2, \Rn2, lsr #(\shift * 8) + mov \Rd3, \Rn3, lsr #(\shift * 8) + orr \Rd0, \Rd0, \Rn1, lsl #(32 - \shift * 8) + orr \Rd1, \Rd1, \Rn2, lsl #(32 - \shift * 8) + orr \Rd2, \Rd2, \Rn3, lsl #(32 - \shift * 8) + orr \Rd3, \Rd3, \Rn4, lsl #(32 - \shift * 8) +.endm +.macro ADJ_ALIGN_DOUBLEWORD shift, R0, R1, R2 + mov \R0, \R0, lsr #(\shift * 8) + orr \R0, \R0, \R1, lsl #(32 - \shift * 8) + mov \R1, \R1, lsr #(\shift * 8) + orr \R1, \R1, \R2, lsl #(32 - \shift * 8) +.endm +.macro ADJ_ALIGN_DOUBLEWORD_D shift, Rdst0, Rdst1, Rsrc0, Rsrc1, Rsrc2 + mov \Rdst0, \Rsrc0, lsr #(\shift * 8) + mov \Rdst1, \Rsrc1, lsr #(\shift * 8) + orr \Rdst0, \Rdst0, \Rsrc1, lsl #(32 - (\shift * 8)) + orr \Rdst1, \Rdst1, \Rsrc2, lsl #(32 - (\shift * 8)) +.endm + +.macro RND_AVG32 Rd0, Rd1, Rn0, Rn1, Rm0, Rm1, Rmask + @ Rd = (Rn | Rm) - (((Rn ^ Rm) & ~0x01010101) >> 1) + @ Rmask = 0xFEFEFEFE + @ Rn = destroy + eor \Rd0, \Rn0, \Rm0 + eor \Rd1, \Rn1, \Rm1 + orr \Rn0, \Rn0, \Rm0 + orr \Rn1, \Rn1, \Rm1 + and \Rd0, \Rd0, \Rmask + and \Rd1, \Rd1, \Rmask + sub \Rd0, \Rn0, \Rd0, lsr #1 + sub \Rd1, \Rn1, \Rd1, lsr #1 +.endm + +.macro NO_RND_AVG32 Rd0, Rd1, Rn0, Rn1, Rm0, Rm1, Rmask + @ Rd = (Rn & Rm) - (((Rn ^ Rm) & ~0x01010101) >> 1) + @ Rmask = 0xFEFEFEFE + @ Rn = destroy + eor \Rd0, \Rn0, \Rm0 + eor \Rd1, \Rn1, \Rm1 + and \Rn0, \Rn0, \Rm0 + and \Rn1, \Rn1, \Rm1 + and \Rd0, \Rd0, \Rmask + and \Rd1, \Rd1, \Rmask + add \Rd0, \Rn0, \Rd0, lsr #1 + add \Rd1, \Rn1, \Rd1, lsr #1 +.endm + +@ ---------------------------------------------------------------- + .align 8 + .global put_pixels16_arm +put_pixels16_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11, lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + bic r1, r1, #3 + add r5, r5, r4, lsl #2 + ldrne pc, [r5] +1: + ldmia r1, {r4-r7} + add r1, r1, r2 + stmia r0, {r4-r7} + pld [r1] + subs r3, r3, #1 + add r0, r0, r2 + bne 1b + ldmfd sp!, {r4-r11, pc} + .align 8 +2: + ldmia r1, {r4-r8} + add r1, r1, r2 + ADJ_ALIGN_QUADWORD_D 1, r9, r10, r11, r12, r4, r5, r6, r7, r8 + pld [r1] + subs r3, r3, #1 + stmia r0, {r9-r12} + add r0, r0, r2 + bne 2b + ldmfd sp!, {r4-r11, pc} + .align 8 +3: + ldmia r1, {r4-r8} + add r1, r1, r2 + ADJ_ALIGN_QUADWORD_D 2, r9, r10, r11, r12, r4, r5, r6, r7, r8 + pld [r1] + subs r3, r3, #1 + stmia r0, {r9-r12} + add r0, r0, r2 + bne 3b + ldmfd sp!, {r4-r11, pc} + .align 8 +4: + ldmia r1, {r4-r8} + add r1, r1, r2 + ADJ_ALIGN_QUADWORD_D 3, r9, r10, r11, r12, r4, r5, r6, r7, r8 + pld [r1] + subs r3, r3, #1 + stmia r0, {r9-r12} + add r0, r0, r2 + bne 4b + ldmfd sp!, {r4-r11,pc} + .align 8 +5: + .word 1b + .word 2b + .word 3b + .word 4b + +@ ---------------------------------------------------------------- + .align 8 + .global put_pixels8_arm +put_pixels8_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r5,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + bic r1, r1, #3 + add r5, r5, r4, lsl #2 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5} + add r1, r1, r2 + subs r3, r3, #1 + pld [r1] + stmia r0, {r4-r5} + add r0, r0, r2 + bne 1b + ldmfd sp!, {r4-r5,pc} + .align 8 +2: + ldmia r1, {r4-r5, r12} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r12 + pld [r1] + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 2b + ldmfd sp!, {r4-r5,pc} + .align 8 +3: + ldmia r1, {r4-r5, r12} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r12 + pld [r1] + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 3b + ldmfd sp!, {r4-r5,pc} + .align 8 +4: + ldmia r1, {r4-r5, r12} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r12 + pld [r1] + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 4b + ldmfd sp!, {r4-r5,pc} + .align 8 +5: + .word 1b + .word 2b + .word 3b + .word 4b + +@ ---------------------------------------------------------------- + .align 8 + .global put_pixels8_x2_arm +put_pixels8_x2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r10,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + ldr r12, [r5] + add r5, r5, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 + pld [r1] + RND_AVG32 r8, r9, r4, r5, r6, r7, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 1b + ldmfd sp!, {r4-r10,pc} + .align 8 +2: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 + ADJ_ALIGN_DOUBLEWORD_D 2, r8, r9, r4, r5, r10 + pld [r1] + RND_AVG32 r4, r5, r6, r7, r8, r9, r12 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 2b + ldmfd sp!, {r4-r10,pc} + .align 8 +3: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 2, r6, r7, r4, r5, r10 + ADJ_ALIGN_DOUBLEWORD_D 3, r8, r9, r4, r5, r10 + pld [r1] + RND_AVG32 r4, r5, r6, r7, r8, r9, r12 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 3b + ldmfd sp!, {r4-r10,pc} + .align 8 +4: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 3, r6, r7, r4, r5, r10 + pld [r1] + RND_AVG32 r8, r9, r6, r7, r5, r10, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 4b + ldmfd sp!, {r4-r10,pc} @@ update PC with LR content. + .align 8 +5: + .word 0xFEFEFEFE + .word 2b + .word 3b + .word 4b + + .align 8 + .global put_no_rnd_pixels8_x2_arm +put_no_rnd_pixels8_x2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r10,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + ldr r12, [r5] + add r5, r5, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 + pld [r1] + NO_RND_AVG32 r8, r9, r4, r5, r6, r7, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 1b + ldmfd sp!, {r4-r10,pc} + .align 8 +2: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 1, r6, r7, r4, r5, r10 + ADJ_ALIGN_DOUBLEWORD_D 2, r8, r9, r4, r5, r10 + pld [r1] + NO_RND_AVG32 r4, r5, r6, r7, r8, r9, r12 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 2b + ldmfd sp!, {r4-r10,pc} + .align 8 +3: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 2, r6, r7, r4, r5, r10 + ADJ_ALIGN_DOUBLEWORD_D 3, r8, r9, r4, r5, r10 + pld [r1] + NO_RND_AVG32 r4, r5, r6, r7, r8, r9, r12 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 3b + ldmfd sp!, {r4-r10,pc} + .align 8 +4: + ldmia r1, {r4-r5, r10} + add r1, r1, r2 + ADJ_ALIGN_DOUBLEWORD_D 3, r6, r7, r4, r5, r10 + pld [r1] + NO_RND_AVG32 r8, r9, r6, r7, r5, r10, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 4b + ldmfd sp!, {r4-r10,pc} @@ update PC with LR content. + .align 8 +5: + .word 0xFEFEFEFE + .word 2b + .word 3b + .word 4b + + +@ ---------------------------------------------------------------- + .align 8 + .global put_pixels8_y2_arm +put_pixels8_y2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + mov r3, r3, lsr #1 + ldr r12, [r5] + add r5, r5, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5} + add r1, r1, r2 +6: ldmia r1, {r6-r7} + add r1, r1, r2 + pld [r1] + RND_AVG32 r8, r9, r4, r5, r6, r7, r12 + ldmia r1, {r4-r5} + add r1, r1, r2 + stmia r0, {r8-r9} + add r0, r0, r2 + pld [r1] + RND_AVG32 r8, r9, r6, r7, r4, r5, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +2: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r7, r8, r9 + RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 + subs r3, r3, #1 + RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +3: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r7, r8, r9 + RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 + subs r3, r3, #1 + RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +4: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r7, r8, r9 + RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 + subs r3, r3, #1 + RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + + .align 8 +5: + .word 0xFEFEFEFE + .word 2b + .word 3b + .word 4b + + .align 8 + .global put_no_rnd_pixels8_y2_arm +put_no_rnd_pixels8_y2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11,lr} @ R14 is also called LR + adr r5, 5f + ands r4, r1, #3 + mov r3, r3, lsr #1 + ldr r12, [r5] + add r5, r5, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + ldmia r1, {r4-r5} + add r1, r1, r2 +6: ldmia r1, {r6-r7} + add r1, r1, r2 + pld [r1] + NO_RND_AVG32 r8, r9, r4, r5, r6, r7, r12 + ldmia r1, {r4-r5} + add r1, r1, r2 + stmia r0, {r8-r9} + add r0, r0, r2 + pld [r1] + NO_RND_AVG32 r8, r9, r6, r7, r4, r5, r12 + subs r3, r3, #1 + stmia r0, {r8-r9} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +2: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r7, r8, r9 + NO_RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 1, r4, r5, r6 + subs r3, r3, #1 + NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +3: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r7, r8, r9 + NO_RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 2, r4, r5, r6 + subs r3, r3, #1 + NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +4: + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 +6: ldmia r1, {r7-r9} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r7, r8, r9 + NO_RND_AVG32 r10, r11, r4, r5, r7, r8, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + ldmia r1, {r4-r6} + add r1, r1, r2 + pld [r1] + ADJ_ALIGN_DOUBLEWORD 3, r4, r5, r6 + subs r3, r3, #1 + NO_RND_AVG32 r10, r11, r7, r8, r4, r5, r12 + stmia r0, {r10-r11} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} + .align 8 +5: + .word 0xFEFEFEFE + .word 2b + .word 3b + .word 4b + +@ ---------------------------------------------------------------- +.macro RND_XY2_IT align, rnd + @ l1= (a & 0x03030303) + (b & 0x03030303) ?(+ 0x02020202) + @ h1= ((a & 0xFCFCFCFCUL) >> 2) + ((b & 0xFCFCFCFCUL) >> 2) +.if \align == 0 + ldmia r1, {r6-r8} +.elseif \align == 3 + ldmia r1, {r5-r7} +.else + ldmia r1, {r8-r10} +.endif + add r1, r1, r2 + pld [r1] +.if \align == 0 + ADJ_ALIGN_DOUBLEWORD_D 1, r4, r5, r6, r7, r8 +.elseif \align == 1 + ADJ_ALIGN_DOUBLEWORD_D 1, r4, r5, r8, r9, r10 + ADJ_ALIGN_DOUBLEWORD_D 2, r6, r7, r8, r9, r10 +.elseif \align == 2 + ADJ_ALIGN_DOUBLEWORD_D 2, r4, r5, r8, r9, r10 + ADJ_ALIGN_DOUBLEWORD_D 3, r6, r7, r8, r9, r10 +.elseif \align == 3 + ADJ_ALIGN_DOUBLEWORD_D 3, r4, r5, r5, r6, r7 +.endif + ldr r14, [r12, #0] @ 0x03030303 + tst r3, #1 + and r8, r4, r14 + and r9, r5, r14 + and r10, r6, r14 + and r11, r7, r14 +.if \rnd == 1 + ldreq r14, [r12, #16] @ 0x02020202 +.else + ldreq r14, [r12, #28] @ 0x01010101 +.endif + add r8, r8, r10 + add r9, r9, r11 + addeq r8, r8, r14 + addeq r9, r9, r14 + ldr r14, [r12, #20] @ 0xFCFCFCFC >> 2 + and r4, r14, r4, lsr #2 + and r5, r14, r5, lsr #2 + and r6, r14, r6, lsr #2 + and r7, r14, r7, lsr #2 + add r10, r4, r6 + add r11, r5, r7 +.endm + +.macro RND_XY2_EXPAND align, rnd + RND_XY2_IT \align, \rnd +6: stmfd sp!, {r8-r11} + RND_XY2_IT \align, \rnd + ldmfd sp!, {r4-r7} + add r4, r4, r8 + add r5, r5, r9 + add r6, r6, r10 + add r7, r7, r11 + ldr r14, [r12, #24] @ 0x0F0F0F0F + and r4, r14, r4, lsr #2 + and r5, r14, r5, lsr #2 + add r4, r4, r6 + add r5, r5, r7 + subs r3, r3, #1 + stmia r0, {r4-r5} + add r0, r0, r2 + bne 6b + ldmfd sp!, {r4-r11,pc} +.endm + + .align 8 + .global put_pixels8_xy2_arm +put_pixels8_xy2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11,lr} @ R14 is also called LR + adrl r12, 5f + ands r4, r1, #3 + add r5, r12, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + RND_XY2_EXPAND 0, 1 + + .align 8 +2: + RND_XY2_EXPAND 1, 1 + + .align 8 +3: + RND_XY2_EXPAND 2, 1 + + .align 8 +4: + RND_XY2_EXPAND 3, 1 + +5: + .word 0x03030303 + .word 2b + .word 3b + .word 4b + .word 0x02020202 + .word 0xFCFCFCFC >> 2 + .word 0x0F0F0F0F + .word 0x01010101 + + .align 8 + .global put_no_rnd_pixels8_xy2_arm +put_no_rnd_pixels8_xy2_arm: + @ void func(uint8_t *block, const uint8_t *pixels, int line_size, int h) + @ block = word aligned, pixles = unaligned + pld [r1] + stmfd sp!, {r4-r11,lr} @ R14 is also called LR + adrl r12, 5f + ands r4, r1, #3 + add r5, r12, r4, lsl #2 + bic r1, r1, #3 + ldrne pc, [r5] +1: + RND_XY2_EXPAND 0, 0 + + .align 8 +2: + RND_XY2_EXPAND 1, 0 + + .align 8 +3: + RND_XY2_EXPAND 2, 0 + + .align 8 +4: + RND_XY2_EXPAND 3, 0 + +5: + .word 0x03030303 + .word 2b + .word 3b + .word 4b + .word 0x02020202 + .word 0xFCFCFCFC >> 2 + .word 0x0F0F0F0F + .word 0x01010101 diff --git a/mpeg4/src/libavcodec/armv4l/dsputil_iwmmxt.c b/mpeg4/src/libavcodec/armv4l/dsputil_iwmmxt.c new file mode 100644 index 00000000..460b7a84 --- /dev/null +++ b/mpeg4/src/libavcodec/armv4l/dsputil_iwmmxt.c @@ -0,0 +1,186 @@ +/* + * iWMMXt optimized DSP utils + * Copyright (c) 2004 AGAWA Koji + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../dsputil.h" + +#define DEF(x, y) x ## _no_rnd_ ## y ##_iwmmxt +#define SET_RND(regd) __asm__ __volatile__ ("mov r12, #1 \n\t tbcsth " #regd ", r12":::"r12"); +#define WAVG2B "wavg2b" +#include "dsputil_iwmmxt_rnd.h" +#undef DEF +#undef SET_RND +#undef WAVG2B + +#define DEF(x, y) x ## _ ## y ##_iwmmxt +#define SET_RND(regd) __asm__ __volatile__ ("mov r12, #2 \n\t tbcsth " #regd ", r12":::"r12"); +#define WAVG2B "wavg2br" +#include "dsputil_iwmmxt_rnd.h" +#undef DEF +#undef SET_RND +#undef WAVG2BR + +// need scheduling +#define OP(AVG) \ + asm volatile ( \ + /* alignment */ \ + "and r12, %[pixels], #7 \n\t" \ + "bic %[pixels], %[pixels], #7 \n\t" \ + "tmcr wcgr1, r12 \n\t" \ + \ + "wldrd wr0, [%[pixels]] \n\t" \ + "wldrd wr1, [%[pixels], #8] \n\t" \ + "add %[pixels], %[pixels], %[line_size] \n\t" \ + "walignr1 wr4, wr0, wr1 \n\t" \ + \ + "1: \n\t" \ + \ + "wldrd wr2, [%[pixels]] \n\t" \ + "wldrd wr3, [%[pixels], #8] \n\t" \ + "add %[pixels], %[pixels], %[line_size] \n\t" \ + "pld [%[pixels]] \n\t" \ + "walignr1 wr5, wr2, wr3 \n\t" \ + AVG " wr6, wr4, wr5 \n\t" \ + "wstrd wr6, [%[block]] \n\t" \ + "add %[block], %[block], %[line_size] \n\t" \ + \ + "wldrd wr0, [%[pixels]] \n\t" \ + "wldrd wr1, [%[pixels], #8] \n\t" \ + "add %[pixels], %[pixels], %[line_size] \n\t" \ + "walignr1 wr4, wr0, wr1 \n\t" \ + "pld [%[pixels]] \n\t" \ + AVG " wr6, wr4, wr5 \n\t" \ + "wstrd wr6, [%[block]] \n\t" \ + "add %[block], %[block], %[line_size] \n\t" \ + \ + "subs %[h], %[h], #2 \n\t" \ + "bne 1b \n\t" \ + : [block]"+r"(block), [pixels]"+r"(pixels), [h]"+r"(h) \ + : [line_size]"r"(line_size) \ + : "memory", "r12"); +void put_pixels8_y2_iwmmxt(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + OP("wavg2br"); +} +void put_no_rnd_pixels8_y2_iwmmxt(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + OP("wavg2b"); +} +#undef OP + +void add_pixels_clamped_iwmmxt(const DCTELEM *block, uint8_t *pixels, int line_size) +{ + uint8_t *pixels2 = pixels + line_size; + + __asm__ __volatile__ ( + "mov r12, #4 \n\t" + "1: \n\t" + "pld [%[pixels], %[line_size2]] \n\t" + "pld [%[pixels2], %[line_size2]] \n\t" + "wldrd wr4, [%[pixels]] \n\t" + "wldrd wr5, [%[pixels2]] \n\t" + "pld [%[block], #32] \n\t" + "wunpckelub wr6, wr4 \n\t" + "wldrd wr0, [%[block]] \n\t" + "wunpckehub wr7, wr4 \n\t" + "wldrd wr1, [%[block], #8] \n\t" + "wunpckelub wr8, wr5 \n\t" + "wldrd wr2, [%[block], #16] \n\t" + "wunpckehub wr9, wr5 \n\t" + "wldrd wr3, [%[block], #24] \n\t" + "add %[block], %[block], #32 \n\t" + "waddhss wr10, wr0, wr6 \n\t" + "waddhss wr11, wr1, wr7 \n\t" + "waddhss wr12, wr2, wr8 \n\t" + "waddhss wr13, wr3, wr9 \n\t" + "wpackhus wr14, wr10, wr11 \n\t" + "wpackhus wr15, wr12, wr13 \n\t" + "wstrd wr14, [%[pixels]] \n\t" + "add %[pixels], %[pixels], %[line_size2] \n\t" + "subs r12, r12, #1 \n\t" + "wstrd wr15, [%[pixels2]] \n\t" + "add %[pixels2], %[pixels2], %[line_size2] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [pixels2]"+r"(pixels2) + : [line_size2]"r"(line_size << 1) + : "cc", "memory", "r12"); +} + +static void nop(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + return; +} + +int mm_flags; /* multimedia extension flags */ + +int mm_support(void) +{ + return 0; /* TODO, implement proper detection */ +} + +void dsputil_init_iwmmxt(DSPContext* c, AVCodecContext *avctx) +{ + mm_flags = mm_support(); + + if (avctx->dsp_mask) { + if (avctx->dsp_mask & FF_MM_FORCE) + mm_flags |= (avctx->dsp_mask & 0xffff); + else + mm_flags &= ~(avctx->dsp_mask & 0xffff); + } + + if (!(mm_flags & MM_IWMMXT)) return; + + c->add_pixels_clamped = add_pixels_clamped_iwmmxt; + + c->put_pixels_tab[0][0] = put_pixels16_iwmmxt; + c->put_pixels_tab[0][1] = put_pixels16_x2_iwmmxt; + c->put_pixels_tab[0][2] = put_pixels16_y2_iwmmxt; + c->put_pixels_tab[0][3] = put_pixels16_xy2_iwmmxt; + c->put_no_rnd_pixels_tab[0][0] = put_pixels16_iwmmxt; + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_iwmmxt; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_iwmmxt; + c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_iwmmxt; + + c->put_pixels_tab[1][0] = put_pixels8_iwmmxt; + c->put_pixels_tab[1][1] = put_pixels8_x2_iwmmxt; + c->put_pixels_tab[1][2] = put_pixels8_y2_iwmmxt; + c->put_pixels_tab[1][3] = put_pixels8_xy2_iwmmxt; + c->put_no_rnd_pixels_tab[1][0] = put_pixels8_iwmmxt; + c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_iwmmxt; + c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_iwmmxt; + c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_iwmmxt; + + c->avg_pixels_tab[0][0] = avg_pixels16_iwmmxt; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_iwmmxt; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_iwmmxt; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_iwmmxt; + c->avg_no_rnd_pixels_tab[0][0] = avg_pixels16_iwmmxt; + c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x2_iwmmxt; + c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y2_iwmmxt; + c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy2_iwmmxt; + + c->avg_pixels_tab[1][0] = avg_pixels8_iwmmxt; + c->avg_pixels_tab[1][1] = avg_pixels8_x2_iwmmxt; + c->avg_pixels_tab[1][2] = avg_pixels8_y2_iwmmxt; + c->avg_pixels_tab[1][3] = avg_pixels8_xy2_iwmmxt; + c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels8_iwmmxt; + c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels8_x2_iwmmxt; + c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels8_y2_iwmmxt; + c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels8_xy2_iwmmxt; +} diff --git a/mpeg4/src/libavcodec/armv4l/dsputil_iwmmxt_rnd.h b/mpeg4/src/libavcodec/armv4l/dsputil_iwmmxt_rnd.h new file mode 100644 index 00000000..ca49a76b --- /dev/null +++ b/mpeg4/src/libavcodec/armv4l/dsputil_iwmmxt_rnd.h @@ -0,0 +1,1093 @@ +void DEF(put, pixels8)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + __asm__ __volatile__ ( + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r4, %[pixels], %[line_size] \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "1: \n\t" + "wldrd wr0, [%[pixels]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wldrd wr1, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr3, [r4] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wldrd wr4, [r4, #8] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr8, wr0, wr1 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr10, wr3, wr4 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr10, [r5] \n\t" + "add r5, r5, %[line_size] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [line_size]"+r"(stride), [h]"+r"(h) + : + : "memory", "r4", "r5", "r12"); +} + +void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + __asm__ __volatile__ ( + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r4, %[pixels], %[line_size] \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "1: \n\t" + "wldrd wr0, [%[pixels]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wldrd wr1, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr3, [r4] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wldrd wr4, [r4, #8] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr8, wr0, wr1 \n\t" + "wldrd wr0, [%[block]] \n\t" + "wldrd wr2, [r5] \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr10, wr3, wr4 \n\t" + WAVG2B" wr8, wr8, wr0 \n\t" + WAVG2B" wr10, wr10, wr2 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr10, [r5] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "add r5, r5, %[line_size] \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [line_size]"+r"(stride), [h]"+r"(h) + : + : "memory", "r4", "r5", "r12"); +} + +void DEF(put, pixels16)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + __asm__ __volatile__ ( + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r4, %[pixels], %[line_size] \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "1: \n\t" + "wldrd wr0, [%[pixels]] \n\t" + "wldrd wr1, [%[pixels], #8] \n\t" + "subs %[h], %[h], #2 \n\t" + "wldrd wr2, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr3, [r4] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr8, wr0, wr1 \n\t" + "wldrd wr4, [r4, #8] \n\t" + "walignr1 wr9, wr1, wr2 \n\t" + "wldrd wr5, [r4, #16] \n\t" + "add r4, r4, %[line_size] \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr10, wr3, wr4 \n\t" + "wstrd wr8, [%[block]] \n\t" + "walignr1 wr11, wr4, wr5 \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr10, [r5] \n\t" + "wstrd wr11, [r5, #8] \n\t" + "add r5, r5, %[line_size] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [line_size]"+r"(stride), [h]"+r"(h) + : + : "memory", "r4", "r5", "r12"); +} + +void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + __asm__ __volatile__ ( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "1: \n\t" + "wldrd wr0, [%[pixels]] \n\t" + "wldrd wr1, [%[pixels], #8] \n\t" + "subs %[h], %[h], #2 \n\t" + "wldrd wr2, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr3, [r4] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr8, wr0, wr1 \n\t" + "wldrd wr4, [r4, #8] \n\t" + "walignr1 wr9, wr1, wr2 \n\t" + "wldrd wr5, [r4, #16] \n\t" + "add r4, r4, %[line_size] \n\t" + "wldrd wr0, [%[block]] \n\t" + "pld [r4] \n\t" + "wldrd wr1, [%[block], #8] \n\t" + "pld [r4, #32] \n\t" + "wldrd wr2, [r5] \n\t" + "walignr1 wr10, wr3, wr4 \n\t" + "wldrd wr3, [r5, #8] \n\t" + WAVG2B" wr8, wr8, wr0 \n\t" + WAVG2B" wr9, wr9, wr1 \n\t" + WAVG2B" wr10, wr10, wr2 \n\t" + "wstrd wr8, [%[block]] \n\t" + "walignr1 wr11, wr4, wr5 \n\t" + WAVG2B" wr11, wr11, wr3 \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr10, [r5] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "wstrd wr11, [r5, #8] \n\t" + "add r5, r5, %[line_size] \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + "bne 1b \n\t" + : [block]"+r"(block), [pixels]"+r"(pixels), [line_size]"+r"(stride), [h]"+r"(h) + : + : "memory", "r4", "r5", "r12"); +} + +void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "tmcr wcgr2, r12 \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr13, [r4] \n\t" + "pld [%[pixels]] \n\t" + "wldrd wr14, [r4, #8] \n\t" + "pld [%[pixels], #32] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr2, wr13, wr14 \n\t" + "wmoveq wr4, wr11 \n\t" + "wmoveq wr6, wr14 \n\t" + "walignr2ne wr4, wr10, wr11 \n\t" + "walignr2ne wr6, wr13, wr14 \n\t" + WAVG2B" wr0, wr0, wr4 \n\t" + WAVG2B" wr2, wr2, wr6 \n\t" + "wstrd wr0, [%[block]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr2, [r5] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "add r5, r5, %[line_size] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "tmcr wcgr2, r12 \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr13, [r4] \n\t" + "pld [%[pixels]] \n\t" + "wldrd wr14, [r4, #8] \n\t" + "pld [%[pixels], #32] \n\t" + "wldrd wr15, [r4, #16] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + "walignr1 wr2, wr13, wr14 \n\t" + "walignr1 wr3, wr14, wr15 \n\t" + "wmoveq wr4, wr11 \n\t" + "wmoveq wr5, wr12 \n\t" + "wmoveq wr6, wr14 \n\t" + "wmoveq wr7, wr15 \n\t" + "walignr2ne wr4, wr10, wr11 \n\t" + "walignr2ne wr5, wr11, wr12 \n\t" + "walignr2ne wr6, wr13, wr14 \n\t" + "walignr2ne wr7, wr14, wr15 \n\t" + WAVG2B" wr0, wr0, wr4 \n\t" + WAVG2B" wr1, wr1, wr5 \n\t" + "wstrd wr0, [%[block]] \n\t" + WAVG2B" wr2, wr2, wr6 \n\t" + "wstrd wr1, [%[block], #8] \n\t" + WAVG2B" wr3, wr3, wr7 \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr2, [r5] \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr3, [r5, #8] \n\t" + "add r5, r5, %[line_size] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "tmcr wcgr2, r12 \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr13, [r4] \n\t" + "pld [%[pixels]] \n\t" + "wldrd wr14, [r4, #8] \n\t" + "pld [%[pixels], #32] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr2, wr13, wr14 \n\t" + "wmoveq wr4, wr11 \n\t" + "wmoveq wr6, wr14 \n\t" + "walignr2ne wr4, wr10, wr11 \n\t" + "wldrd wr10, [%[block]] \n\t" + "walignr2ne wr6, wr13, wr14 \n\t" + "wldrd wr12, [r5] \n\t" + WAVG2B" wr0, wr0, wr4 \n\t" + WAVG2B" wr2, wr2, wr6 \n\t" + WAVG2B" wr0, wr0, wr10 \n\t" + WAVG2B" wr2, wr2, wr12 \n\t" + "wstrd wr0, [%[block]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr2, [r5] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "add r5, r5, %[line_size] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "add r4, %[pixels], %[line_size]\n\t" + "tmcr wcgr2, r12 \n\t" + "add r5, %[block], %[line_size] \n\t" + "mov %[line_size], %[line_size], lsl #1 \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "wldrd wr13, [r4] \n\t" + "pld [%[pixels]] \n\t" + "wldrd wr14, [r4, #8] \n\t" + "pld [%[pixels], #32] \n\t" + "wldrd wr15, [r4, #16] \n\t" + "add r4, r4, %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [r4] \n\t" + "pld [r4, #32] \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + "walignr1 wr2, wr13, wr14 \n\t" + "walignr1 wr3, wr14, wr15 \n\t" + "wmoveq wr4, wr11 \n\t" + "wmoveq wr5, wr12 \n\t" + "wmoveq wr6, wr14 \n\t" + "wmoveq wr7, wr15 \n\t" + "walignr2ne wr4, wr10, wr11 \n\t" + "walignr2ne wr5, wr11, wr12 \n\t" + "walignr2ne wr6, wr13, wr14 \n\t" + "walignr2ne wr7, wr14, wr15 \n\t" + "wldrd wr10, [%[block]] \n\t" + WAVG2B" wr0, wr0, wr4 \n\t" + "wldrd wr11, [%[block], #8] \n\t" + WAVG2B" wr1, wr1, wr5 \n\t" + "wldrd wr12, [r5] \n\t" + WAVG2B" wr2, wr2, wr6 \n\t" + "wldrd wr13, [r5, #8] \n\t" + WAVG2B" wr3, wr3, wr7 \n\t" + WAVG2B" wr0, wr0, wr10 \n\t" + WAVG2B" wr1, wr1, wr11 \n\t" + WAVG2B" wr2, wr2, wr12 \n\t" + WAVG2B" wr3, wr3, wr13 \n\t" + "wstrd wr0, [%[block]] \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr1, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wstrd wr2, [r5] \n\t" + "pld [%[block]] \n\t" + "wstrd wr3, [r5, #8] \n\t" + "add r5, r5, %[line_size] \n\t" + "pld [%[block], #32] \n\t" + "pld [r5] \n\t" + "pld [r5, #32] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + :"r4", "r5", "r12", "memory"); +} + +void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "pld [%[block]] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr4, wr10, wr11 \n\t" + "wldrd wr10, [%[block]] \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr8, wr8, wr10 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "pld [%[block]] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "wldrd wr10, [%[block]] \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr8, wr8, wr10 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "subs %[h], %[h], #2 \n\t" + "pld [%[block]] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "cc", "memory", "r12"); +} + +void DEF(put, pixels16_y2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr4, wr10, wr11 \n\t" + "walignr1 wr5, wr11, wr12 \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr9, wr1, wr5 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr9, wr1, wr5 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "subs %[h], %[h], #2 \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(avg, pixels16_y2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + int stride = line_size; + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "and r12, %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "pld [%[block]] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + + "1: \n\t" + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr4, wr10, wr11 \n\t" + "walignr1 wr5, wr11, wr12 \n\t" + "wldrd wr10, [%[block]] \n\t" + "wldrd wr11, [%[block], #8] \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr9, wr1, wr5 \n\t" + WAVG2B" wr8, wr8, wr10 \n\t" + WAVG2B" wr9, wr9, wr11 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "wldrd wr10, [%[pixels]] \n\t" + "wldrd wr11, [%[pixels], #8] \n\t" + "pld [%[block]] \n\t" + "wldrd wr12, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr0, wr10, wr11 \n\t" + "walignr1 wr1, wr11, wr12 \n\t" + "wldrd wr10, [%[block]] \n\t" + "wldrd wr11, [%[block], #8] \n\t" + WAVG2B" wr8, wr0, wr4 \n\t" + WAVG2B" wr9, wr1, wr5 \n\t" + WAVG2B" wr8, wr8, wr10 \n\t" + WAVG2B" wr9, wr9, wr11 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "subs %[h], %[h], #2 \n\t" + "pld [%[block]] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block), [line_size]"+r"(stride) + : + : "r4", "r5", "r12", "memory"); +} + +void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "mov r12, #2 \n\t" + "pld [%[pixels], #32] \n\t" + "tmcr wcgr0, r12 \n\t" /* for shift value */ + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "add r12, r12, #1 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "tmcr wcgr2, r12 \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "cmp r12, #8 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + + "1: \n\t" + // [wr0 wr1 wr2 wr3] + // [wr4 wr5 wr6 wr7] <= * + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr6, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr4, wr6 \n\t" + "wunpckehub wr5, wr6 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr4, wr4, wr8 \n\t" + "waddhus wr5, wr5, wr9 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "subs %[h], %[h], #2 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block) + : [line_size]"r"(line_size) + : "r12", "memory"); +} + +void DEF(put, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[pixels]] \n\t" + "mov r12, #2 \n\t" + "pld [%[pixels], #32] \n\t" + "tmcr wcgr0, r12 \n\t" /* for shift value */ + /* alignment */ + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "tmcr wcgr2, r12 \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr3, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr2, wr3 \n\t" + "wunpckehub wr3, wr3 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr2, wr2, wr10 \n\t" + "waddhus wr3, wr3, wr11 \n\t" + + "1: \n\t" + // [wr0 wr1 wr2 wr3] + // [wr4 wr5 wr6 wr7] <= * + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr6, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr7, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr4, wr6 \n\t" + "wunpckehub wr5, wr6 \n\t" + "wunpckelub wr6, wr7 \n\t" + "wunpckehub wr7, wr7 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr4, wr4, wr8 \n\t" + "waddhus wr5, wr5, wr9 \n\t" + "waddhus wr6, wr6, wr10 \n\t" + "waddhus wr7, wr7, wr11 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr10, wr2, wr6 \n\t" + "waddhus wr11, wr3, wr7 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "waddhus wr10, wr10, wr15 \n\t" + "waddhus wr11, wr11, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wsrlhg wr10, wr10, wcgr0 \n\t" + "wsrlhg wr11, wr11, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wpackhus wr9, wr10, wr11 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr3, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr2, wr3 \n\t" + "wunpckehub wr3, wr3 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr2, wr2, wr10 \n\t" + "waddhus wr3, wr3, wr11 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr10, wr2, wr6 \n\t" + "waddhus wr11, wr3, wr7 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "waddhus wr10, wr10, wr15 \n\t" + "waddhus wr11, wr11, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wsrlhg wr10, wr10, wcgr0 \n\t" + "wsrlhg wr11, wr11, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wpackhus wr9, wr10, wr11 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + "subs %[h], %[h], #2 \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block) + : [line_size]"r"(line_size) + : "r12", "memory"); +} + +void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "pld [%[pixels]] \n\t" + "mov r12, #2 \n\t" + "pld [%[pixels], #32] \n\t" + "tmcr wcgr0, r12 \n\t" /* for shift value */ + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "add r12, r12, #1 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "tmcr wcgr2, r12 \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "cmp r12, #8 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + + "1: \n\t" + // [wr0 wr1 wr2 wr3] + // [wr4 wr5 wr6 wr7] <= * + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr6, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr4, wr6 \n\t" + "wunpckehub wr5, wr6 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr4, wr4, wr8 \n\t" + "waddhus wr5, wr5, wr9 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "wldrd wr12, [%[block]] \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + WAVG2B" wr8, wr8, wr12 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "wldrd wr12, [%[pixels]] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr13, [%[pixels], #8] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "wmoveq wr10, wr13 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "wldrd wr12, [%[block]] \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "subs %[h], %[h], #2 \n\t" + WAVG2B" wr8, wr8, wr12 \n\t" + "wstrd wr8, [%[block]] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block) + : [line_size]"r"(line_size) + : "r12", "memory"); +} + +void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, const int line_size, int h) +{ + // [wr0 wr1 wr2 wr3] for previous line + // [wr4 wr5 wr6 wr7] for current line + SET_RND(wr15); // =2 for rnd and =1 for no_rnd version + __asm__ __volatile__( + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "pld [%[pixels]] \n\t" + "mov r12, #2 \n\t" + "pld [%[pixels], #32] \n\t" + "tmcr wcgr0, r12 \n\t" /* for shift value */ + /* alignment */ + "and r12, %[pixels], #7 \n\t" + "bic %[pixels], %[pixels], #7 \n\t" + "tmcr wcgr1, r12 \n\t" + "add r12, r12, #1 \n\t" + "tmcr wcgr2, r12 \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "pld [%[pixels]] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr3, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr2, wr3 \n\t" + "wunpckehub wr3, wr3 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr2, wr2, wr10 \n\t" + "waddhus wr3, wr3, wr11 \n\t" + + "1: \n\t" + // [wr0 wr1 wr2 wr3] + // [wr4 wr5 wr6 wr7] <= * + "wldrd wr12, [%[pixels]] \n\t" + "cmp r12, #8 \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr6, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr7, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr4, wr6 \n\t" + "wunpckehub wr5, wr6 \n\t" + "wunpckelub wr6, wr7 \n\t" + "wunpckehub wr7, wr7 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr4, wr4, wr8 \n\t" + "waddhus wr5, wr5, wr9 \n\t" + "waddhus wr6, wr6, wr10 \n\t" + "waddhus wr7, wr7, wr11 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr10, wr2, wr6 \n\t" + "waddhus wr11, wr3, wr7 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "waddhus wr10, wr10, wr15 \n\t" + "waddhus wr11, wr11, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wldrd wr12, [%[block]] \n\t" + "wldrd wr13, [%[block], #8] \n\t" + "wsrlhg wr10, wr10, wcgr0 \n\t" + "wsrlhg wr11, wr11, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wpackhus wr9, wr10, wr11 \n\t" + WAVG2B" wr8, wr8, wr12 \n\t" + WAVG2B" wr9, wr9, wr13 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + + // [wr0 wr1 wr2 wr3] <= * + // [wr4 wr5 wr6 wr7] + "wldrd wr12, [%[pixels]] \n\t" + "pld [%[block]] \n\t" + "wldrd wr13, [%[pixels], #8] \n\t" + "pld [%[block], #32] \n\t" + "wldrd wr14, [%[pixels], #16] \n\t" + "add %[pixels], %[pixels], %[line_size] \n\t" + "walignr1 wr2, wr12, wr13 \n\t" + "pld [%[pixels]] \n\t" + "pld [%[pixels], #32] \n\t" + "walignr1 wr3, wr13, wr14 \n\t" + "wmoveq wr10, wr13 \n\t" + "wmoveq wr11, wr14 \n\t" + "walignr2ne wr10, wr12, wr13 \n\t" + "walignr2ne wr11, wr13, wr14 \n\t" + "wunpckelub wr0, wr2 \n\t" + "wunpckehub wr1, wr2 \n\t" + "wunpckelub wr2, wr3 \n\t" + "wunpckehub wr3, wr3 \n\t" + "wunpckelub wr8, wr10 \n\t" + "wunpckehub wr9, wr10 \n\t" + "wunpckelub wr10, wr11 \n\t" + "wunpckehub wr11, wr11 \n\t" + "waddhus wr0, wr0, wr8 \n\t" + "waddhus wr1, wr1, wr9 \n\t" + "waddhus wr2, wr2, wr10 \n\t" + "waddhus wr3, wr3, wr11 \n\t" + "waddhus wr8, wr0, wr4 \n\t" + "waddhus wr9, wr1, wr5 \n\t" + "waddhus wr10, wr2, wr6 \n\t" + "waddhus wr11, wr3, wr7 \n\t" + "waddhus wr8, wr8, wr15 \n\t" + "waddhus wr9, wr9, wr15 \n\t" + "waddhus wr10, wr10, wr15 \n\t" + "waddhus wr11, wr11, wr15 \n\t" + "wsrlhg wr8, wr8, wcgr0 \n\t" + "wsrlhg wr9, wr9, wcgr0 \n\t" + "wldrd wr12, [%[block]] \n\t" + "wldrd wr13, [%[block], #8] \n\t" + "wsrlhg wr10, wr10, wcgr0 \n\t" + "wsrlhg wr11, wr11, wcgr0 \n\t" + "wpackhus wr8, wr8, wr9 \n\t" + "wpackhus wr9, wr10, wr11 \n\t" + WAVG2B" wr8, wr8, wr12 \n\t" + WAVG2B" wr9, wr9, wr13 \n\t" + "wstrd wr8, [%[block]] \n\t" + "wstrd wr9, [%[block], #8] \n\t" + "add %[block], %[block], %[line_size] \n\t" + "subs %[h], %[h], #2 \n\t" + "pld [%[block]] \n\t" + "pld [%[block], #32] \n\t" + "bne 1b \n\t" + : [h]"+r"(h), [pixels]"+r"(pixels), [block]"+r"(block) + : [line_size]"r"(line_size) + : "r12", "memory"); +} diff --git a/mpeg4/src/libavcodec/armv4l/jrevdct_arm.S b/mpeg4/src/libavcodec/armv4l/jrevdct_arm.S new file mode 100644 index 00000000..294ea475 --- /dev/null +++ b/mpeg4/src/libavcodec/armv4l/jrevdct_arm.S @@ -0,0 +1,386 @@ +/* + C-like prototype : + void j_rev_dct_ARM(DCTBLOCK data) + + With DCTBLOCK being a pointer to an array of 64 'signed shorts' + + Copyright (c) 2001 Lionel Ulmer (lionel.ulmer@free.fr / bbrox@bbrox.org) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ +#define FIX_0_298631336 2446 +#define FIX_0_541196100 4433 +#define FIX_0_765366865 6270 +#define FIX_1_175875602 9633 +#define FIX_1_501321110 12299 +#define FIX_2_053119869 16819 +#define FIX_3_072711026 25172 +#define FIX_M_0_390180644 -3196 +#define FIX_M_0_899976223 -7373 +#define FIX_M_1_847759065 -15137 +#define FIX_M_1_961570560 -16069 +#define FIX_M_2_562915447 -20995 +#define FIX_0xFFFF 0xFFFF + +#define FIX_0_298631336_ID 0 +#define FIX_0_541196100_ID 4 +#define FIX_0_765366865_ID 8 +#define FIX_1_175875602_ID 12 +#define FIX_1_501321110_ID 16 +#define FIX_2_053119869_ID 20 +#define FIX_3_072711026_ID 24 +#define FIX_M_0_390180644_ID 28 +#define FIX_M_0_899976223_ID 32 +#define FIX_M_1_847759065_ID 36 +#define FIX_M_1_961570560_ID 40 +#define FIX_M_2_562915447_ID 44 +#define FIX_0xFFFF_ID 48 + .text + .align + + .global j_rev_dct_ARM +j_rev_dct_ARM: + stmdb sp!, { r4 - r12, lr } @ all callee saved regs + + sub sp, sp, #4 @ reserve some space on the stack + str r0, [ sp ] @ save the DCT pointer to the stack + + mov lr, r0 @ lr = pointer to the current row + mov r12, #8 @ r12 = row-counter + add r11, pc, #(const_array-.-8) @ r11 = base pointer to the constants array +row_loop: + ldrsh r0, [lr, # 0] @ r0 = 'd0' + ldrsh r1, [lr, # 8] @ r1 = 'd1' + + @ Optimization for row that have all items except the first set to 0 + @ (this works as the DCTELEMS are always 4-byte aligned) + ldr r5, [lr, # 0] + ldr r2, [lr, # 4] + ldr r3, [lr, # 8] + ldr r4, [lr, #12] + orr r3, r3, r4 + orr r3, r3, r2 + orrs r5, r3, r5 + beq end_of_row_loop @ nothing to be done as ALL of them are '0' + orrs r2, r3, r1 + beq empty_row + + ldrsh r2, [lr, # 2] @ r2 = 'd2' + ldrsh r4, [lr, # 4] @ r4 = 'd4' + ldrsh r6, [lr, # 6] @ r6 = 'd6' + + ldr r3, [r11, #FIX_0_541196100_ID] + add r7, r2, r6 + ldr r5, [r11, #FIX_M_1_847759065_ID] + mul r7, r3, r7 @ r7 = z1 + ldr r3, [r11, #FIX_0_765366865_ID] + mla r6, r5, r6, r7 @ r6 = tmp2 + add r5, r0, r4 @ r5 = tmp0 + mla r2, r3, r2, r7 @ r2 = tmp3 + sub r3, r0, r4 @ r3 = tmp1 + + add r0, r2, r5, lsl #13 @ r0 = tmp10 + rsb r2, r2, r5, lsl #13 @ r2 = tmp13 + add r4, r6, r3, lsl #13 @ r4 = tmp11 + rsb r3, r6, r3, lsl #13 @ r3 = tmp12 + + stmdb sp!, { r0, r2, r3, r4 } @ save on the stack tmp10, tmp13, tmp12, tmp11 + + ldrsh r3, [lr, #10] @ r3 = 'd3' + ldrsh r5, [lr, #12] @ r5 = 'd5' + ldrsh r7, [lr, #14] @ r7 = 'd7' + + add r0, r3, r5 @ r0 = 'z2' + add r2, r1, r7 @ r2 = 'z1' + add r4, r3, r7 @ r4 = 'z3' + add r6, r1, r5 @ r6 = 'z4' + ldr r9, [r11, #FIX_1_175875602_ID] + add r8, r4, r6 @ r8 = z3 + z4 + ldr r10, [r11, #FIX_M_0_899976223_ID] + mul r8, r9, r8 @ r8 = 'z5' + ldr r9, [r11, #FIX_M_2_562915447_ID] + mul r2, r10, r2 @ r2 = 'z1' + ldr r10, [r11, #FIX_M_1_961570560_ID] + mul r0, r9, r0 @ r0 = 'z2' + ldr r9, [r11, #FIX_M_0_390180644_ID] + mla r4, r10, r4, r8 @ r4 = 'z3' + ldr r10, [r11, #FIX_0_298631336_ID] + mla r6, r9, r6, r8 @ r6 = 'z4' + ldr r9, [r11, #FIX_2_053119869_ID] + mla r7, r10, r7, r2 @ r7 = tmp0 + z1 + ldr r10, [r11, #FIX_3_072711026_ID] + mla r5, r9, r5, r0 @ r5 = tmp1 + z2 + ldr r9, [r11, #FIX_1_501321110_ID] + mla r3, r10, r3, r0 @ r3 = tmp2 + z2 + add r7, r7, r4 @ r7 = tmp0 + mla r1, r9, r1, r2 @ r1 = tmp3 + z1 + add r5, r5, r6 @ r5 = tmp1 + add r3, r3, r4 @ r3 = tmp2 + add r1, r1, r6 @ r1 = tmp3 + + ldmia sp!, { r0, r2, r4, r6 } @ r0 = tmp10 / r2 = tmp13 / r4 = tmp12 / r6 = tmp11 + @ r1 = tmp3 / r3 = tmp2 / r5 = tmp1 / r7 = tmp0 + + @ Compute DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS) + add r8, r0, r1 + add r8, r8, #(1<<10) + mov r8, r8, asr #11 + strh r8, [lr, # 0] + + @ Compute DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS) + sub r8, r0, r1 + add r8, r8, #(1<<10) + mov r8, r8, asr #11 + strh r8, [lr, #14] + + @ Compute DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS) + add r8, r6, r3 + add r8, r8, #(1<<10) + mov r8, r8, asr #11 + strh r8, [lr, # 2] + + @ Compute DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS) + sub r8, r6, r3 + add r8, r8, #(1<<10) + mov r8, r8, asr #11 + strh r8, [lr, #12] + + @ Compute DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS) + add r8, r4, r5 + add r8, r8, #(1<<10) + mov r8, r8, asr #11 + strh r8, [lr, # 4] + + @ Compute DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS) + sub r8, r4, r5 + add r8, r8, #(1<<10) + mov r8, r8, asr #11 + strh r8, [lr, #10] + + @ Compute DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS) + add r8, r2, r7 + add r8, r8, #(1<<10) + mov r8, r8, asr #11 + strh r8, [lr, # 6] + + @ Compute DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS) + sub r8, r2, r7 + add r8, r8, #(1<<10) + mov r8, r8, asr #11 + strh r8, [lr, # 8] + + @ End of row loop + add lr, lr, #16 + subs r12, r12, #1 + bne row_loop + beq start_column_loop + +empty_row: + ldr r1, [r11, #FIX_0xFFFF_ID] + mov r0, r0, lsl #2 + and r0, r0, r1 + add r0, r0, r0, lsl #16 + str r0, [lr, # 0] + str r0, [lr, # 4] + str r0, [lr, # 8] + str r0, [lr, #12] + +end_of_row_loop: + @ End of loop + add lr, lr, #16 + subs r12, r12, #1 + bne row_loop + +start_column_loop: + @ Start of column loop + ldr lr, [ sp ] + mov r12, #8 +column_loop: + ldrsh r0, [lr, #( 0*8)] @ r0 = 'd0' + ldrsh r2, [lr, #( 4*8)] @ r2 = 'd2' + ldrsh r4, [lr, #( 8*8)] @ r4 = 'd4' + ldrsh r6, [lr, #(12*8)] @ r6 = 'd6' + + ldr r3, [r11, #FIX_0_541196100_ID] + add r1, r2, r6 + ldr r5, [r11, #FIX_M_1_847759065_ID] + mul r1, r3, r1 @ r1 = z1 + ldr r3, [r11, #FIX_0_765366865_ID] + mla r6, r5, r6, r1 @ r6 = tmp2 + add r5, r0, r4 @ r5 = tmp0 + mla r2, r3, r2, r1 @ r2 = tmp3 + sub r3, r0, r4 @ r3 = tmp1 + + add r0, r2, r5, lsl #13 @ r0 = tmp10 + rsb r2, r2, r5, lsl #13 @ r2 = tmp13 + add r4, r6, r3, lsl #13 @ r4 = tmp11 + rsb r6, r6, r3, lsl #13 @ r6 = tmp12 + + ldrsh r1, [lr, #( 2*8)] @ r1 = 'd1' + ldrsh r3, [lr, #( 6*8)] @ r3 = 'd3' + ldrsh r5, [lr, #(10*8)] @ r5 = 'd5' + ldrsh r7, [lr, #(14*8)] @ r7 = 'd7' + + @ Check for empty odd column (happens about 20 to 25 % of the time according to my stats) + orr r9, r1, r3 + orr r10, r5, r7 + orrs r10, r9, r10 + beq empty_odd_column + + stmdb sp!, { r0, r2, r4, r6 } @ save on the stack tmp10, tmp13, tmp12, tmp11 + + add r0, r3, r5 @ r0 = 'z2' + add r2, r1, r7 @ r2 = 'z1' + add r4, r3, r7 @ r4 = 'z3' + add r6, r1, r5 @ r6 = 'z4' + ldr r9, [r11, #FIX_1_175875602_ID] + add r8, r4, r6 + ldr r10, [r11, #FIX_M_0_899976223_ID] + mul r8, r9, r8 @ r8 = 'z5' + ldr r9, [r11, #FIX_M_2_562915447_ID] + mul r2, r10, r2 @ r2 = 'z1' + ldr r10, [r11, #FIX_M_1_961570560_ID] + mul r0, r9, r0 @ r0 = 'z2' + ldr r9, [r11, #FIX_M_0_390180644_ID] + mla r4, r10, r4, r8 @ r4 = 'z3' + ldr r10, [r11, #FIX_0_298631336_ID] + mla r6, r9, r6, r8 @ r6 = 'z4' + ldr r9, [r11, #FIX_2_053119869_ID] + mla r7, r10, r7, r2 @ r7 = tmp0 + z1 + ldr r10, [r11, #FIX_3_072711026_ID] + mla r5, r9, r5, r0 @ r5 = tmp1 + z2 + ldr r9, [r11, #FIX_1_501321110_ID] + mla r3, r10, r3, r0 @ r3 = tmp2 + z2 + add r7, r7, r4 @ r7 = tmp0 + mla r1, r9, r1, r2 @ r1 = tmp3 + z1 + add r5, r5, r6 @ r5 = tmp1 + add r3, r3, r4 @ r3 = tmp2 + add r1, r1, r6 @ r1 = tmp3 + + ldmia sp!, { r0, r2, r4, r6 } @ r0 = tmp10 / r2 = tmp13 / r4 = tmp11 / r6 = tmp12 + @ r1 = tmp3 / r3 = tmp2 / r5 = tmp1 / r7 = tmp0 + + @ Compute DESCALE(tmp10 + tmp3, CONST_BITS+PASS1_BITS+3) + add r8, r0, r1 + add r8, r8, #(1<<17) + mov r8, r8, asr #18 + strh r8, [lr, #( 0*8)] + + @ Compute DESCALE(tmp10 - tmp3, CONST_BITS+PASS1_BITS+3) + sub r8, r0, r1 + add r8, r8, #(1<<17) + mov r8, r8, asr #18 + strh r8, [lr, #(14*8)] + + @ Compute DESCALE(tmp11 + tmp2, CONST_BITS+PASS1_BITS+3) + add r8, r4, r3 + add r8, r8, #(1<<17) + mov r8, r8, asr #18 + strh r8, [lr, #( 2*8)] + + @ Compute DESCALE(tmp11 - tmp2, CONST_BITS+PASS1_BITS+3) + sub r8, r4, r3 + add r8, r8, #(1<<17) + mov r8, r8, asr #18 + strh r8, [lr, #(12*8)] + + @ Compute DESCALE(tmp12 + tmp1, CONST_BITS+PASS1_BITS+3) + add r8, r6, r5 + add r8, r8, #(1<<17) + mov r8, r8, asr #18 + strh r8, [lr, #( 4*8)] + + @ Compute DESCALE(tmp12 - tmp1, CONST_BITS+PASS1_BITS+3) + sub r8, r6, r5 + add r8, r8, #(1<<17) + mov r8, r8, asr #18 + strh r8, [lr, #(10*8)] + + @ Compute DESCALE(tmp13 + tmp0, CONST_BITS+PASS1_BITS+3) + add r8, r2, r7 + add r8, r8, #(1<<17) + mov r8, r8, asr #18 + strh r8, [lr, #( 6*8)] + + @ Compute DESCALE(tmp13 - tmp0, CONST_BITS+PASS1_BITS+3) + sub r8, r2, r7 + add r8, r8, #(1<<17) + mov r8, r8, asr #18 + strh r8, [lr, #( 8*8)] + + @ End of row loop + add lr, lr, #2 + subs r12, r12, #1 + bne column_loop + beq the_end + +empty_odd_column: + @ Compute DESCALE(tmp10 + tmp3, CONST_BITS+PASS1_BITS+3) + @ Compute DESCALE(tmp10 - tmp3, CONST_BITS+PASS1_BITS+3) + add r0, r0, #(1<<17) + mov r0, r0, asr #18 + strh r0, [lr, #( 0*8)] + strh r0, [lr, #(14*8)] + + @ Compute DESCALE(tmp11 + tmp2, CONST_BITS+PASS1_BITS+3) + @ Compute DESCALE(tmp11 - tmp2, CONST_BITS+PASS1_BITS+3) + add r4, r4, #(1<<17) + mov r4, r4, asr #18 + strh r4, [lr, #( 2*8)] + strh r4, [lr, #(12*8)] + + @ Compute DESCALE(tmp12 + tmp1, CONST_BITS+PASS1_BITS+3) + @ Compute DESCALE(tmp12 - tmp1, CONST_BITS+PASS1_BITS+3) + add r6, r6, #(1<<17) + mov r6, r6, asr #18 + strh r6, [lr, #( 4*8)] + strh r6, [lr, #(10*8)] + + @ Compute DESCALE(tmp13 + tmp0, CONST_BITS+PASS1_BITS+3) + @ Compute DESCALE(tmp13 - tmp0, CONST_BITS+PASS1_BITS+3) + add r2, r2, #(1<<17) + mov r2, r2, asr #18 + strh r2, [lr, #( 6*8)] + strh r2, [lr, #( 8*8)] + + @ End of row loop + add lr, lr, #2 + subs r12, r12, #1 + bne column_loop + +the_end: + @ The end.... + add sp, sp, #4 + ldmia sp!, { r4 - r12, pc } @ restore callee saved regs and return + +const_array: + .align + .word FIX_0_298631336 + .word FIX_0_541196100 + .word FIX_0_765366865 + .word FIX_1_175875602 + .word FIX_1_501321110 + .word FIX_2_053119869 + .word FIX_3_072711026 + .word FIX_M_0_390180644 + .word FIX_M_0_899976223 + .word FIX_M_1_847759065 + .word FIX_M_1_961570560 + .word FIX_M_2_562915447 + .word FIX_0xFFFF diff --git a/mpeg4/src/libavcodec/armv4l/mpegvideo_arm.c b/mpeg4/src/libavcodec/armv4l/mpegvideo_arm.c new file mode 100644 index 00000000..263e3c5b --- /dev/null +++ b/mpeg4/src/libavcodec/armv4l/mpegvideo_arm.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2002 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "../dsputil.h" +#include "../mpegvideo.h" +#include "../avcodec.h" + +extern void MPV_common_init_iwmmxt(MpegEncContext *s); + +void MPV_common_init_armv4l(MpegEncContext *s) +{ +#ifdef HAVE_IWMMXT + MPV_common_init_iwmmxt(s); +#endif +} diff --git a/mpeg4/src/libavcodec/armv4l/mpegvideo_iwmmxt.c b/mpeg4/src/libavcodec/armv4l/mpegvideo_iwmmxt.c new file mode 100644 index 00000000..9724de8c --- /dev/null +++ b/mpeg4/src/libavcodec/armv4l/mpegvideo_iwmmxt.c @@ -0,0 +1,99 @@ +#include "../dsputil.h" +#include "../mpegvideo.h" +#include "../avcodec.h" + +static void dct_unquantize_h263_intra_iwmmxt(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + int level, qmul, qadd; + int nCoeffs; + DCTELEM *block_orig = block; + + assert(s->block_last_index[n]>=0); + + qmul = qscale << 1; + + if (!s->h263_aic) { + if (n < 4) + level = block[0] * s->y_dc_scale; + else + level = block[0] * s->c_dc_scale; + qadd = (qscale - 1) | 1; + }else{ + qadd = 0; + level = block[0]; + } + if(s->ac_pred) + nCoeffs=63; + else + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; + + __asm__ __volatile__ ( +/* "movd %1, %%mm6 \n\t" //qmul */ +/* "packssdw %%mm6, %%mm6 \n\t" */ +/* "packssdw %%mm6, %%mm6 \n\t" */ + "tbcsth wr6, %[qmul] \n\t" +/* "movd %2, %%mm5 \n\t" //qadd */ +/* "packssdw %%mm5, %%mm5 \n\t" */ +/* "packssdw %%mm5, %%mm5 \n\t" */ + "tbcsth wr5, %[qadd] \n\t" + "wzero wr7 \n\t" /* "pxor %%mm7, %%mm7 \n\t" */ + "wzero wr4 \n\t" /* "pxor %%mm4, %%mm4 \n\t" */ + "wsubh wr7, wr5, wr7 \n\t" /* "psubw %%mm5, %%mm7 \n\t" */ + "1: \n\t" + "wldrd wr2, [%[block]] \n\t" /* "movq (%0, %3), %%mm0 \n\t" */ + "wldrd wr3, [%[block], #8] \n\t" /* "movq 8(%0, %3), %%mm1 \n\t" */ + "wmulsl wr0, wr6, wr2 \n\t" /* "pmullw %%mm6, %%mm0 \n\t" */ + "wmulsl wr1, wr6, wr3 \n\t" /* "pmullw %%mm6, %%mm1 \n\t" */ +/* "movq (%0, %3), %%mm2 \n\t" */ +/* "movq 8(%0, %3), %%mm3 \n\t" */ + "wcmpgtsh wr2, wr4, wr2 \n\t" /* "pcmpgtw %%mm4, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 */ + "wcmpgtsh wr3, wr4, wr2 \n\t" /* "pcmpgtw %%mm4, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 */ + "wxor wr0, wr2, wr0 \n\t" /* "pxor %%mm2, %%mm0 \n\t" */ + "wxor wr1, wr3, wr1 \n\t" /* "pxor %%mm3, %%mm1 \n\t" */ + "waddh wr0, wr7, wr0 \n\t" /* "paddw %%mm7, %%mm0 \n\t" */ + "waddh wr1, wr7, wr1 \n\t" /* "paddw %%mm7, %%mm1 \n\t" */ + "wxor wr2, wr0, wr2 \n\t" /* "pxor %%mm0, %%mm2 \n\t" */ + "wxor wr3, wr1, wr3 \n\t" /* "pxor %%mm1, %%mm3 \n\t" */ + "wcmpeqh wr0, wr7, wr0 \n\t" /* "pcmpeqw %%mm7, %%mm0 \n\t" // block[i] == 0 ? -1 : 0 */ + "wcmpeqh wr1, wr7, wr1 \n\t" /* "pcmpeqw %%mm7, %%mm1 \n\t" // block[i] == 0 ? -1 : 0 */ + "wandn wr0, wr2, wr0 \n\t" /* "pandn %%mm2, %%mm0 \n\t" */ + "wandn wr1, wr3, wr1 \n\t" /* "pandn %%mm3, %%mm1 \n\t" */ + "wstrd wr0, [%[block]] \n\t" /* "movq %%mm0, (%0, %3) \n\t" */ + "wstrd wr1, [%[block], #8] \n\t" /* "movq %%mm1, 8(%0, %3) \n\t" */ + "add %[block], %[block], #16 \n\t" /* "addl $16, %3 \n\t" */ + "subs %[i], %[i], #1 \n\t" + "bne 1b \n\t" /* "jng 1b \n\t" */ + :[block]"+r"(block) + :[i]"r"((nCoeffs + 8) / 8), [qmul]"r"(qmul), [qadd]"r"(qadd) + :"memory"); + + block_orig[0] = level; +} + +#if 0 +static void dct_unquantize_h263_inter_iwmmxt(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + int nCoeffs; + + assert(s->block_last_index[n]>=0); + + if(s->ac_pred) + nCoeffs=63; + else + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; + + ippiQuantInvInter_Compact_H263_16s_I(block, nCoeffs+1, qscale); +} +#endif + +void MPV_common_init_iwmmxt(MpegEncContext *s) +{ + if (!(mm_flags & MM_IWMMXT)) return; + + s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_iwmmxt; +#if 0 + s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_iwmmxt; +#endif +} diff --git a/mpeg4/src/libavcodec/armv4l/simple_idct_arm.S b/mpeg4/src/libavcodec/armv4l/simple_idct_arm.S new file mode 100644 index 00000000..43751896 --- /dev/null +++ b/mpeg4/src/libavcodec/armv4l/simple_idct_arm.S @@ -0,0 +1,485 @@ +/* + * simple_idct_arm.S + * Copyright (C) 2002 Frederic 'dilb' Boulay. + * All Rights Reserved. + * + * Author: Frederic Boulay + * + * You can redistribute this file and/or modify + * it under the terms of the GNU General Public License (version 2) + * as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * + * The function defined in this file, is derived from the simple_idct function + * from the libavcodec library part of the ffmpeg project. + */ + +/* useful constants for the algorithm, they are save in __constant_ptr__ at */ +/* the end of the source code.*/ +#define W1 22725 +#define W2 21407 +#define W3 19266 +#define W4 16383 +#define W5 12873 +#define W6 8867 +#define W7 4520 +#define MASK_MSHW 0xFFFF0000 + +/* offsets of the constants in the vector */ +#define offW1 0 +#define offW2 4 +#define offW3 8 +#define offW4 12 +#define offW5 16 +#define offW6 20 +#define offW7 24 +#define offMASK_MSHW 28 + +#define ROW_SHIFT 11 +#define ROW_SHIFT2MSHW (16-11) +#define COL_SHIFT 20 +#define ROW_SHIFTED_1 1024 /* 1<< (ROW_SHIFT-1) */ +#define COL_SHIFTED_1 524288 /* 1<< (COL_SHIFT-1) */ + + + .text + .align + .global simple_idct_ARM + +simple_idct_ARM: + @@ void simple_idct_ARM(int16_t *block) + @@ save stack for reg needed (take all of them), + @@ R0-R3 are scratch regs, so no need to save them, but R0 contains the pointer to block + @@ so it must not be overwritten, if it is not saved!! + @@ R12 is another scratch register, so it should not be saved too + @@ save all registers + stmfd sp!, {r4-r11, r14} @ R14 is also called LR + @@ at this point, R0=block, other registers are free. + add r14, r0, #112 @ R14=&block[8*7], better start from the last row, and decrease the value until row=0, i.e. R12=block. + add r12, pc, #(__constant_ptr__-.-8) @ R12=__constant_ptr__, the vector containing the constants, probably not necessary to reserve a register for it + @@ add 2 temporary variables in the stack: R0 and R14 + sub sp, sp, #8 @ allow 2 local variables + str r0, [sp, #0] @ save block in sp[0] + @@ stack status + @@ sp+4 free + @@ sp+0 R0 (block) + + + @@ at this point, R0=block, R14=&block[56], R12=__const_ptr_, R1-R11 free + + +__row_loop: + @@ read the row and check if it is null, almost null, or not, according to strongarm specs, it is not necessary to optimise ldr accesses (i.e. split 32bits in 2 16bits words), at least it gives more usable registers :) + ldr r1, [r14, #0] @ R1=(int32)(R12)[0]=ROWr32[0] (relative row cast to a 32b pointer) + ldr r2, [r14, #4] @ R2=(int32)(R12)[1]=ROWr32[1] + ldr r3, [r14, #8] @ R3=ROWr32[2] + ldr r4, [r14, #12] @ R4=ROWr32[3] + @@ check if the words are null, if all of them are null, then proceed with next row (branch __end_row_loop), + @@ if ROWr16[0] is the only one not null, then proceed with this special case (branch __almost_empty_row) + @@ else follow the complete algorithm. + @@ at this point, R0=block, R14=&block[n], R12=__const_ptr_, R1=ROWr32[0], R2=ROWr32[1], + @@ R3=ROWr32[2], R4=ROWr32[3], R5-R11 free + orr r5, r4, r3 @ R5=R4 | R3 + orr r5, r5, r2 @ R5=R4 | R3 | R2 + orrs r6, r5, r1 @ Test R5 | R1 (the aim is to check if everything is null) + beq __end_row_loop + mov r7, r1, asr #16 @ R7=R1>>16=ROWr16[1] (evaluate it now, as it could be useful later) + ldrsh r6, [r14, #0] @ R6=ROWr16[0] + orrs r5, r5, r7 @ R5=R4 | R3 | R2 | R7 + beq __almost_empty_row + +__b_evaluation: + @@ at this point, R0=block (temp), R1(free), R2=ROWr32[1], R3=ROWr32[2], R4=ROWr32[3], + @@ R5=(temp), R6=ROWr16[0], R7=ROWr16[1], R8-R11 free, + @@ R12=__const_ptr_, R14=&block[n] + @@ to save some registers/calls, proceed with b0-b3 first, followed by a0-a3 + + @@ MUL16(b0, W1, row[1]); + @@ MUL16(b1, W3, row[1]); + @@ MUL16(b2, W5, row[1]); + @@ MUL16(b3, W7, row[1]); + @@ MAC16(b0, W3, row[3]); + @@ MAC16(b1, -W7, row[3]); + @@ MAC16(b2, -W1, row[3]); + @@ MAC16(b3, -W5, row[3]); + ldr r8, [r12, #offW1] @ R8=W1 + mov r2, r2, asr #16 @ R2=ROWr16[3] + mul r0, r8, r7 @ R0=W1*ROWr16[1]=b0 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle) + ldr r9, [r12, #offW3] @ R9=W3 + ldr r10, [r12, #offW5] @ R10=W5 + mul r1, r9, r7 @ R1=W3*ROWr16[1]=b1 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle) + ldr r11, [r12, #offW7] @ R11=W7 + mul r5, r10, r7 @ R5=W5*ROWr16[1]=b2 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle) + mul r7, r11, r7 @ R7=W7*ROWr16[1]=b3 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle) + teq r2, #0 @ if null avoid muls + mlane r0, r9, r2, r0 @ R0+=W3*ROWr16[3]=b0 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle) + rsbne r2, r2, #0 @ R2=-ROWr16[3] + mlane r1, r11, r2, r1 @ R1-=W7*ROWr16[3]=b1 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle) + mlane r5, r8, r2, r5 @ R5-=W1*ROWr16[3]=b2 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle) + mlane r7, r10, r2, r7 @ R7-=W5*ROWr16[3]=b3 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle) + + @@ at this point, R0=b0, R1=b1, R2 (free), R3=ROWr32[2], R4=ROWr32[3], + @@ R5=b2, R6=ROWr16[0], R7=b3, R8=W1, R9=W3, R10=W5, R11=W7, + @@ R12=__const_ptr_, R14=&block[n] + @@ temp = ((uint32_t*)row)[2] | ((uint32_t*)row)[3]; + @@ if (temp != 0) {} + orrs r2, r3, r4 @ R2=ROWr32[2] | ROWr32[3] + beq __end_b_evaluation + + @@ at this point, R0=b0, R1=b1, R2 (free), R3=ROWr32[2], R4=ROWr32[3], + @@ R5=b2, R6=ROWr16[0], R7=b3, R8=W1, R9=W3, R10=W5, R11=W7, + @@ R12=__const_ptr_, R14=&block[n] + @@ MAC16(b0, W5, row[5]); + @@ MAC16(b2, W7, row[5]); + @@ MAC16(b3, W3, row[5]); + @@ MAC16(b1, -W1, row[5]); + @@ MAC16(b0, W7, row[7]); + @@ MAC16(b2, W3, row[7]); + @@ MAC16(b3, -W1, row[7]); + @@ MAC16(b1, -W5, row[7]); + mov r3, r3, asr #16 @ R3=ROWr16[5] + teq r3, #0 @ if null avoid muls + mlane r0, r10, r3, r0 @ R0+=W5*ROWr16[5]=b0 + mov r4, r4, asr #16 @ R4=ROWr16[7] + mlane r5, r11, r3, r5 @ R5+=W7*ROWr16[5]=b2 + mlane r7, r9, r3, r7 @ R7+=W3*ROWr16[5]=b3 + rsbne r3, r3, #0 @ R3=-ROWr16[5] + mlane r1, r8, r3, r1 @ R7-=W1*ROWr16[5]=b1 + @@ R3 is free now + teq r4, #0 @ if null avoid muls + mlane r0, r11, r4, r0 @ R0+=W7*ROWr16[7]=b0 + mlane r5, r9, r4, r5 @ R5+=W3*ROWr16[7]=b2 + rsbne r4, r4, #0 @ R4=-ROWr16[7] + mlane r7, r8, r4, r7 @ R7-=W1*ROWr16[7]=b3 + mlane r1, r10, r4, r1 @ R1-=W5*ROWr16[7]=b1 + @@ R4 is free now +__end_b_evaluation: + @@ at this point, R0=b0, R1=b1, R2=ROWr32[2] | ROWr32[3] (tmp), R3 (free), R4 (free), + @@ R5=b2, R6=ROWr16[0], R7=b3, R8 (free), R9 (free), R10 (free), R11 (free), + @@ R12=__const_ptr_, R14=&block[n] + +__a_evaluation: + @@ a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1)); + @@ a1 = a0 + W6 * row[2]; + @@ a2 = a0 - W6 * row[2]; + @@ a3 = a0 - W2 * row[2]; + @@ a0 = a0 + W2 * row[2]; + ldr r9, [r12, #offW4] @ R9=W4 + mul r6, r9, r6 @ R6=W4*ROWr16[0] + ldr r10, [r12, #offW6] @ R10=W6 + ldrsh r4, [r14, #4] @ R4=ROWr16[2] (a3 not defined yet) + add r6, r6, #ROW_SHIFTED_1 @ R6=W4*ROWr16[0] + 1<<(ROW_SHIFT-1) (a0) + + mul r11, r10, r4 @ R11=W6*ROWr16[2] + ldr r8, [r12, #offW2] @ R8=W2 + sub r3, r6, r11 @ R3=a0-W6*ROWr16[2] (a2) + @@ temp = ((uint32_t*)row)[2] | ((uint32_t*)row)[3]; + @@ if (temp != 0) {} + teq r2, #0 + beq __end_bef_a_evaluation + + add r2, r6, r11 @ R2=a0+W6*ROWr16[2] (a1) + mul r11, r8, r4 @ R11=W2*ROWr16[2] + sub r4, r6, r11 @ R4=a0-W2*ROWr16[2] (a3) + add r6, r6, r11 @ R6=a0+W2*ROWr16[2] (a0) + + + @@ at this point, R0=b0, R1=b1, R2=a1, R3=a2, R4=a3, + @@ R5=b2, R6=a0, R7=b3, R8=W2, R9=W4, R10=W6, R11 (free), + @@ R12=__const_ptr_, R14=&block[n] + + + @@ a0 += W4*row[4] + @@ a1 -= W4*row[4] + @@ a2 -= W4*row[4] + @@ a3 += W4*row[4] + ldrsh r11, [r14, #8] @ R11=ROWr16[4] + teq r11, #0 @ if null avoid muls + mulne r11, r9, r11 @ R11=W4*ROWr16[4] + @@ R9 is free now + ldrsh r9, [r14, #12] @ R9=ROWr16[6] + addne r6, r6, r11 @ R6+=W4*ROWr16[4] (a0) + subne r2, r2, r11 @ R2-=W4*ROWr16[4] (a1) + subne r3, r3, r11 @ R3-=W4*ROWr16[4] (a2) + addne r4, r4, r11 @ R4+=W4*ROWr16[4] (a3) + @@ W6 alone is no more useful, save W2*ROWr16[6] in it instead + teq r9, #0 @ if null avoid muls + mulne r11, r10, r9 @ R11=W6*ROWr16[6] + addne r6, r6, r11 @ R6+=W6*ROWr16[6] (a0) + mulne r10, r8, r9 @ R10=W2*ROWr16[6] + @@ a0 += W6*row[6]; + @@ a3 -= W6*row[6]; + @@ a1 -= W2*row[6]; + @@ a2 += W2*row[6]; + subne r4, r4, r11 @ R4-=W6*ROWr16[6] (a3) + subne r2, r2, r10 @ R2-=W2*ROWr16[6] (a1) + addne r3, r3, r10 @ R3+=W2*ROWr16[6] (a2) + +__end_a_evaluation: + @@ at this point, R0=b0, R1=b1, R2=a1, R3=a2, R4=a3, + @@ R5=b2, R6=a0, R7=b3, R8 (free), R9 (free), R10 (free), R11 (free), + @@ R12=__const_ptr_, R14=&block[n] + @@ row[0] = (a0 + b0) >> ROW_SHIFT; + @@ row[1] = (a1 + b1) >> ROW_SHIFT; + @@ row[2] = (a2 + b2) >> ROW_SHIFT; + @@ row[3] = (a3 + b3) >> ROW_SHIFT; + @@ row[4] = (a3 - b3) >> ROW_SHIFT; + @@ row[5] = (a2 - b2) >> ROW_SHIFT; + @@ row[6] = (a1 - b1) >> ROW_SHIFT; + @@ row[7] = (a0 - b0) >> ROW_SHIFT; + add r8, r6, r0 @ R8=a0+b0 + add r9, r2, r1 @ R9=a1+b1 + @@ put 2 16 bits half-words in a 32bits word + @@ ROWr32[0]=ROWr16[0] | (ROWr16[1]<<16) (only Little Endian compliant then!!!) + ldr r10, [r12, #offMASK_MSHW] @ R10=0xFFFF0000 + and r9, r10, r9, lsl #ROW_SHIFT2MSHW @ R9=0xFFFF0000 & ((a1+b1)<<5) + mvn r11, r10 @ R11= NOT R10= 0x0000FFFF + and r8, r11, r8, asr #ROW_SHIFT @ R8=0x0000FFFF & ((a0+b0)>>11) + orr r8, r8, r9 + str r8, [r14, #0] + + add r8, r3, r5 @ R8=a2+b2 + add r9, r4, r7 @ R9=a3+b3 + and r9, r10, r9, lsl #ROW_SHIFT2MSHW @ R9=0xFFFF0000 & ((a3+b3)<<5) + and r8, r11, r8, asr #ROW_SHIFT @ R8=0x0000FFFF & ((a2+b2)>>11) + orr r8, r8, r9 + str r8, [r14, #4] + + sub r8, r4, r7 @ R8=a3-b3 + sub r9, r3, r5 @ R9=a2-b2 + and r9, r10, r9, lsl #ROW_SHIFT2MSHW @ R9=0xFFFF0000 & ((a2-b2)<<5) + and r8, r11, r8, asr #ROW_SHIFT @ R8=0x0000FFFF & ((a3-b3)>>11) + orr r8, r8, r9 + str r8, [r14, #8] + + sub r8, r2, r1 @ R8=a1-b1 + sub r9, r6, r0 @ R9=a0-b0 + and r9, r10, r9, lsl #ROW_SHIFT2MSHW @ R9=0xFFFF0000 & ((a0-b0)<<5) + and r8, r11, r8, asr #ROW_SHIFT @ R8=0x0000FFFF & ((a1-b1)>>11) + orr r8, r8, r9 + str r8, [r14, #12] + + bal __end_row_loop + +__almost_empty_row: + @@ the row was empty, except ROWr16[0], now, management of this special case + @@ at this point, R0=block, R14=&block[n], R12=__const_ptr_, R1=ROWr32[0], R2=ROWr32[1], + @@ R3=ROWr32[2], R4=ROWr32[3], R5=(temp), R6=ROWr16[0], R7=ROWr16[1], + @@ R8=0xFFFF (temp), R9-R11 free + mov r8, #0x10000 @ R8=0xFFFF (2 steps needed!) it saves a ldr call (because of delay run). + sub r8, r8, #1 @ R8 is now ready. + and r5, r8, r6, lsl #3 @ R5=R8 & (R6<<3)= (ROWr16[0]<<3) & 0xFFFF + orr r5, r5, r5, lsl #16 @ R5=R5 | (R5<<16) + str r5, [r14, #0] @ R14[0]=ROWr32[0]=R5 + str r5, [r14, #4] @ R14[4]=ROWr32[1]=R5 + str r5, [r14, #8] @ R14[8]=ROWr32[2]=R5 + str r5, [r14, #12] @ R14[12]=ROWr32[3]=R5 + +__end_row_loop: + @@ at this point, R0-R11 (free) + @@ R12=__const_ptr_, R14=&block[n] + ldr r0, [sp, #0] @ R0=block + teq r0, r14 @ compare current &block[8*n] to block, when block is reached, the loop is finished. + sub r14, r14, #16 + bne __row_loop + + + + @@ at this point, R0=block, R1-R11 (free) + @@ R12=__const_ptr_, R14=&block[n] + add r14, r0, #14 @ R14=&block[7], better start from the last col, and decrease the value until col=0, i.e. R14=block. +__col_loop: + +__b_evaluation2: + @@ at this point, R0=block (temp), R1-R11 (free) + @@ R12=__const_ptr_, R14=&block[n] + @@ proceed with b0-b3 first, followed by a0-a3 + @@ MUL16(b0, W1, col[8x1]); + @@ MUL16(b1, W3, col[8x1]); + @@ MUL16(b2, W5, col[8x1]); + @@ MUL16(b3, W7, col[8x1]); + @@ MAC16(b0, W3, col[8x3]); + @@ MAC16(b1, -W7, col[8x3]); + @@ MAC16(b2, -W1, col[8x3]); + @@ MAC16(b3, -W5, col[8x3]); + ldr r8, [r12, #offW1] @ R8=W1 + ldrsh r7, [r14, #16] + mul r0, r8, r7 @ R0=W1*ROWr16[1]=b0 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle) + ldr r9, [r12, #offW3] @ R9=W3 + ldr r10, [r12, #offW5] @ R10=W5 + mul r1, r9, r7 @ R1=W3*ROWr16[1]=b1 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle) + ldr r11, [r12, #offW7] @ R11=W7 + mul r5, r10, r7 @ R5=W5*ROWr16[1]=b2 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle) + ldrsh r2, [r14, #48] + mul r7, r11, r7 @ R7=W7*ROWr16[1]=b3 (ROWr16[1] must be the second arg, to have the possibility to save 1 cycle) + teq r2, #0 @ if 0, then avoid muls + mlane r0, r9, r2, r0 @ R0+=W3*ROWr16[3]=b0 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle) + rsbne r2, r2, #0 @ R2=-ROWr16[3] + mlane r1, r11, r2, r1 @ R1-=W7*ROWr16[3]=b1 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle) + mlane r5, r8, r2, r5 @ R5-=W1*ROWr16[3]=b2 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle) + mlane r7, r10, r2, r7 @ R7-=W5*ROWr16[3]=b3 (ROWr16[3] must be the second arg, to have the possibility to save 1 cycle) + + @@ at this point, R0=b0, R1=b1, R2 (free), R3 (free), R4 (free), + @@ R5=b2, R6 (free), R7=b3, R8=W1, R9=W3, R10=W5, R11=W7, + @@ R12=__const_ptr_, R14=&block[n] + @@ MAC16(b0, W5, col[5x8]); + @@ MAC16(b2, W7, col[5x8]); + @@ MAC16(b3, W3, col[5x8]); + @@ MAC16(b1, -W1, col[5x8]); + @@ MAC16(b0, W7, col[7x8]); + @@ MAC16(b2, W3, col[7x8]); + @@ MAC16(b3, -W1, col[7x8]); + @@ MAC16(b1, -W5, col[7x8]); + ldrsh r3, [r14, #80] @ R3=COLr16[5x8] + teq r3, #0 @ if 0 then avoid muls + mlane r0, r10, r3, r0 @ R0+=W5*ROWr16[5x8]=b0 + mlane r5, r11, r3, r5 @ R5+=W7*ROWr16[5x8]=b2 + mlane r7, r9, r3, r7 @ R7+=W3*ROWr16[5x8]=b3 + rsbne r3, r3, #0 @ R3=-ROWr16[5x8] + ldrsh r4, [r14, #112] @ R4=COLr16[7x8] + mlane r1, r8, r3, r1 @ R7-=W1*ROWr16[5x8]=b1 + @@ R3 is free now + teq r4, #0 @ if 0 then avoid muls + mlane r0, r11, r4, r0 @ R0+=W7*ROWr16[7x8]=b0 + mlane r5, r9, r4, r5 @ R5+=W3*ROWr16[7x8]=b2 + rsbne r4, r4, #0 @ R4=-ROWr16[7x8] + mlane r7, r8, r4, r7 @ R7-=W1*ROWr16[7x8]=b3 + mlane r1, r10, r4, r1 @ R1-=W5*ROWr16[7x8]=b1 + @@ R4 is free now +__end_b_evaluation2: + @@ at this point, R0=b0, R1=b1, R2 (free), R3 (free), R4 (free), + @@ R5=b2, R6 (free), R7=b3, R8 (free), R9 (free), R10 (free), R11 (free), + @@ R12=__const_ptr_, R14=&block[n] + +__a_evaluation2: + @@ a0 = (W4 * col[8x0]) + (1 << (COL_SHIFT - 1)); + @@ a1 = a0 + W6 * row[2]; + @@ a2 = a0 - W6 * row[2]; + @@ a3 = a0 - W2 * row[2]; + @@ a0 = a0 + W2 * row[2]; + ldrsh r6, [r14, #0] + ldr r9, [r12, #offW4] @ R9=W4 + mul r6, r9, r6 @ R6=W4*ROWr16[0] + ldr r10, [r12, #offW6] @ R10=W6 + ldrsh r4, [r14, #32] @ R4=ROWr16[2] (a3 not defined yet) + add r6, r6, #COL_SHIFTED_1 @ R6=W4*ROWr16[0] + 1<<(COL_SHIFT-1) (a0) + mul r11, r10, r4 @ R11=W6*ROWr16[2] + ldr r8, [r12, #offW2] @ R8=W2 + add r2, r6, r11 @ R2=a0+W6*ROWr16[2] (a1) + sub r3, r6, r11 @ R3=a0-W6*ROWr16[2] (a2) + mul r11, r8, r4 @ R11=W2*ROWr16[2] + sub r4, r6, r11 @ R4=a0-W2*ROWr16[2] (a3) + add r6, r6, r11 @ R6=a0+W2*ROWr16[2] (a0) + + @@ at this point, R0=b0, R1=b1, R2=a1, R3=a2, R4=a3, + @@ R5=b2, R6=a0, R7=b3, R8=W2, R9=W4, R10=W6, R11 (free), + @@ R12=__const_ptr_, R14=&block[n] + @@ a0 += W4*row[4] + @@ a1 -= W4*row[4] + @@ a2 -= W4*row[4] + @@ a3 += W4*row[4] + ldrsh r11, [r14, #64] @ R11=ROWr16[4] + teq r11, #0 @ if null avoid muls + mulne r11, r9, r11 @ R11=W4*ROWr16[4] + @@ R9 is free now + addne r6, r6, r11 @ R6+=W4*ROWr16[4] (a0) + subne r2, r2, r11 @ R2-=W4*ROWr16[4] (a1) + subne r3, r3, r11 @ R3-=W4*ROWr16[4] (a2) + ldrsh r9, [r14, #96] @ R9=ROWr16[6] + addne r4, r4, r11 @ R4+=W4*ROWr16[4] (a3) + @@ W6 alone is no more useful, save W2*ROWr16[6] in it instead + teq r9, #0 @ if null avoid muls + mulne r11, r10, r9 @ R11=W6*ROWr16[6] + addne r6, r6, r11 @ R6+=W6*ROWr16[6] (a0) + mulne r10, r8, r9 @ R10=W2*ROWr16[6] + @@ a0 += W6*row[6]; + @@ a3 -= W6*row[6]; + @@ a1 -= W2*row[6]; + @@ a2 += W2*row[6]; + subne r4, r4, r11 @ R4-=W6*ROWr16[6] (a3) + subne r2, r2, r10 @ R2-=W2*ROWr16[6] (a1) + addne r3, r3, r10 @ R3+=W2*ROWr16[6] (a2) +__end_a_evaluation2: + @@ at this point, R0=b0, R1=b1, R2=a1, R3=a2, R4=a3, + @@ R5=b2, R6=a0, R7=b3, R8 (free), R9 (free), R10 (free), R11 (free), + @@ R12=__const_ptr_, R14=&block[n] + @@ col[0 ] = ((a0 + b0) >> COL_SHIFT); + @@ col[8 ] = ((a1 + b1) >> COL_SHIFT); + @@ col[16] = ((a2 + b2) >> COL_SHIFT); + @@ col[24] = ((a3 + b3) >> COL_SHIFT); + @@ col[32] = ((a3 - b3) >> COL_SHIFT); + @@ col[40] = ((a2 - b2) >> COL_SHIFT); + @@ col[48] = ((a1 - b1) >> COL_SHIFT); + @@ col[56] = ((a0 - b0) >> COL_SHIFT); + @@@@@ no optimisation here @@@@@ + add r8, r6, r0 @ R8=a0+b0 + add r9, r2, r1 @ R9=a1+b1 + mov r8, r8, asr #COL_SHIFT + mov r9, r9, asr #COL_SHIFT + strh r8, [r14, #0] + strh r9, [r14, #16] + add r8, r3, r5 @ R8=a2+b2 + add r9, r4, r7 @ R9=a3+b3 + mov r8, r8, asr #COL_SHIFT + mov r9, r9, asr #COL_SHIFT + strh r8, [r14, #32] + strh r9, [r14, #48] + sub r8, r4, r7 @ R8=a3-b3 + sub r9, r3, r5 @ R9=a2-b2 + mov r8, r8, asr #COL_SHIFT + mov r9, r9, asr #COL_SHIFT + strh r8, [r14, #64] + strh r9, [r14, #80] + sub r8, r2, r1 @ R8=a1-b1 + sub r9, r6, r0 @ R9=a0-b0 + mov r8, r8, asr #COL_SHIFT + mov r9, r9, asr #COL_SHIFT + strh r8, [r14, #96] + strh r9, [r14, #112] + +__end_col_loop: + @@ at this point, R0-R11 (free) + @@ R12=__const_ptr_, R14=&block[n] + ldr r0, [sp, #0] @ R0=block + teq r0, r14 @ compare current &block[n] to block, when block is reached, the loop is finished. + sub r14, r14, #2 + bne __col_loop + + + + +__end_simple_idct_ARM: + @@ restore registers to previous status! + add sp, sp, #8 @@ the local variables! + ldmfd sp!, {r4-r11, r15} @@ update PC with LR content. + + + +@@ kind of sub-function, here not to overload the common case. +__end_bef_a_evaluation: + add r2, r6, r11 @ R2=a0+W6*ROWr16[2] (a1) + mul r11, r8, r4 @ R11=W2*ROWr16[2] + sub r4, r6, r11 @ R4=a0-W2*ROWr16[2] (a3) + add r6, r6, r11 @ R6=a0+W2*ROWr16[2] (a0) + bal __end_a_evaluation + + +__constant_ptr__: @@ see #defines at the beginning of the source code for values. + .align + .word W1 + .word W2 + .word W3 + .word W4 + .word W5 + .word W6 + .word W7 + .word MASK_MSHW diff --git a/mpeg4/src/libavcodec/asv1.c b/mpeg4/src/libavcodec/asv1.c new file mode 100644 index 00000000..3cfb76e6 --- /dev/null +++ b/mpeg4/src/libavcodec/asv1.c @@ -0,0 +1,647 @@ +/* + * ASUS V1/V2 codec + * Copyright (c) 2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file asv1.c + * ASUS V1/V2 codec. + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + +//#undef NDEBUG +//#include + +#define VLC_BITS 6 +#define ASV2_LEVEL_VLC_BITS 10 + +typedef struct ASV1Context{ + AVCodecContext *avctx; + DSPContext dsp; + AVFrame picture; + PutBitContext pb; + GetBitContext gb; + ScanTable scantable; + int inv_qscale; + int mb_width; + int mb_height; + int mb_width2; + int mb_height2; + DECLARE_ALIGNED_8(DCTELEM, block[6][64]); + DECLARE_ALIGNED_8(uint16_t, intra_matrix[64]); + DECLARE_ALIGNED_8(int, q_intra_matrix[64]); + uint8_t *bitstream_buffer; + unsigned int bitstream_buffer_size; +} ASV1Context; + +static const uint8_t scantab[64]={ + 0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19, + 0x02,0x0A,0x03,0x0B,0x12,0x1A,0x13,0x1B, + 0x04,0x0C,0x05,0x0D,0x20,0x28,0x21,0x29, + 0x06,0x0E,0x07,0x0F,0x14,0x1C,0x15,0x1D, + 0x22,0x2A,0x23,0x2B,0x30,0x38,0x31,0x39, + 0x16,0x1E,0x17,0x1F,0x24,0x2C,0x25,0x2D, + 0x32,0x3A,0x33,0x3B,0x26,0x2E,0x27,0x2F, + 0x34,0x3C,0x35,0x3D,0x36,0x3E,0x37,0x3F, +}; + + +static const uint8_t ccp_tab[17][2]={ + {0x2,2}, {0x7,5}, {0xB,5}, {0x3,5}, + {0xD,5}, {0x5,5}, {0x9,5}, {0x1,5}, + {0xE,5}, {0x6,5}, {0xA,5}, {0x2,5}, + {0xC,5}, {0x4,5}, {0x8,5}, {0x3,2}, + {0xF,5}, //EOB +}; + +static const uint8_t level_tab[7][2]={ + {3,4}, {3,3}, {3,2}, {0,3}, {2,2}, {2,3}, {2,4} +}; + +static const uint8_t dc_ccp_tab[8][2]={ + {0x1,2}, {0xD,4}, {0xF,4}, {0xC,4}, + {0x5,3}, {0xE,4}, {0x4,3}, {0x0,2}, +}; + +static const uint8_t ac_ccp_tab[16][2]={ + {0x00,2}, {0x3B,6}, {0x0A,4}, {0x3A,6}, + {0x02,3}, {0x39,6}, {0x3C,6}, {0x38,6}, + {0x03,3}, {0x3D,6}, {0x08,4}, {0x1F,5}, + {0x09,4}, {0x0B,4}, {0x0D,4}, {0x0C,4}, +}; + +static const uint8_t asv2_level_tab[63][2]={ + {0x3F,10},{0x2F,10},{0x37,10},{0x27,10},{0x3B,10},{0x2B,10},{0x33,10},{0x23,10}, + {0x3D,10},{0x2D,10},{0x35,10},{0x25,10},{0x39,10},{0x29,10},{0x31,10},{0x21,10}, + {0x1F, 8},{0x17, 8},{0x1B, 8},{0x13, 8},{0x1D, 8},{0x15, 8},{0x19, 8},{0x11, 8}, + {0x0F, 6},{0x0B, 6},{0x0D, 6},{0x09, 6}, + {0x07, 4},{0x05, 4}, + {0x03, 2}, + {0x00, 5}, + {0x02, 2}, + {0x04, 4},{0x06, 4}, + {0x08, 6},{0x0C, 6},{0x0A, 6},{0x0E, 6}, + {0x10, 8},{0x18, 8},{0x14, 8},{0x1C, 8},{0x12, 8},{0x1A, 8},{0x16, 8},{0x1E, 8}, + {0x20,10},{0x30,10},{0x28,10},{0x38,10},{0x24,10},{0x34,10},{0x2C,10},{0x3C,10}, + {0x22,10},{0x32,10},{0x2A,10},{0x3A,10},{0x26,10},{0x36,10},{0x2E,10},{0x3E,10}, +}; + + +static VLC ccp_vlc; +static VLC level_vlc; +static VLC dc_ccp_vlc; +static VLC ac_ccp_vlc; +static VLC asv2_level_vlc; + +static void init_vlcs(ASV1Context *a){ + static int done = 0; + + if (!done) { + done = 1; + + init_vlc(&ccp_vlc, VLC_BITS, 17, + &ccp_tab[0][1], 2, 1, + &ccp_tab[0][0], 2, 1, 1); + init_vlc(&dc_ccp_vlc, VLC_BITS, 8, + &dc_ccp_tab[0][1], 2, 1, + &dc_ccp_tab[0][0], 2, 1, 1); + init_vlc(&ac_ccp_vlc, VLC_BITS, 16, + &ac_ccp_tab[0][1], 2, 1, + &ac_ccp_tab[0][0], 2, 1, 1); + init_vlc(&level_vlc, VLC_BITS, 7, + &level_tab[0][1], 2, 1, + &level_tab[0][0], 2, 1, 1); + init_vlc(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63, + &asv2_level_tab[0][1], 2, 1, + &asv2_level_tab[0][0], 2, 1, 1); + } +} + +//FIXME write a reversed bitstream reader to avoid the double reverse +static inline int asv2_get_bits(GetBitContext *gb, int n){ + return ff_reverse[ get_bits(gb, n) << (8-n) ]; +} + +static inline void asv2_put_bits(PutBitContext *pb, int n, int v){ + put_bits(pb, n, ff_reverse[ v << (8-n) ]); +} + +static inline int asv1_get_level(GetBitContext *gb){ + int code= get_vlc2(gb, level_vlc.table, VLC_BITS, 1); + + if(code==3) return get_sbits(gb, 8); + else return code - 3; +} + +static inline int asv2_get_level(GetBitContext *gb){ + int code= get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1); + + if(code==31) return (int8_t)asv2_get_bits(gb, 8); + else return code - 31; +} + +static inline void asv1_put_level(PutBitContext *pb, int level){ + unsigned int index= level + 3; + + if(index <= 6) put_bits(pb, level_tab[index][1], level_tab[index][0]); + else{ + put_bits(pb, level_tab[3][1], level_tab[3][0]); + put_bits(pb, 8, level&0xFF); + } +} + +static inline void asv2_put_level(PutBitContext *pb, int level){ + unsigned int index= level + 31; + + if(index <= 62) put_bits(pb, asv2_level_tab[index][1], asv2_level_tab[index][0]); + else{ + put_bits(pb, asv2_level_tab[31][1], asv2_level_tab[31][0]); + asv2_put_bits(pb, 8, level&0xFF); + } +} + +static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64]){ + int i; + + block[0]= 8*get_bits(&a->gb, 8); + + for(i=0; i<11; i++){ + const int ccp= get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1); + + if(ccp){ + if(ccp == 16) break; + if(ccp < 0 || i>=10){ + av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n"); + return -1; + } + + if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; + if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; + if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; + if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; + } + } + + return 0; +} + +static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64]){ + int i, count, ccp; + + count= asv2_get_bits(&a->gb, 4); + + block[0]= 8*asv2_get_bits(&a->gb, 8); + + ccp= get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1); + if(ccp){ + if(ccp&4) block[a->scantable.permutated[1]]= (asv2_get_level(&a->gb) * a->intra_matrix[1])>>4; + if(ccp&2) block[a->scantable.permutated[2]]= (asv2_get_level(&a->gb) * a->intra_matrix[2])>>4; + if(ccp&1) block[a->scantable.permutated[3]]= (asv2_get_level(&a->gb) * a->intra_matrix[3])>>4; + } + + for(i=1; igb, ac_ccp_vlc.table, VLC_BITS, 1); + + if(ccp){ + if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4; + if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4; + if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4; + if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4; + } + } + + return 0; +} + +static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){ + int i; + int nc_count=0; + + put_bits(&a->pb, 8, (block[0] + 32)>>6); + block[0]= 0; + + for(i=0; i<10; i++){ + const int index= scantab[4*i]; + int ccp=0; + + if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; + if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; + if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; + if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; + + if(ccp){ + for(;nc_count; nc_count--) + put_bits(&a->pb, ccp_tab[0][1], ccp_tab[0][0]); + + put_bits(&a->pb, ccp_tab[ccp][1], ccp_tab[ccp][0]); + + if(ccp&8) asv1_put_level(&a->pb, block[index + 0]); + if(ccp&4) asv1_put_level(&a->pb, block[index + 8]); + if(ccp&2) asv1_put_level(&a->pb, block[index + 1]); + if(ccp&1) asv1_put_level(&a->pb, block[index + 9]); + }else{ + nc_count++; + } + } + put_bits(&a->pb, ccp_tab[16][1], ccp_tab[16][0]); +} + +static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){ + int i; + int count=0; + + for(count=63; count>3; count--){ + const int index= scantab[count]; + + if( (block[index]*a->q_intra_matrix[index] + (1<<15))>>16 ) + break; + } + + count >>= 2; + + asv2_put_bits(&a->pb, 4, count); + asv2_put_bits(&a->pb, 8, (block[0] + 32)>>6); + block[0]= 0; + + for(i=0; i<=count; i++){ + const int index= scantab[4*i]; + int ccp=0; + + if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8; + if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4; + if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2; + if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1; + + assert(i || ccp<8); + if(i) put_bits(&a->pb, ac_ccp_tab[ccp][1], ac_ccp_tab[ccp][0]); + else put_bits(&a->pb, dc_ccp_tab[ccp][1], dc_ccp_tab[ccp][0]); + + if(ccp){ + if(ccp&8) asv2_put_level(&a->pb, block[index + 0]); + if(ccp&4) asv2_put_level(&a->pb, block[index + 8]); + if(ccp&2) asv2_put_level(&a->pb, block[index + 1]); + if(ccp&1) asv2_put_level(&a->pb, block[index + 9]); + } + } +} + +static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){ + int i; + + a->dsp.clear_blocks(block[0]); + + if(a->avctx->codec_id == CODEC_ID_ASV1){ + for(i=0; i<6; i++){ + if( asv1_decode_block(a, block[i]) < 0) + return -1; + } + }else{ + for(i=0; i<6; i++){ + if( asv2_decode_block(a, block[i]) < 0) + return -1; + } + } + return 0; +} + +static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){ + int i; + + if(a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < 30*16*16*3/2/8){ + av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + + if(a->avctx->codec_id == CODEC_ID_ASV1){ + for(i=0; i<6; i++) + asv1_encode_block(a, block[i]); + }else{ + for(i=0; i<6; i++) + asv2_encode_block(a, block[i]); + } + return 0; +} + +static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){ + DCTELEM (*block)[64]= a->block; + int linesize= a->picture.linesize[0]; + + uint8_t *dest_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; + uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; + uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; + + a->dsp.idct_put(dest_y , linesize, block[0]); + a->dsp.idct_put(dest_y + 8, linesize, block[1]); + a->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); + a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); + + if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ + a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]); + a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]); + } +} + +static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ + DCTELEM (*block)[64]= a->block; + int linesize= a->picture.linesize[0]; + int i; + + uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; + uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; + uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; + + a->dsp.get_pixels(block[0], ptr_y , linesize); + a->dsp.get_pixels(block[1], ptr_y + 8, linesize); + a->dsp.get_pixels(block[2], ptr_y + 8*linesize , linesize); + a->dsp.get_pixels(block[3], ptr_y + 8*linesize + 8, linesize); + for(i=0; i<4; i++) + a->dsp.fdct(block[i]); + + if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ + a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]); + a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]); + for(i=4; i<6; i++) + a->dsp.fdct(block[i]); + } +} + +static int decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + ASV1Context * const a = avctx->priv_data; + AVFrame *picture = data; + AVFrame * const p= (AVFrame*)&a->picture; + int mb_x, mb_y; + + if(p->data[0]) + avctx->release_buffer(avctx, p); + + p->reference= 0; + if(avctx->get_buffer(avctx, p) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + p->pict_type= I_TYPE; + p->key_frame= 1; + + a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + + if(avctx->codec_id == CODEC_ID_ASV1) + a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (uint32_t*)buf, buf_size/4); + else{ + int i; + for(i=0; ibitstream_buffer[i]= ff_reverse[ buf[i] ]; + } + + init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8); + + for(mb_y=0; mb_ymb_height2; mb_y++){ + for(mb_x=0; mb_xmb_width2; mb_x++){ + if( decode_mb(a, a->block) <0) + return -1; + + idct_put(a, mb_x, mb_y); + } + } + + if(a->mb_width2 != a->mb_width){ + mb_x= a->mb_width2; + for(mb_y=0; mb_ymb_height2; mb_y++){ + if( decode_mb(a, a->block) <0) + return -1; + + idct_put(a, mb_x, mb_y); + } + } + + if(a->mb_height2 != a->mb_height){ + mb_y= a->mb_height2; + for(mb_x=0; mb_xmb_width; mb_x++){ + if( decode_mb(a, a->block) <0) + return -1; + + idct_put(a, mb_x, mb_y); + } + } +#if 0 +int i; +printf("%d %d\n", 8*buf_size, get_bits_count(&a->gb)); +for(i=get_bits_count(&a->gb); i<8*buf_size; i++){ + printf("%d", get_bits1(&a->gb)); +} + +for(i=0; iavctx->extradata_size; i++){ + printf("%c\n", ((uint8_t*)s->avctx->extradata)[i]); +} +#endif + + *picture= *(AVFrame*)&a->picture; + *data_size = sizeof(AVPicture); + + emms_c(); + + return (get_bits_count(&a->gb)+31)/32*4; +} + +static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + ASV1Context * const a = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p= (AVFrame*)&a->picture; + int size; + int mb_x, mb_y; + + init_put_bits(&a->pb, buf, buf_size); + + *p = *pict; + p->pict_type= I_TYPE; + p->key_frame= 1; + + for(mb_y=0; mb_ymb_height2; mb_y++){ + for(mb_x=0; mb_xmb_width2; mb_x++){ + dct_get(a, mb_x, mb_y); + encode_mb(a, a->block); + } + } + + if(a->mb_width2 != a->mb_width){ + mb_x= a->mb_width2; + for(mb_y=0; mb_ymb_height2; mb_y++){ + dct_get(a, mb_x, mb_y); + encode_mb(a, a->block); + } + } + + if(a->mb_height2 != a->mb_height){ + mb_y= a->mb_height2; + for(mb_x=0; mb_xmb_width; mb_x++){ + dct_get(a, mb_x, mb_y); + encode_mb(a, a->block); + } + } + emms_c(); + + align_put_bits(&a->pb); + while(put_bits_count(&a->pb)&31) + put_bits(&a->pb, 8, 0); + + size= put_bits_count(&a->pb)/32; + + if(avctx->codec_id == CODEC_ID_ASV1) + a->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); + else{ + int i; + for(i=0; i<4*size; i++) + buf[i]= ff_reverse[ buf[i] ]; + } + + return size*4; +} + +static void common_init(AVCodecContext *avctx){ + ASV1Context * const a = avctx->priv_data; + + dsputil_init(&a->dsp, avctx); + + a->mb_width = (avctx->width + 15) / 16; + a->mb_height = (avctx->height + 15) / 16; + a->mb_width2 = (avctx->width + 0) / 16; + a->mb_height2 = (avctx->height + 0) / 16; + + avctx->coded_frame= (AVFrame*)&a->picture; + a->avctx= avctx; +} + +static int decode_init(AVCodecContext *avctx){ + ASV1Context * const a = avctx->priv_data; + AVFrame *p= (AVFrame*)&a->picture; + int i; + const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; + + common_init(avctx); + init_vlcs(a); + ff_init_scantable(a->dsp.idct_permutation, &a->scantable, scantab); + avctx->pix_fmt= PIX_FMT_YUV420P; + + a->inv_qscale= ((uint8_t*)avctx->extradata)[0]; + if(a->inv_qscale == 0){ + av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n"); + if(avctx->codec_id == CODEC_ID_ASV1) + a->inv_qscale= 6; + else + a->inv_qscale= 10; + } + + for(i=0; i<64; i++){ + int index= scantab[i]; + + a->intra_matrix[i]= 64*scale*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale; + } + + p->qstride= a->mb_width; + p->qscale_table= av_malloc( p->qstride * a->mb_height); + p->quality= (32*scale + a->inv_qscale/2)/a->inv_qscale; + memset(p->qscale_table, p->quality, p->qstride*a->mb_height); + + return 0; +} + +static int encode_init(AVCodecContext *avctx){ + ASV1Context * const a = avctx->priv_data; + int i; + const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; + + common_init(avctx); + + if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE; + + a->inv_qscale= (32*scale*FF_QUALITY_SCALE + avctx->global_quality/2) / avctx->global_quality; + + avctx->extradata= av_mallocz(8); + avctx->extradata_size=8; + ((uint32_t*)avctx->extradata)[0]= le2me_32(a->inv_qscale); + ((uint32_t*)avctx->extradata)[1]= le2me_32(ff_get_fourcc("ASUS")); + + for(i=0; i<64; i++){ + int q= 32*scale*ff_mpeg1_default_intra_matrix[i]; + a->q_intra_matrix[i]= ((a->inv_qscale<<16) + q/2) / q; + } + + return 0; +} + +static int decode_end(AVCodecContext *avctx){ + ASV1Context * const a = avctx->priv_data; + + av_freep(&a->bitstream_buffer); + av_freep(&a->picture.qscale_table); + a->bitstream_buffer_size=0; + + return 0; +} + +AVCodec asv1_decoder = { + "asv1", + CODEC_TYPE_VIDEO, + CODEC_ID_ASV1, + sizeof(ASV1Context), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; + +AVCodec asv2_decoder = { + "asv2", + CODEC_TYPE_VIDEO, + CODEC_ID_ASV2, + sizeof(ASV1Context), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; + +#ifdef CONFIG_ENCODERS + +AVCodec asv1_encoder = { + "asv1", + CODEC_TYPE_VIDEO, + CODEC_ID_ASV1, + sizeof(ASV1Context), + encode_init, + encode_frame, + //encode_end, +}; + +AVCodec asv2_encoder = { + "asv2", + CODEC_TYPE_VIDEO, + CODEC_ID_ASV2, + sizeof(ASV1Context), + encode_init, + encode_frame, + //encode_end, +}; + +#endif //CONFIG_ENCODERS diff --git a/mpeg4/src/libavcodec/avcodec.h b/mpeg4/src/libavcodec/avcodec.h new file mode 100644 index 00000000..0ba573e5 --- /dev/null +++ b/mpeg4/src/libavcodec/avcodec.h @@ -0,0 +1,2567 @@ +#ifndef AVCODEC_H +#define AVCODEC_H + +/** + * @file avcodec.h + * external api header. + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "avutil.h" +#include /* size_t */ + +//FIXME the following 2 really dont belong in here +#define FFMPEG_VERSION_INT 0x000409 +#define FFMPEG_VERSION "CVS" + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define LIBAVCODEC_VERSION_INT ((51<<16)+(9<<8)+0) +#define LIBAVCODEC_VERSION 51.9.0 +#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT + +#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) + +#define AV_NOPTS_VALUE int64_t_C(0x8000000000000000) +#define AV_TIME_BASE 1000000 +#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} + +enum CodecID { + CODEC_ID_NONE, + CODEC_ID_MPEG1VIDEO, + CODEC_ID_MPEG2VIDEO, /* prefered ID for MPEG Video 1 or 2 decoding */ + CODEC_ID_MPEG2VIDEO_XVMC, + CODEC_ID_H261, + CODEC_ID_H263, + CODEC_ID_RV10, + CODEC_ID_RV20, + CODEC_ID_MJPEG, + CODEC_ID_MJPEGB, + CODEC_ID_LJPEG, + CODEC_ID_SP5X, + CODEC_ID_JPEGLS, + CODEC_ID_MPEG4, + CODEC_ID_RAWVIDEO, + CODEC_ID_MSMPEG4V1, + CODEC_ID_MSMPEG4V2, + CODEC_ID_MSMPEG4V3, + CODEC_ID_WMV1, + CODEC_ID_WMV2, + CODEC_ID_H263P, + CODEC_ID_H263I, + CODEC_ID_FLV1, + CODEC_ID_SVQ1, + CODEC_ID_SVQ3, + CODEC_ID_DVVIDEO, + CODEC_ID_HUFFYUV, + CODEC_ID_CYUV, + CODEC_ID_H264, + CODEC_ID_INDEO3, + CODEC_ID_VP3, + CODEC_ID_THEORA, + CODEC_ID_ASV1, + CODEC_ID_ASV2, + CODEC_ID_FFV1, + CODEC_ID_4XM, + CODEC_ID_VCR1, + CODEC_ID_CLJR, + CODEC_ID_MDEC, + CODEC_ID_ROQ, + CODEC_ID_INTERPLAY_VIDEO, + CODEC_ID_XAN_WC3, + CODEC_ID_XAN_WC4, + CODEC_ID_RPZA, + CODEC_ID_CINEPAK, + CODEC_ID_WS_VQA, + CODEC_ID_MSRLE, + CODEC_ID_MSVIDEO1, + CODEC_ID_IDCIN, + CODEC_ID_8BPS, + CODEC_ID_SMC, + CODEC_ID_FLIC, + CODEC_ID_TRUEMOTION1, + CODEC_ID_VMDVIDEO, + CODEC_ID_MSZH, + CODEC_ID_ZLIB, + CODEC_ID_QTRLE, + CODEC_ID_SNOW, + CODEC_ID_TSCC, + CODEC_ID_ULTI, + CODEC_ID_QDRAW, + CODEC_ID_VIXL, + CODEC_ID_QPEG, + CODEC_ID_XVID, + CODEC_ID_PNG, + CODEC_ID_PPM, + CODEC_ID_PBM, + CODEC_ID_PGM, + CODEC_ID_PGMYUV, + CODEC_ID_PAM, + CODEC_ID_FFVHUFF, + CODEC_ID_RV30, + CODEC_ID_RV40, + CODEC_ID_VC9, + CODEC_ID_WMV3, + CODEC_ID_LOCO, + CODEC_ID_WNV1, + CODEC_ID_AASC, + CODEC_ID_INDEO2, + CODEC_ID_FRAPS, + CODEC_ID_TRUEMOTION2, + CODEC_ID_BMP, + CODEC_ID_CSCD, + CODEC_ID_MMVIDEO, + CODEC_ID_ZMBV, + CODEC_ID_AVS, + CODEC_ID_SMACKVIDEO, + CODEC_ID_NUV, + CODEC_ID_KMVC, + + /* various pcm "codecs" */ + CODEC_ID_PCM_S16LE= 0x10000, + CODEC_ID_PCM_S16BE, + CODEC_ID_PCM_U16LE, + CODEC_ID_PCM_U16BE, + CODEC_ID_PCM_S8, + CODEC_ID_PCM_U8, + CODEC_ID_PCM_MULAW, + CODEC_ID_PCM_ALAW, + CODEC_ID_PCM_S32LE, + CODEC_ID_PCM_S32BE, + CODEC_ID_PCM_U32LE, + CODEC_ID_PCM_U32BE, + CODEC_ID_PCM_S24LE, + CODEC_ID_PCM_S24BE, + CODEC_ID_PCM_U24LE, + CODEC_ID_PCM_U24BE, + CODEC_ID_PCM_S24DAUD, + + /* various adpcm codecs */ + CODEC_ID_ADPCM_IMA_QT= 0x11000, + CODEC_ID_ADPCM_IMA_WAV, + CODEC_ID_ADPCM_IMA_DK3, + CODEC_ID_ADPCM_IMA_DK4, + CODEC_ID_ADPCM_IMA_WS, + CODEC_ID_ADPCM_IMA_SMJPEG, + CODEC_ID_ADPCM_MS, + CODEC_ID_ADPCM_4XM, + CODEC_ID_ADPCM_XA, + CODEC_ID_ADPCM_ADX, + CODEC_ID_ADPCM_EA, + CODEC_ID_ADPCM_G726, + CODEC_ID_ADPCM_CT, + CODEC_ID_ADPCM_SWF, + CODEC_ID_ADPCM_YAMAHA, + CODEC_ID_ADPCM_SBPRO_4, + CODEC_ID_ADPCM_SBPRO_3, + CODEC_ID_ADPCM_SBPRO_2, + + /* AMR */ + CODEC_ID_AMR_NB= 0x12000, + CODEC_ID_AMR_WB, + + /* RealAudio codecs*/ + CODEC_ID_RA_144= 0x13000, + CODEC_ID_RA_288, + + /* various DPCM codecs */ + CODEC_ID_ROQ_DPCM= 0x14000, + CODEC_ID_INTERPLAY_DPCM, + CODEC_ID_XAN_DPCM, + CODEC_ID_SOL_DPCM, + + CODEC_ID_MP2= 0x15000, + CODEC_ID_MP3, /* prefered ID for MPEG Audio layer 1, 2 or3 decoding */ + CODEC_ID_AAC, + CODEC_ID_MPEG4AAC, + CODEC_ID_AC3, + CODEC_ID_DTS, + CODEC_ID_VORBIS, + CODEC_ID_DVAUDIO, + CODEC_ID_WMAV1, + CODEC_ID_WMAV2, + CODEC_ID_MACE3, + CODEC_ID_MACE6, + CODEC_ID_VMDAUDIO, + CODEC_ID_SONIC, + CODEC_ID_SONIC_LS, + CODEC_ID_FLAC, + CODEC_ID_MP3ADU, + CODEC_ID_MP3ON4, + CODEC_ID_SHORTEN, + CODEC_ID_ALAC, + CODEC_ID_WESTWOOD_SND1, + CODEC_ID_GSM, + CODEC_ID_QDM2, + CODEC_ID_COOK, + CODEC_ID_TRUESPEECH, + CODEC_ID_TTA, + CODEC_ID_SMACKAUDIO, + + CODEC_ID_OGGTHEORA= 0x16000, + + /* subtitle codecs */ + CODEC_ID_DVD_SUBTITLE= 0x17000, + CODEC_ID_DVB_SUBTITLE, + + CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG2 transport + stream (only used by libavformat) */ +}; + +/* CODEC_ID_MP3LAME is absolete */ +#define CODEC_ID_MP3LAME CODEC_ID_MP3 + +enum CodecType { + CODEC_TYPE_UNKNOWN = -1, + CODEC_TYPE_VIDEO, + CODEC_TYPE_AUDIO, + CODEC_TYPE_DATA, + CODEC_TYPE_SUBTITLE, +}; + +/* currently unused, may be used if 24/32 bits samples ever supported */ +/* all in native endian */ +enum SampleFormat { + SAMPLE_FMT_NONE = -1, + SAMPLE_FMT_U8, ///< unsigned 8 bits + SAMPLE_FMT_S16, ///< signed 16 bits + SAMPLE_FMT_S24, ///< signed 24 bits + SAMPLE_FMT_S32, ///< signed 32 bits + SAMPLE_FMT_FLT, ///< float +}; + +/* in bytes */ +#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio + +/** + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * this is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end
    + * Note, if the first 23 bits of the additional bytes are not 0 then damaged + * MPEG bitstreams could cause overread and segfault + */ +#define FF_INPUT_BUFFER_PADDING_SIZE 8 + +/** + * minimum encoding buffer size. + * used to avoid some checks during header writing + */ +#define FF_MIN_BUFFER_SIZE 16384 + +/* motion estimation type, EPZS by default */ +enum Motion_Est_ID { + ME_ZERO = 1, + ME_FULL, + ME_LOG, + ME_PHODS, + ME_EPZS, + ME_X1, + ME_HEX, + ME_UMH, + ME_ITER, +}; + +enum AVDiscard{ +//we leave some space between them for extensions (drop some keyframes for intra only or drop just some bidir frames) + AVDISCARD_NONE =-16, ///< discard nothing + AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi + AVDISCARD_NONREF = 8, ///< discard all non reference + AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames + AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes + AVDISCARD_ALL = 48, ///< discard all +}; + +typedef struct RcOverride{ + int start_frame; + int end_frame; + int qscale; // if this is 0 then quality_factor will be used instead + float quality_factor; +} RcOverride; + +/* only for ME compatiblity with old apps */ +extern int motion_estimation_method; + +#define FF_MAX_B_FRAMES 16 + +/* encoding support + these flags can be passed in AVCodecContext.flags before initing + Note: not everything is supported yet. +*/ + +#define CODEC_FLAG_QSCALE 0x0002 ///< use fixed qscale +#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / Advanced prediction for H263 +#define CODEC_FLAG_QPEL 0x0010 ///< use qpel MC +#define CODEC_FLAG_GMC 0x0020 ///< use GMC +#define CODEC_FLAG_MV0 0x0040 ///< always try a MB with MV=<0,0> +#define CODEC_FLAG_PART 0x0080 ///< use data partitioning +/* parent program gurantees that the input for b-frame containing streams is not written to + for at least s->max_b_frames+1 frames, if this is not set than the input will be copied */ +#define CODEC_FLAG_INPUT_PRESERVED 0x0100 +#define CODEC_FLAG_PASS1 0x0200 ///< use internal 2pass ratecontrol in first pass mode +#define CODEC_FLAG_PASS2 0x0400 ///< use internal 2pass ratecontrol in second pass mode +#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< use external huffman table (for mjpeg) +#define CODEC_FLAG_GRAY 0x2000 ///< only decode/encode grayscale +#define CODEC_FLAG_EMU_EDGE 0x4000///< don't draw edges +#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding +#define CODEC_FLAG_TRUNCATED 0x00010000 /** input bitstream might be truncated at a random location instead + of only at frame boundaries */ +#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< normalize adaptive quantization +#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< use interlaced dct +#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< force low delay +#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< use alternate scan +#define CODEC_FLAG_TRELLIS_QUANT 0x00200000 ///< use trellis quantization +#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< place global headers in extradata instead of every keyframe +#define CODEC_FLAG_BITEXACT 0x00800000 ///< use only bitexact stuff (except (i)dct) +/* Fx : Flag for h263+ extra options */ +#define CODEC_FLAG_H263P_AIC 0x01000000 ///< H263 Advanced intra coding / MPEG4 AC prediction (remove this) +#define CODEC_FLAG_AC_PRED 0x01000000 ///< H263 Advanced intra coding / MPEG4 AC prediction +#define CODEC_FLAG_H263P_UMV 0x02000000 ///< Unlimited motion vector +#define CODEC_FLAG_CBP_RD 0x04000000 ///< use rate distortion optimization for cbp +#define CODEC_FLAG_QP_RD 0x08000000 ///< use rate distortion optimization for qp selectioon +#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H263 Alternative inter vlc +#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC +#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter +#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000 +#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation +#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< will reserve space for SVCD scan offset user data +#define CODEC_FLAG_CLOSED_GOP 0x80000000 +#define CODEC_FLAG2_FAST 0x00000001 ///< allow non spec compliant speedup tricks +#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< strictly enforce GOP size +#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< skip bitstream encoding +#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< place global headers at every keyframe instead of in extradata +#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow b-frames to be used as references +#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for b-frames +#define CODEC_FLAG2_MIXED_REFS 0x00000040 ///< H.264 multiple references per partition +#define CODEC_FLAG2_8X8DCT 0x00000080 ///< H.264 high profile 8x8 transform +#define CODEC_FLAG2_FASTPSKIP 0x00000100 ///< H.264 fast pskip +#define CODEC_FLAG2_AUD 0x00000200 ///< H.264 access unit delimiters +#define CODEC_FLAG2_BRDO 0x00000400 ///< b-frame rate-distortion optimization + +/* Unsupported options : + * Syntax Arithmetic coding (SAC) + * Reference Picture Selection + * Independant Segment Decoding */ +/* /Fx */ +/* codec capabilities */ + +#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< decoder can use draw_horiz_band callback +/** + * Codec uses get_buffer() for allocating buffers. + * direct rendering method 1 + */ +#define CODEC_CAP_DR1 0x0002 +/* if 'parse_only' field is true, then avcodec_parse_frame() can be + used */ +#define CODEC_CAP_PARSE_ONLY 0x0004 +#define CODEC_CAP_TRUNCATED 0x0008 +/* codec can export data for HW decoding (XvMC) */ +#define CODEC_CAP_HWACCEL 0x0010 +/** + * codec has a non zero delay and needs to be feeded with NULL at the end to get the delayed data. + * if this is not set, the codec is guranteed to never be feeded with NULL data + */ +#define CODEC_CAP_DELAY 0x0020 + +//the following defines may change, don't expect compatibility if you use them +#define MB_TYPE_INTRA4x4 0x0001 +#define MB_TYPE_INTRA16x16 0x0002 //FIXME h264 specific +#define MB_TYPE_INTRA_PCM 0x0004 //FIXME h264 specific +#define MB_TYPE_16x16 0x0008 +#define MB_TYPE_16x8 0x0010 +#define MB_TYPE_8x16 0x0020 +#define MB_TYPE_8x8 0x0040 +#define MB_TYPE_INTERLACED 0x0080 +#define MB_TYPE_DIRECT2 0x0100 //FIXME +#define MB_TYPE_ACPRED 0x0200 +#define MB_TYPE_GMC 0x0400 +#define MB_TYPE_SKIP 0x0800 +#define MB_TYPE_P0L0 0x1000 +#define MB_TYPE_P1L0 0x2000 +#define MB_TYPE_P0L1 0x4000 +#define MB_TYPE_P1L1 0x8000 +#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) +#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) +#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) +#define MB_TYPE_QUANT 0x00010000 +#define MB_TYPE_CBP 0x00020000 +//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) + +/** + * Pan Scan area. + * this specifies the area which should be displayed. Note there may be multiple such areas for one frame + */ +typedef struct AVPanScan{ + /** + * id. + * - encoding: set by user. + * - decoding: set by lavc + */ + int id; + + /** + * width and height in 1/16 pel + * - encoding: set by user. + * - decoding: set by lavc + */ + int width; + int height; + + /** + * position of the top left corner in 1/16 pel for up to 3 fields/frames. + * - encoding: set by user. + * - decoding: set by lavc + */ + int16_t position[3][2]; +}AVPanScan; + +#define FF_COMMON_FRAME \ + /**\ + * pointer to the picture planes.\ + * this might be different from the first allocated byte\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *data[4];\ + int linesize[4];\ + /**\ + * pointer to the first allocated byte of the picture. can be used in get_buffer/release_buffer\ + * this isn't used by lavc unless the default get/release_buffer() is used\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *base[4];\ + /**\ + * 1 -> keyframe, 0-> not\ + * - encoding: set by lavc\ + * - decoding: set by lavc\ + */\ + int key_frame;\ +\ + /**\ + * picture type of the frame, see ?_TYPE below.\ + * - encoding: set by lavc for coded_picture (and set by user for input)\ + * - decoding: set by lavc\ + */\ + int pict_type;\ +\ + /**\ + * presentation timestamp in time_base units (time when frame should be shown to user)\ + * if AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed\ + * - encoding: MUST be set by user\ + * - decoding: set by lavc\ + */\ + int64_t pts;\ +\ + /**\ + * picture number in bitstream order.\ + * - encoding: set by\ + * - decoding: set by lavc\ + */\ + int coded_picture_number;\ + /**\ + * picture number in display order.\ + * - encoding: set by\ + * - decoding: set by lavc\ + */\ + int display_picture_number;\ +\ + /**\ + * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ + * - encoding: set by lavc for coded_picture (and set by user for input)\ + * - decoding: set by lavc\ + */\ + int quality; \ +\ + /**\ + * buffer age (1->was last buffer and dint change, 2->..., ...).\ + * set to INT_MAX if the buffer has not been used yet \ + * - encoding: unused\ + * - decoding: MUST be set by get_buffer()\ + */\ + int age;\ +\ + /**\ + * is this picture used as reference\ + * - encoding: unused\ + * - decoding: set by lavc (before get_buffer() call))\ + */\ + int reference;\ +\ + /**\ + * QP table\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + int8_t *qscale_table;\ + /**\ + * QP store stride\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + int qstride;\ +\ + /**\ + * mbskip_table[mb]>=1 if MB didnt change\ + * stride= mb_width = (width+15)>>4\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + uint8_t *mbskip_table;\ +\ + /**\ + * Motion vector table.\ + * @code\ + * example:\ + * int mv_sample_log2= 4 - motion_subsample_log2;\ + * int mb_width= (width+15)>>4;\ + * int mv_stride= (mb_width << mv_sample_log2) + 1;\ + * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];\ + * @endcode\ + * - encoding: set by user\ + * - decoding: set by lavc\ + */\ + int16_t (*motion_val[2])[2];\ +\ + /**\ + * Macroblock type table\ + * mb_type_base + mb_width + 2\ + * - encoding: set by user\ + * - decoding: set by lavc\ + */\ + uint32_t *mb_type;\ +\ + /**\ + * log2 of the size of the block which a single vector in motion_val represents: \ + * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + uint8_t motion_subsample_log2;\ +\ + /**\ + * for some private data of the user\ + * - encoding: unused\ + * - decoding: set by user\ + */\ + void *opaque;\ +\ + /**\ + * error\ + * - encoding: set by lavc if flags&CODEC_FLAG_PSNR\ + * - decoding: unused\ + */\ + uint64_t error[4];\ +\ + /**\ + * type of the buffer (to keep track of who has to dealloc data[*])\ + * - encoding: set by the one who allocs it\ + * - decoding: set by the one who allocs it\ + * Note: user allocated (direct rendering) & internal buffers can not coexist currently\ + */\ + int type;\ + \ + /**\ + * when decoding, this signal how much the picture must be delayed.\ + * extra_delay = repeat_pict / (2*fps)\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + int repeat_pict;\ + \ + /**\ + * \ + */\ + int qscale_type;\ + \ + /**\ + * The content of the picture is interlaced.\ + * - encoding: set by user\ + * - decoding: set by lavc (default 0)\ + */\ + int interlaced_frame;\ + \ + /**\ + * if the content is interlaced, is top field displayed first.\ + * - encoding: set by user\ + * - decoding: set by lavc\ + */\ + int top_field_first;\ + \ + /**\ + * Pan scan.\ + * - encoding: set by user\ + * - decoding: set by lavc\ + */\ + AVPanScan *pan_scan;\ + \ + /**\ + * tell user application that palette has changed from previous frame.\ + * - encoding: ??? (no palette-enabled encoder yet)\ + * - decoding: set by lavc (default 0)\ + */\ + int palette_has_changed;\ + \ + /**\ + * Codec suggestion on buffer type if != 0\ + * - encoding: unused\ + * - decoding: set by lavc (before get_buffer() call))\ + */\ + int buffer_hints;\ +\ + /**\ + * DCT coeffitients\ + * - encoding: unused\ + * - decoding: set by lavc\ + */\ + short *dct_coeff;\ +\ + /**\ + * Motion referece frame index\ + * - encoding: set by user\ + * - decoding: set by lavc\ + */\ + int8_t *ref_index[2]; + +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 +#define FF_QSCALE_TYPE_H264 2 + +#define FF_BUFFER_TYPE_INTERNAL 1 +#define FF_BUFFER_TYPE_USER 2 ///< Direct rendering buffers (image is (de)allocated by user) +#define FF_BUFFER_TYPE_SHARED 4 ///< buffer from somewhere else, don't dealloc image (data/base), all other tables are not shared +#define FF_BUFFER_TYPE_COPY 8 ///< just a (modified) copy of some other buffer, don't dealloc anything + + +#define FF_I_TYPE 1 // Intra +#define FF_P_TYPE 2 // Predicted +#define FF_B_TYPE 3 // Bi-dir predicted +#define FF_S_TYPE 4 // S(GMC)-VOP MPEG4 +#define FF_SI_TYPE 5 +#define FF_SP_TYPE 6 + +#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore) +#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer +#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content +#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update) + +/** + * Audio Video Frame. + */ +typedef struct AVFrame { + FF_COMMON_FRAME +} AVFrame; + +#define DEFAULT_FRAME_RATE_BASE 1001000 + +/** + * Used by av_log + */ +typedef struct AVCLASS AVClass; +struct AVCLASS { + const char* class_name; + const char* (*item_name)(void*); /* actually passing a pointer to an AVCodecContext + or AVFormatContext, which begin with an AVClass. + Needed because av_log is in libavcodec and has no visibility + of AVIn/OutputFormat */ + struct AVOption *option; +}; + +/** + * main external api structure. + */ +typedef struct AVCodecContext { + /** + * Info on struct for av_log + * - set by avcodec_alloc_context + */ + AVClass *av_class; + /** + * the average bitrate. + * - encoding: set by user. unused for constant quantizer encoding + * - decoding: set by lavc. 0 or some bitrate if this info is available in the stream + */ + int bit_rate; + + /** + * number of bits the bitstream is allowed to diverge from the reference. + * the reference can be CBR (for CBR pass1) or VBR (for pass2) + * - encoding: set by user. unused for constant quantizer encoding + * - decoding: unused + */ + int bit_rate_tolerance; + + /** + * CODEC_FLAG_*. + * - encoding: set by user. + * - decoding: set by user. + */ + int flags; + + /** + * some codecs needs additionnal format info. It is stored here + * - encoding: set by user. + * - decoding: set by lavc. (FIXME is this ok?) + */ + int sub_id; + + /** + * motion estimation algorithm used for video coding. + * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex), + * 8 (umh), 9 (iter) [7, 8 are x264 specific, 9 is snow specific] + * - encoding: MUST be set by user. + * - decoding: unused + */ + int me_method; + + /** + * some codecs need / can use extra-data like huffman tables. + * mjpeg: huffman tables + * rv10: additional flags + * mpeg4: global headers (they can be in the bitstream or here) + * the allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger + * then extradata_size to avoid prolems if its read with the bitstream reader + * the bytewise contents of extradata must not depend on the architecture or cpu endianness + * - encoding: set/allocated/freed by lavc. + * - decoding: set/allocated/freed by user. + */ + void *extradata; + int extradata_size; + + /** + * this is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. for fixed-fps content, + * timebase should be 1/framerate and timestamp increments should be + * identically 1. + * - encoding: MUST be set by user + * - decoding: set by lavc. + */ + AVRational time_base; + + /* video only */ + /** + * picture width / height. + * - encoding: MUST be set by user. + * - decoding: set by lavc. + * Note, for compatibility its possible to set this instead of + * coded_width/height before decoding + */ + int width, height; + +#define FF_ASPECT_EXTENDED 15 + + /** + * the number of pictures in a group of pitures, or 0 for intra_only. + * - encoding: set by user. + * - decoding: unused + */ + int gop_size; + + /** + * pixel format, see PIX_FMT_xxx. + * - encoding: set by user. + * - decoding: set by lavc. + */ + enum PixelFormat pix_fmt; + + /** + * Frame rate emulation. If not zero lower layer (i.e. format handler) + * has to read frames at native frame rate. + * - encoding: set by user. + * - decoding: unused. + */ + int rate_emu; + + /** + * if non NULL, 'draw_horiz_band' is called by the libavcodec + * decoder to draw an horizontal band. It improve cache usage. Not + * all codecs can do that. You must check the codec capabilities + * before + * - encoding: unused + * - decoding: set by user. + * @param height the height of the slice + * @param y the y position of the slice + * @param type 1->top field, 2->bottom field, 3->frame + * @param offset offset into the AVFrame.data from which the slice should be read + */ + void (*draw_horiz_band)(struct AVCodecContext *s, + const AVFrame *src, int offset[4], + int y, int type, int height); + + /* audio only */ + int sample_rate; ///< samples per sec + int channels; + + /** + * audio sample format. + * - encoding: set by user. + * - decoding: set by lavc. + */ + enum SampleFormat sample_fmt; ///< sample format, currenly unused + + /* the following data should not be initialized */ + /** + * samples per packet. initialized when calling 'init' + */ + int frame_size; + int frame_number; ///< audio or video frame number + int real_pict_num; ///< returns the real picture number of previous encoded frame + + /** + * number of frames the decoded output will be delayed relative to + * the encoded input. + * - encoding: set by lavc. + * - decoding: unused + */ + int delay; + + /* - encoding parameters */ + float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) + float qblur; ///< amount of qscale smoothing over time (0.0-1.0) + + /** + * minimum quantizer. + * - encoding: set by user. + * - decoding: unused + */ + int qmin; + + /** + * maximum quantizer. + * - encoding: set by user. + * - decoding: unused + */ + int qmax; + + /** + * maximum quantizer difference etween frames. + * - encoding: set by user. + * - decoding: unused + */ + int max_qdiff; + + /** + * maximum number of b frames between non b frames. + * note: the output will be delayed by max_b_frames+1 relative to the input + * - encoding: set by user. + * - decoding: unused + */ + int max_b_frames; + + /** + * qscale factor between ip and b frames. + * - encoding: set by user. + * - decoding: unused + */ + float b_quant_factor; + + /** obsolete FIXME remove */ + int rc_strategy; +#define FF_RC_STRATEGY_XVID 1 + + int b_frame_strategy; + + /** + * hurry up amount. + * deprecated in favor of skip_idct and skip_frame + * - encoding: unused + * - decoding: set by user. 1-> skip b frames, 2-> skip idct/dequant too, 5-> skip everything except header + */ + int hurry_up; + + struct AVCodec *codec; + + void *priv_data; + + /* unused, FIXME remove*/ + int rtp_mode; + + int rtp_payload_size; /* The size of the RTP payload: the coder will */ + /* do it's best to deliver a chunk with size */ + /* below rtp_payload_size, the chunk will start */ + /* with a start code on some codecs like H.263 */ + /* This doesn't take account of any particular */ + /* headers inside the transmited RTP payload */ + + + /* The RTP callback: This function is called */ + /* every time the encoder has a packet to send */ + /* Depends on the encoder if the data starts */ + /* with a Start Code (it should) H.263 does. */ + /* mb_nb contains the number of macroblocks */ + /* encoded in the RTP payload */ + void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb); + + /* statistics, used for 2-pass encoding */ + int mv_bits; + int header_bits; + int i_tex_bits; + int p_tex_bits; + int i_count; + int p_count; + int skip_count; + int misc_bits; + + /** + * number of bits used for the previously encoded frame. + * - encoding: set by lavc + * - decoding: unused + */ + int frame_bits; + + /** + * private data of the user, can be used to carry app specific stuff. + * - encoding: set by user + * - decoding: set by user + */ + void *opaque; + + char codec_name[32]; + enum CodecType codec_type; /* see CODEC_TYPE_xxx */ + enum CodecID codec_id; /* see CODEC_ID_xxx */ + + /** + * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * this is used to workaround some encoder bugs + * - encoding: set by user, if not then the default based on codec_id will be used + * - decoding: set by user, will be converted to upper case by lavc during init + */ + unsigned int codec_tag; + + /** + * workaround bugs in encoders which sometimes cannot be detected automatically. + * - encoding: set by user + * - decoding: set by user + */ + int workaround_bugs; +#define FF_BUG_AUTODETECT 1 ///< autodetection +#define FF_BUG_OLD_MSMPEG4 2 +#define FF_BUG_XVID_ILACE 4 +#define FF_BUG_UMP4 8 +#define FF_BUG_NO_PADDING 16 +#define FF_BUG_AMV 32 +#define FF_BUG_AC_VLC 0 ///< will be removed, libavcodec can now handle these non compliant files by default +#define FF_BUG_QPEL_CHROMA 64 +#define FF_BUG_STD_QPEL 128 +#define FF_BUG_QPEL_CHROMA2 256 +#define FF_BUG_DIRECT_BLOCKSIZE 512 +#define FF_BUG_EDGE 1024 +#define FF_BUG_HPEL_CHROMA 2048 +#define FF_BUG_DC_CLIP 4096 +#define FF_BUG_MS 8192 ///< workaround various bugs in microsofts broken decoders +//#define FF_BUG_FAKE_SCALABILITY 16 //autodetection should work 100% + + /** + * luma single coeff elimination threshold. + * - encoding: set by user + * - decoding: unused + */ + int luma_elim_threshold; + + /** + * chroma single coeff elimination threshold. + * - encoding: set by user + * - decoding: unused + */ + int chroma_elim_threshold; + + /** + * strictly follow the std (MPEG4, ...). + * - encoding: set by user + * - decoding: unused + */ + int strict_std_compliance; +#define FF_COMPLIANCE_VERY_STRICT 2 ///< strictly conform to a older more strict version of the spec or reference software +#define FF_COMPLIANCE_STRICT 1 ///< strictly conform to all the things in the spec no matter what consequences +#define FF_COMPLIANCE_NORMAL 0 +#define FF_COMPLIANCE_INOFFICIAL -1 ///< allow inofficial extensions +#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< allow non standarized experimental things + + /** + * qscale offset between ip and b frames. + * if > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset) + * if < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset) + * - encoding: set by user. + * - decoding: unused + */ + float b_quant_offset; + + /** + * error resilience higher values will detect more errors but may missdetect + * some more or less valid parts as errors. + * - encoding: unused + * - decoding: set by user + */ + int error_resilience; +#define FF_ER_CAREFUL 1 +#define FF_ER_COMPLIANT 2 +#define FF_ER_AGGRESSIVE 3 +#define FF_ER_VERY_AGGRESSIVE 4 + + /** + * called at the beginning of each frame to get a buffer for it. + * if pic.reference is set then the frame will be read later by lavc + * avcodec_align_dimensions() should be used to find the required width and + * height, as they normally need to be rounded up to the next multiple of 16 + * - encoding: unused + * - decoding: set by lavc, user can override + */ + int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * called to release buffers which where allocated with get_buffer. + * a released buffer can be reused in get_buffer() + * pic.data[*] must be set to NULL + * - encoding: unused + * - decoding: set by lavc, user can override + */ + void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * if 1 the stream has a 1 frame delay during decoding. + * - encoding: set by lavc + * - decoding: set by lavc + */ + int has_b_frames; + + /** + * number of bytes per packet if constant and known or 0 + * used by some WAV based audio codecs + */ + int block_align; + + int parse_only; /* - decoding only: if true, only parsing is done + (function avcodec_parse_frame()). The frame + data is returned. Only MPEG codecs support this now. */ + + /** + * 0-> h263 quant 1-> mpeg quant. + * - encoding: set by user. + * - decoding: unused + */ + int mpeg_quant; + + /** + * pass1 encoding statistics output buffer. + * - encoding: set by lavc + * - decoding: unused + */ + char *stats_out; + + /** + * pass2 encoding statistics input buffer. + * concatenated stuff from stats_out of pass1 should be placed here + * - encoding: allocated/set/freed by user + * - decoding: unused + */ + char *stats_in; + + /** + * ratecontrol qmin qmax limiting method. + * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax + * - encoding: set by user. + * - decoding: unused + */ + float rc_qsquish; + + float rc_qmod_amp; + int rc_qmod_freq; + + /** + * ratecontrol override, see RcOverride. + * - encoding: allocated/set/freed by user. + * - decoding: unused + */ + RcOverride *rc_override; + int rc_override_count; + + /** + * rate control equation. + * - encoding: set by user + * - decoding: unused + */ + char *rc_eq; + + /** + * maximum bitrate. + * - encoding: set by user. + * - decoding: unused + */ + int rc_max_rate; + + /** + * minimum bitrate. + * - encoding: set by user. + * - decoding: unused + */ + int rc_min_rate; + + /** + * decoder bitstream buffer size. + * - encoding: set by user. + * - decoding: unused + */ + int rc_buffer_size; + float rc_buffer_aggressivity; + + /** + * qscale factor between p and i frames. + * if > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset) + * if < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset) + * - encoding: set by user. + * - decoding: unused + */ + float i_quant_factor; + + /** + * qscale offset between p and i frames. + * - encoding: set by user. + * - decoding: unused + */ + float i_quant_offset; + + /** + * initial complexity for pass1 ratecontrol. + * - encoding: set by user. + * - decoding: unused + */ + float rc_initial_cplx; + + /** + * dct algorithm, see FF_DCT_* below. + * - encoding: set by user + * - decoding: unused + */ + int dct_algo; +#define FF_DCT_AUTO 0 +#define FF_DCT_FASTINT 1 +#define FF_DCT_INT 2 +#define FF_DCT_MMX 3 +#define FF_DCT_MLIB 4 +#define FF_DCT_ALTIVEC 5 +#define FF_DCT_FAAN 6 + + /** + * luminance masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float lumi_masking; + + /** + * temporary complexity masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float temporal_cplx_masking; + + /** + * spatial complexity masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float spatial_cplx_masking; + + /** + * p block masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float p_masking; + + /** + * darkness masking (0-> disabled). + * - encoding: set by user + * - decoding: unused + */ + float dark_masking; + + + /* for binary compatibility */ + int unused; + + /** + * idct algorithm, see FF_IDCT_* below. + * - encoding: set by user + * - decoding: set by user + */ + int idct_algo; +#define FF_IDCT_AUTO 0 +#define FF_IDCT_INT 1 +#define FF_IDCT_SIMPLE 2 +#define FF_IDCT_SIMPLEMMX 3 +#define FF_IDCT_LIBMPEG2MMX 4 +#define FF_IDCT_PS2 5 +#define FF_IDCT_MLIB 6 +#define FF_IDCT_ARM 7 +#define FF_IDCT_ALTIVEC 8 +#define FF_IDCT_SH4 9 +#define FF_IDCT_SIMPLEARM 10 +#define FF_IDCT_H264 11 +#define FF_IDCT_VP3 12 +#define FF_IDCT_IPP 13 +#define FF_IDCT_XVIDMMX 14 + + /** + * slice count. + * - encoding: set by lavc + * - decoding: set by user (or 0) + */ + int slice_count; + /** + * slice offsets in the frame in bytes. + * - encoding: set/allocated by lavc + * - decoding: set/allocated by user (or NULL) + */ + int *slice_offset; + + /** + * error concealment flags. + * - encoding: unused + * - decoding: set by user + */ + int error_concealment; +#define FF_EC_GUESS_MVS 1 +#define FF_EC_DEBLOCK 2 + + /** + * dsp_mask could be add used to disable unwanted CPU features + * CPU features (i.e. MMX, SSE. ...) + * + * with FORCE flag you may instead enable given CPU features + * (Dangerous: usable in case of misdetection, improper usage however will + * result into program crash) + */ + unsigned dsp_mask; +#define FF_MM_FORCE 0x80000000 /* force usage of selected flags (OR) */ + /* lower 16 bits - CPU features */ +#ifdef HAVE_MMX +#define FF_MM_MMX 0x0001 /* standard MMX */ +#define FF_MM_3DNOW 0x0004 /* AMD 3DNOW */ +#define FF_MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */ +#define FF_MM_SSE 0x0008 /* SSE functions */ +#define FF_MM_SSE2 0x0010 /* PIV SSE2 functions */ +#define FF_MM_3DNOWEXT 0x0020 /* AMD 3DNowExt */ +#endif /* HAVE_MMX */ +#ifdef HAVE_IWMMXT +#define FF_MM_IWMMXT 0x0100 /* XScale IWMMXT */ +#endif /* HAVE_IWMMXT */ + + /** + * bits per sample/pixel from the demuxer (needed for huffyuv). + * - encoding: set by lavc + * - decoding: set by user + */ + int bits_per_sample; + + /** + * prediction method (needed for huffyuv). + * - encoding: set by user + * - decoding: unused + */ + int prediction_method; +#define FF_PRED_LEFT 0 +#define FF_PRED_PLANE 1 +#define FF_PRED_MEDIAN 2 + + /** + * sample aspect ratio (0 if unknown). + * numerator and denominator must be relative prime and smaller then 256 for some video standards + * - encoding: set by user. + * - decoding: set by lavc. + */ + AVRational sample_aspect_ratio; + + /** + * the picture in the bitstream. + * - encoding: set by lavc + * - decoding: set by lavc + */ + AVFrame *coded_frame; + + /** + * debug. + * - encoding: set by user. + * - decoding: set by user. + */ + int debug; +#define FF_DEBUG_PICT_INFO 1 +#define FF_DEBUG_RC 2 +#define FF_DEBUG_BITSTREAM 4 +#define FF_DEBUG_MB_TYPE 8 +#define FF_DEBUG_QP 16 +#define FF_DEBUG_MV 32 +#define FF_DEBUG_DCT_COEFF 0x00000040 +#define FF_DEBUG_SKIP 0x00000080 +#define FF_DEBUG_STARTCODE 0x00000100 +#define FF_DEBUG_PTS 0x00000200 +#define FF_DEBUG_ER 0x00000400 +#define FF_DEBUG_MMCO 0x00000800 +#define FF_DEBUG_BUGS 0x00001000 +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 + + /** + * debug. + * - encoding: set by user. + * - decoding: set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames + + /** + * error. + * - encoding: set by lavc if flags&CODEC_FLAG_PSNR + * - decoding: unused + */ + uint64_t error[4]; + + /** + * minimum MB quantizer. + * - encoding: unused + * - decoding: unused + */ + int mb_qmin; + + /** + * maximum MB quantizer. + * - encoding: unused + * - decoding: unused + */ + int mb_qmax; + + /** + * motion estimation compare function. + * - encoding: set by user. + * - decoding: unused + */ + int me_cmp; + /** + * subpixel motion estimation compare function. + * - encoding: set by user. + * - decoding: unused + */ + int me_sub_cmp; + /** + * macroblock compare function (not supported yet). + * - encoding: set by user. + * - decoding: unused + */ + int mb_cmp; + /** + * interlaced dct compare function + * - encoding: set by user. + * - decoding: unused + */ + int ildct_cmp; +#define FF_CMP_SAD 0 +#define FF_CMP_SSE 1 +#define FF_CMP_SATD 2 +#define FF_CMP_DCT 3 +#define FF_CMP_PSNR 4 +#define FF_CMP_BIT 5 +#define FF_CMP_RD 6 +#define FF_CMP_ZERO 7 +#define FF_CMP_VSAD 8 +#define FF_CMP_VSSE 9 +#define FF_CMP_NSSE 10 +#define FF_CMP_W53 11 +#define FF_CMP_W97 12 +#define FF_CMP_DCTMAX 13 +#define FF_CMP_DCT264 14 +#define FF_CMP_CHROMA 256 + + /** + * ME diamond size & shape. + * - encoding: set by user. + * - decoding: unused + */ + int dia_size; + + /** + * amount of previous MV predictors (2a+1 x 2a+1 square). + * - encoding: set by user. + * - decoding: unused + */ + int last_predictor_count; + + /** + * pre pass for motion estimation. + * - encoding: set by user. + * - decoding: unused + */ + int pre_me; + + /** + * motion estimation pre pass compare function. + * - encoding: set by user. + * - decoding: unused + */ + int me_pre_cmp; + + /** + * ME pre pass diamond size & shape. + * - encoding: set by user. + * - decoding: unused + */ + int pre_dia_size; + + /** + * subpel ME quality. + * - encoding: set by user. + * - decoding: unused + */ + int me_subpel_quality; + + /** + * callback to negotiate the pixelFormat. + * @param fmt is the list of formats which are supported by the codec, + * its terminated by -1 as 0 is a valid format, the formats are ordered by quality + * the first is allways the native one + * @return the choosen format + * - encoding: unused + * - decoding: set by user, if not set then the native format will always be choosen + */ + enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt); + + /** + * DTG active format information (additionnal aspect ratio + * information only used in DVB MPEG2 transport streams). 0 if + * not set. + * + * - encoding: unused. + * - decoding: set by decoder + */ + int dtg_active_format; +#define FF_DTG_AFD_SAME 8 +#define FF_DTG_AFD_4_3 9 +#define FF_DTG_AFD_16_9 10 +#define FF_DTG_AFD_14_9 11 +#define FF_DTG_AFD_4_3_SP_14_9 13 +#define FF_DTG_AFD_16_9_SP_14_9 14 +#define FF_DTG_AFD_SP_4_3 15 + + /** + * Maximum motion estimation search range in subpel units. + * if 0 then no limit + * + * - encoding: set by user. + * - decoding: unused. + */ + int me_range; + + /** + * intra quantizer bias. + * - encoding: set by user. + * - decoding: unused + */ + int intra_quant_bias; +#define FF_DEFAULT_QUANT_BIAS 999999 + + /** + * inter quantizer bias. + * - encoding: set by user. + * - decoding: unused + */ + int inter_quant_bias; + + /** + * color table ID. + * - encoding: unused. + * - decoding: which clrtable should be used for 8bit RGB images + * table have to be stored somewhere FIXME + */ + int color_table_id; + + /** + * internal_buffer count. + * Don't touch, used by lavc default_get_buffer() + */ + int internal_buffer_count; + + /** + * internal_buffers. + * Don't touch, used by lavc default_get_buffer() + */ + void *internal_buffer; + +#define FF_LAMBDA_SHIFT 7 +#define FF_LAMBDA_SCALE (1< ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * this is used to workaround some encoder bugs + * - encoding: unused + * - decoding: set by user, will be converted to upper case by lavc during init + */ + unsigned int stream_codec_tag; + + /** + * scene change detection threshold. + * 0 is default, larger means fewer detected scene changes + * - encoding: set by user. + * - decoding: unused + */ + int scenechange_threshold; + + /** + * minimum lagrange multipler + * - encoding: set by user. + * - decoding: unused + */ + int lmin; + + /** + * maximum lagrange multipler + * - encoding: set by user. + * - decoding: unused + */ + int lmax; + + /** + * Palette control structure + * - encoding: ??? (no palette-enabled encoder yet) + * - decoding: set by user. + */ + struct AVPaletteControl *palctrl; + + /** + * noise reduction strength + * - encoding: set by user. + * - decoding: unused + */ + int noise_reduction; + + /** + * called at the beginning of a frame to get cr buffer for it. + * buffer type (size, hints) must be the same. lavc won't check it. + * lavc will pass previous buffer in pic, function should return + * same buffer or new buffer with old frame "painted" into it. + * if pic.data[0] == NULL must behave like get_buffer(). + * - encoding: unused + * - decoding: set by lavc, user can override + */ + int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * number of bits which should be loaded into the rc buffer before decoding starts + * - encoding: set by user. + * - decoding: unused + */ + int rc_initial_buffer_occupancy; + + /** + * + * - encoding: set by user. + * - decoding: unused + */ + int inter_threshold; + + /** + * CODEC_FLAG2_*. + * - encoding: set by user. + * - decoding: set by user. + */ + int flags2; + + /** + * simulates errors in the bitstream to test error concealment. + * - encoding: set by user. + * - decoding: unused. + */ + int error_rate; + + /** + * MP3 antialias algorithm, see FF_AA_* below. + * - encoding: unused + * - decoding: set by user + */ + int antialias_algo; +#define FF_AA_AUTO 0 +#define FF_AA_FASTINT 1 //not implemented yet +#define FF_AA_INT 2 +#define FF_AA_FLOAT 3 + /** + * Quantizer noise shaping. + * - encoding: set by user + * - decoding: unused + */ + int quantizer_noise_shaping; + + /** + * Thread count. + * is used to decide how many independant tasks should be passed to execute() + * - encoding: set by user + * - decoding: set by user + */ + int thread_count; + + /** + * the codec may call this to execute several independant things. it will return only after + * finishing all tasks, the user may replace this with some multithreaded implementation, the + * default implementation will execute the parts serially + * @param count the number of things to execute + * - encoding: set by lavc, user can override + * - decoding: set by lavc, user can override + */ + int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void **arg2, int *ret, int count); + + /** + * Thread opaque. + * can be used by execute() to store some per AVCodecContext stuff. + * - encoding: set by execute() + * - decoding: set by execute() + */ + void *thread_opaque; + + /** + * Motion estimation threshold. under which no motion estimation is + * performed, but instead the user specified motion vectors are used + * + * - encoding: set by user + * - decoding: unused + */ + int me_threshold; + + /** + * Macroblock threshold. under which the user specified macroblock types will be used + * - encoding: set by user + * - decoding: unused + */ + int mb_threshold; + + /** + * precision of the intra dc coefficient - 8. + * - encoding: set by user + * - decoding: unused + */ + int intra_dc_precision; + + /** + * noise vs. sse weight for the nsse comparsion function. + * - encoding: set by user + * - decoding: unused + */ + int nsse_weight; + + /** + * number of macroblock rows at the top which are skipped. + * - encoding: unused + * - decoding: set by user + */ + int skip_top; + + /** + * number of macroblock rows at the bottom which are skipped. + * - encoding: unused + * - decoding: set by user + */ + int skip_bottom; + + /** + * profile + * - encoding: set by user + * - decoding: set by lavc + */ + int profile; +#define FF_PROFILE_UNKNOWN -99 + + /** + * level + * - encoding: set by user + * - decoding: set by lavc + */ + int level; +#define FF_LEVEL_UNKNOWN -99 + + /** + * low resolution decoding. 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: set by user + */ + int lowres; + + /** + * bitsream width / height. may be different from width/height if lowres + * or other things are used + * - encoding: unused + * - decoding: set by user before init if known, codec should override / dynamically change if needed + */ + int coded_width, coded_height; + + /** + * frame skip threshold + * - encoding: set by user + * - decoding: unused + */ + int frame_skip_threshold; + + /** + * frame skip factor + * - encoding: set by user + * - decoding: unused + */ + int frame_skip_factor; + + /** + * frame skip exponent + * - encoding: set by user + * - decoding: unused + */ + int frame_skip_exp; + + /** + * frame skip comparission function + * - encoding: set by user. + * - decoding: unused + */ + int frame_skip_cmp; + + /** + * border processing masking. raises the quantizer for mbs on the borders + * of the picture. + * - encoding: set by user + * - decoding: unused + */ + float border_masking; + + /** + * minimum MB lagrange multipler. + * - encoding: set by user. + * - decoding: unused + */ + int mb_lmin; + + /** + * maximum MB lagrange multipler. + * - encoding: set by user. + * - decoding: unused + */ + int mb_lmax; + + /** + * + * - encoding: set by user. + * - decoding: unused + */ + int me_penalty_compensation; + + /** + * + * - encoding: unused + * - decoding: set by user. + */ + enum AVDiscard skip_loop_filter; + + /** + * + * - encoding: unused + * - decoding: set by user. + */ + enum AVDiscard skip_idct; + + /** + * + * - encoding: unused + * - decoding: set by user. + */ + enum AVDiscard skip_frame; + + /** + * + * - encoding: set by user. + * - decoding: unused + */ + int bidir_refine; + + /** + * + * - encoding: set by user. + * - decoding: unused + */ + int brd_scale; + + /** + * constant rate factor - quality-based VBR - values ~correspond to qps + * - encoding: set by user. + * - decoding: unused + */ + int crf; + + /** + * constant quantization parameter rate control method + * - encoding: set by user. + * - decoding: unused + */ + int cqp; + + /** + * minimum gop size + * - encoding: set by user. + * - decoding: unused + */ + int keyint_min; + + /** + * number of reference frames + * - encoding: set by user. + * - decoding: unused + */ + int refs; + + /** + * chroma qp offset from luma + * - encoding: set by user. + * - decoding: unused + */ + int chromaoffset; + + /** + * influences how often b-frames are used + * - encoding: set by user. + * - decoding: unused + */ + int bframebias; + + /** + * trellis RD quantization + * - encoding: set by user. + * - decoding: unused + */ + int trellis; + + /** + * reduce fluctuations in qp (before curve compression) + * - encoding: set by user. + * - decoding: unused + */ + float complexityblur; + + /** + * in-loop deblocking filter alphac0 parameter + * alpha is in the range -6...6 + * - encoding: set by user. + * - decoding: unused + */ + int deblockalpha; + + /** + * in-loop deblocking filter beta parameter + * beta is in the range -6...6 + * - encoding: set by user. + * - decoding: unused + */ + int deblockbeta; + + /** + * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4 + * - encoding: set by user. + * - decoding: unused + */ + int partitions; +#define X264_PART_I4X4 0x001 /* Analyse i4x4 */ +#define X264_PART_I8X8 0x002 /* Analyse i8x8 (requires 8x8 transform) */ +#define X264_PART_P8X8 0x010 /* Analyse p16x8, p8x16 and p8x8 */ +#define X264_PART_P4X4 0x020 /* Analyse p8x4, p4x8, p4x4 */ +#define X264_PART_B8X8 0x100 /* Analyse b16x8, b8x16 and b8x8 */ + + /** + * direct mv prediction mode - 0 (none), 1 (spatial), 2 (temporal) + * - encoding: set by user. + * - decoding: unused + */ + int directpred; + + /** + * audio cutoff bandwidth (0 means "automatic") . Currently used only by FAAC + * - encoding: set by user. + * - decoding: unused + */ + int cutoff; + + /** + * multiplied by qscale for each frame and added to scene_change_score + * - encoding: set by user. + * - decoding: unused + */ + int scenechange_factor; +} AVCodecContext; + +/** + * AVCodec. + */ +typedef struct AVCodec { + const char *name; + enum CodecType type; + enum CodecID id; + int priv_data_size; + int (*init)(AVCodecContext *); + int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); + int (*close)(AVCodecContext *); + int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, + uint8_t *buf, int buf_size); + int capabilities; +#if LIBAVCODEC_VERSION_INT < ((50<<16)+(0<<8)+0) + void *dummy; // FIXME remove next time we break binary compatibility +#endif + struct AVCodec *next; + void (*flush)(AVCodecContext *); + const AVRational *supported_framerates; ///array of supported framerates, or NULL if any, array is terminated by {0,0} + const enum PixelFormat *pix_fmts; ///array of supported pixel formats, or NULL if unknown, array is terminanted by -1 +} AVCodec; + +/** + * four components are given, that's all. + * the last component is alpha + */ +typedef struct AVPicture { + uint8_t *data[4]; + int linesize[4]; ///< number of bytes per line +} AVPicture; + +/** + * AVPaletteControl + * This structure defines a method for communicating palette changes + * between and demuxer and a decoder. + */ +#define AVPALETTE_SIZE 1024 +#define AVPALETTE_COUNT 256 +typedef struct AVPaletteControl { + + /* demuxer sets this to 1 to indicate the palette has changed; + * decoder resets to 0 */ + int palette_changed; + + /* 4-byte ARGB palette entries, stored in native byte order; note that + * the individual palette components should be on a 8-bit scale; if + * the palette data comes from a IBM VGA native format, the component + * data is probably 6 bits in size and needs to be scaled */ + unsigned int palette[AVPALETTE_COUNT]; + +} AVPaletteControl; + +typedef struct AVSubtitleRect { + uint16_t x; + uint16_t y; + uint16_t w; + uint16_t h; + uint16_t nb_colors; + int linesize; + uint32_t *rgba_palette; + uint8_t *bitmap; +} AVSubtitleRect; + +typedef struct AVSubtitle { + uint16_t format; /* 0 = graphics */ + uint32_t start_display_time; /* relative to packet pts, in ms */ + uint32_t end_display_time; /* relative to packet pts, in ms */ + uint32_t num_rects; + AVSubtitleRect *rects; +} AVSubtitle; + +extern AVCodec ac3_encoder; +extern AVCodec mp2_encoder; +extern AVCodec mp3lame_encoder; +extern AVCodec oggvorbis_encoder; +extern AVCodec oggtheora_encoder; +extern AVCodec faac_encoder; +extern AVCodec xvid_encoder; +extern AVCodec mpeg1video_encoder; +extern AVCodec mpeg2video_encoder; +extern AVCodec h261_encoder; +extern AVCodec h263_encoder; +extern AVCodec h263p_encoder; +extern AVCodec flv_encoder; +extern AVCodec rv10_encoder; +extern AVCodec rv20_encoder; +extern AVCodec dvvideo_encoder; +extern AVCodec mjpeg_encoder; +extern AVCodec ljpeg_encoder; +extern AVCodec jpegls_encoder; +extern AVCodec png_encoder; +extern AVCodec ppm_encoder; +extern AVCodec pgm_encoder; +extern AVCodec pgmyuv_encoder; +extern AVCodec pbm_encoder; +extern AVCodec pam_encoder; +extern AVCodec mpeg4_encoder; +extern AVCodec msmpeg4v1_encoder; +extern AVCodec msmpeg4v2_encoder; +extern AVCodec msmpeg4v3_encoder; +extern AVCodec wmv1_encoder; +extern AVCodec wmv2_encoder; +extern AVCodec huffyuv_encoder; +extern AVCodec ffvhuff_encoder; +extern AVCodec h264_encoder; +extern AVCodec asv1_encoder; +extern AVCodec asv2_encoder; +extern AVCodec vcr1_encoder; +extern AVCodec ffv1_encoder; +extern AVCodec snow_encoder; +extern AVCodec mdec_encoder; +extern AVCodec zlib_encoder; +extern AVCodec sonic_encoder; +extern AVCodec sonic_ls_encoder; +extern AVCodec svq1_encoder; +extern AVCodec x264_encoder; + +extern AVCodec h263_decoder; +extern AVCodec h261_decoder; +extern AVCodec mpeg4_decoder; +extern AVCodec msmpeg4v1_decoder; +extern AVCodec msmpeg4v2_decoder; +extern AVCodec msmpeg4v3_decoder; +extern AVCodec wmv1_decoder; +extern AVCodec wmv2_decoder; +extern AVCodec vc9_decoder; +extern AVCodec wmv3_decoder; +extern AVCodec mpeg1video_decoder; +extern AVCodec mpeg2video_decoder; +extern AVCodec mpegvideo_decoder; +extern AVCodec mpeg_xvmc_decoder; +extern AVCodec h263i_decoder; +extern AVCodec flv_decoder; +extern AVCodec rv10_decoder; +extern AVCodec rv20_decoder; +extern AVCodec rv30_decoder; +extern AVCodec rv40_decoder; +extern AVCodec svq1_decoder; +extern AVCodec svq3_decoder; +extern AVCodec dvvideo_decoder; +extern AVCodec wmav1_decoder; +extern AVCodec wmav2_decoder; +extern AVCodec mjpeg_decoder; +extern AVCodec mjpegb_decoder; +extern AVCodec sp5x_decoder; +extern AVCodec png_decoder; +extern AVCodec mp2_decoder; +extern AVCodec mp3_decoder; +extern AVCodec mp3adu_decoder; +extern AVCodec mp3on4_decoder; +extern AVCodec qdm2_decoder; +extern AVCodec cook_decoder; +extern AVCodec truespeech_decoder; +extern AVCodec tta_decoder; +extern AVCodec mace3_decoder; +extern AVCodec mace6_decoder; +extern AVCodec huffyuv_decoder; +extern AVCodec ffvhuff_decoder; +extern AVCodec oggvorbis_decoder; +extern AVCodec oggtheora_decoder; +extern AVCodec cyuv_decoder; +extern AVCodec h264_decoder; +extern AVCodec indeo3_decoder; +extern AVCodec vp3_decoder; +extern AVCodec theora_decoder; +extern AVCodec amr_nb_decoder; +extern AVCodec amr_nb_encoder; +extern AVCodec amr_wb_encoder; +extern AVCodec amr_wb_decoder; +extern AVCodec aac_decoder; +extern AVCodec mpeg4aac_decoder; +extern AVCodec asv1_decoder; +extern AVCodec asv2_decoder; +extern AVCodec vcr1_decoder; +extern AVCodec cljr_decoder; +extern AVCodec ffv1_decoder; +extern AVCodec snow_decoder; +extern AVCodec fourxm_decoder; +extern AVCodec mdec_decoder; +extern AVCodec roq_decoder; +extern AVCodec interplay_video_decoder; +extern AVCodec xan_wc3_decoder; +extern AVCodec rpza_decoder; +extern AVCodec cinepak_decoder; +extern AVCodec msrle_decoder; +extern AVCodec msvideo1_decoder; +extern AVCodec vqa_decoder; +extern AVCodec idcin_decoder; +extern AVCodec eightbps_decoder; +extern AVCodec smc_decoder; +extern AVCodec flic_decoder; +extern AVCodec vmdvideo_decoder; +extern AVCodec vmdaudio_decoder; +extern AVCodec truemotion1_decoder; +extern AVCodec truemotion2_decoder; +extern AVCodec mszh_decoder; +extern AVCodec zlib_decoder; +extern AVCodec ra_144_decoder; +extern AVCodec ra_288_decoder; +extern AVCodec roq_dpcm_decoder; +extern AVCodec interplay_dpcm_decoder; +extern AVCodec xan_dpcm_decoder; +extern AVCodec sol_dpcm_decoder; +extern AVCodec sonic_decoder; +extern AVCodec qtrle_decoder; +extern AVCodec flac_decoder; +extern AVCodec tscc_decoder; +extern AVCodec cscd_decoder; +extern AVCodec nuv_decoder; +extern AVCodec ulti_decoder; +extern AVCodec qdraw_decoder; +extern AVCodec xl_decoder; +extern AVCodec qpeg_decoder; +extern AVCodec shorten_decoder; +extern AVCodec loco_decoder; +extern AVCodec wnv1_decoder; +extern AVCodec aasc_decoder; +extern AVCodec alac_decoder; +extern AVCodec ws_snd1_decoder; +extern AVCodec indeo2_decoder; +extern AVCodec vorbis_decoder; +extern AVCodec fraps_decoder; +extern AVCodec libgsm_encoder; +extern AVCodec libgsm_decoder; +extern AVCodec bmp_decoder; +extern AVCodec mmvideo_decoder; +extern AVCodec zmbv_decoder; +extern AVCodec avs_decoder; +extern AVCodec smacker_decoder; +extern AVCodec smackaud_decoder; +extern AVCodec kmvc_decoder; + +/* pcm codecs */ +#define PCM_CODEC(id, name) \ +extern AVCodec name ## _decoder; \ +extern AVCodec name ## _encoder + +PCM_CODEC(CODEC_ID_PCM_S32LE, pcm_s32le); +PCM_CODEC(CODEC_ID_PCM_S32BE, pcm_s32be); +PCM_CODEC(CODEC_ID_PCM_U32LE, pcm_u32le); +PCM_CODEC(CODEC_ID_PCM_U32BE, pcm_u32be); +PCM_CODEC(CODEC_ID_PCM_S24LE, pcm_s24le); +PCM_CODEC(CODEC_ID_PCM_S24BE, pcm_s24be); +PCM_CODEC(CODEC_ID_PCM_U24LE, pcm_u24le); +PCM_CODEC(CODEC_ID_PCM_U24BE, pcm_u24be); +PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); +PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); +PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); +PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); +PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); +PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); +PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); +PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); +PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); + +/* adpcm codecs */ + +PCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); +PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); +PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); +PCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); +PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws); +PCM_CODEC(CODEC_ID_ADPCM_SMJPEG, adpcm_ima_smjpeg); +PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); +PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); +PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); +PCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx); +PCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); +PCM_CODEC(CODEC_ID_ADPCM_G726, adpcm_g726); +PCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct); +PCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf); +PCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); +PCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4); +PCM_CODEC(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3); +PCM_CODEC(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2); + +#undef PCM_CODEC + +/* dummy raw video codec */ +extern AVCodec rawvideo_encoder; +extern AVCodec rawvideo_decoder; + +/* the following codecs use external GPL libs */ +extern AVCodec ac3_decoder; +extern AVCodec dts_decoder; + +/* subtitles */ +extern AVCodec dvdsub_encoder; +extern AVCodec dvdsub_decoder; +extern AVCodec dvbsub_encoder; +extern AVCodec dvbsub_decoder; + +/* resample.c */ + +struct ReSampleContext; +struct AVResampleContext; + +typedef struct ReSampleContext ReSampleContext; + +ReSampleContext *audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate); +int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); +void audio_resample_close(ReSampleContext *s); + +struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); +int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); +void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); +void av_resample_close(struct AVResampleContext *c); + +/* YUV420 format is assumed ! */ + +struct ImgReSampleContext; + +typedef struct ImgReSampleContext ImgReSampleContext; + +ImgReSampleContext *img_resample_init(int output_width, int output_height, + int input_width, int input_height); + +ImgReSampleContext *img_resample_full_init(int owidth, int oheight, + int iwidth, int iheight, + int topBand, int bottomBand, + int leftBand, int rightBand, + int padtop, int padbottom, + int padleft, int padright); + + +void img_resample(ImgReSampleContext *s, + AVPicture *output, const AVPicture *input); + +void img_resample_close(ImgReSampleContext *s); + +/** + * Allocate memory for a picture. Call avpicture_free to free it. + * + * @param picture the picture to be filled in. + * @param pix_fmt the format of the picture. + * @param width the width of the picture. + * @param height the height of the picture. + * @return 0 if successful, -1 if not. + */ +int avpicture_alloc(AVPicture *picture, int pix_fmt, int width, int height); + +/* Free a picture previously allocated by avpicture_alloc. */ +void avpicture_free(AVPicture *picture); + +int avpicture_fill(AVPicture *picture, uint8_t *ptr, + int pix_fmt, int width, int height); +int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, + unsigned char *dest, int dest_size); +int avpicture_get_size(int pix_fmt, int width, int height); +void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift); +const char *avcodec_get_pix_fmt_name(int pix_fmt); +void avcodec_set_dimensions(AVCodecContext *s, int width, int height); +enum PixelFormat avcodec_get_pix_fmt(const char* name); +unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat p); + +#define FF_LOSS_RESOLUTION 0x0001 /* loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /* loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /* loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /* loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /* loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /* loss of chroma (e.g. rgb to gray conversion) */ + +int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, + int has_alpha); +int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, + int has_alpha, int *loss_ptr); + +#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ +#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ +int img_get_alpha_info(const AVPicture *src, + int pix_fmt, int width, int height); + +/* convert among pixel formats */ +int img_convert(AVPicture *dst, int dst_pix_fmt, + const AVPicture *src, int pix_fmt, + int width, int height); + +/* deinterlace a picture */ +int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height); + +/* external high level API */ + +extern AVCodec *first_avcodec; + +/* returns LIBAVCODEC_VERSION_INT constant */ +unsigned avcodec_version(void); +/* returns LIBAVCODEC_BUILD constant */ +unsigned avcodec_build(void); +void avcodec_init(void); + +void register_avcodec(AVCodec *format); +AVCodec *avcodec_find_encoder(enum CodecID id); +AVCodec *avcodec_find_encoder_by_name(const char *name); +AVCodec *avcodec_find_decoder(enum CodecID id); +AVCodec *avcodec_find_decoder_by_name(const char *name); +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); + +void avcodec_get_context_defaults(AVCodecContext *s); +AVCodecContext *avcodec_alloc_context(void); +void avcodec_get_frame_defaults(AVFrame *pic); +AVFrame *avcodec_alloc_frame(void); + +int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); +int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); +int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h); +enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt); + +int avcodec_thread_init(AVCodecContext *s, int thread_count); +void avcodec_thread_free(AVCodecContext *s); +int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void **arg, int *ret, int count); +int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void **arg, int *ret, int count); +//FIXME func typedef + +/** + * opens / inits the AVCodecContext. + * not thread save! + */ +int avcodec_open(AVCodecContext *avctx, AVCodec *codec); + +int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + uint8_t *buf, int buf_size); +int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + uint8_t *buf, int buf_size); +int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + const uint8_t *buf, int buf_size); +int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, + int *data_size_ptr, + uint8_t *buf, int buf_size); +int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const short *samples); +int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVFrame *pict); +int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVSubtitle *sub); + +int avcodec_close(AVCodecContext *avctx); + +void avcodec_register_all(void); + +void avcodec_flush_buffers(AVCodecContext *avctx); + +void avcodec_default_free_buffers(AVCodecContext *s); + +/* misc usefull functions */ + +/** + * returns a single letter to describe the picture type + */ +char av_get_pict_type_char(int pict_type); + + +/* frame parsing */ +typedef struct AVCodecParserContext { + void *priv_data; + struct AVCodecParser *parser; + int64_t frame_offset; /* offset of the current frame */ + int64_t cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + int64_t last_frame_offset; /* offset of the last frame */ + /* video info */ + int pict_type; /* XXX: put it back in AVCodecContext */ + int repeat_pict; /* XXX: put it back in AVCodecContext */ + int64_t pts; /* pts of the current frame */ + int64_t dts; /* dts of the current frame */ + + /* private data */ + int64_t last_pts; + int64_t last_dts; + int fetch_timestamp; + +#define AV_PARSER_PTS_NB 4 + int cur_frame_start_index; + int64_t cur_frame_offset[AV_PARSER_PTS_NB]; + int64_t cur_frame_pts[AV_PARSER_PTS_NB]; + int64_t cur_frame_dts[AV_PARSER_PTS_NB]; + + int flags; +#define PARSER_FLAG_COMPLETE_FRAMES 0x0001 +} AVCodecParserContext; + +typedef struct AVCodecParser { + int codec_ids[5]; /* several codec IDs are permitted */ + int priv_data_size; + int (*parser_init)(AVCodecParserContext *s); + int (*parser_parse)(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + void (*parser_close)(AVCodecParserContext *s); + int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); + struct AVCodecParser *next; +} AVCodecParser; + +extern AVCodecParser *av_first_parser; + +void av_register_codec_parser(AVCodecParser *parser); +AVCodecParserContext *av_parser_init(int codec_id); +int av_parser_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts); +int av_parser_change(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_parser_close(AVCodecParserContext *s); + +extern AVCodecParser mpegvideo_parser; +extern AVCodecParser mpeg4video_parser; +extern AVCodecParser h261_parser; +extern AVCodecParser h263_parser; +extern AVCodecParser h264_parser; +extern AVCodecParser mjpeg_parser; +extern AVCodecParser pnm_parser; +extern AVCodecParser mpegaudio_parser; +extern AVCodecParser ac3_parser; +extern AVCodecParser dvdsub_parser; +extern AVCodecParser dvbsub_parser; +extern AVCodecParser aac_parser; + +/* memory */ +void *av_malloc(unsigned int size); +void *av_mallocz(unsigned int size); +void *av_realloc(void *ptr, unsigned int size); +void av_free(void *ptr); +char *av_strdup(const char *s); +void av_freep(void *ptr); +void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); +/* for static data only */ +/* call av_free_static to release all staticaly allocated tables */ +void av_free_static(void); +void *av_mallocz_static(unsigned int size); +void *av_realloc_static(void *ptr, unsigned int size); + +/* add by bero : in adx.c */ +int is_adx(const unsigned char *buf,size_t bufsize); + +void img_copy(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height); + +int img_crop(AVPicture *dst, const AVPicture *src, + int pix_fmt, int top_band, int left_band); + +int img_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, + int padtop, int padbottom, int padleft, int padright, int *color); + +/* av_log API */ + +#include + +#define AV_LOG_QUIET -1 +#define AV_LOG_ERROR 0 +#define AV_LOG_INFO 1 +#define AV_LOG_DEBUG 2 + +#ifdef __GNUC__ +extern void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); +#else +extern void av_log(void*, int level, const char *fmt, ...); +#endif + +extern void av_vlog(void*, int level, const char *fmt, va_list); +extern int av_log_get_level(void); +extern void av_log_set_level(int); +extern void av_log_set_callback(void (*)(void*, int, const char*, va_list)); + +/* endian macros */ +#if !defined(BE_16) || !defined(BE_32) || !defined(LE_16) || !defined(LE_32) +#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1]) +#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \ + (((uint8_t*)(x))[1] << 16) | \ + (((uint8_t*)(x))[2] << 8) | \ + ((uint8_t*)(x))[3]) +#define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0]) +#define LE_32(x) ((((uint8_t*)(x))[3] << 24) | \ + (((uint8_t*)(x))[2] << 16) | \ + (((uint8_t*)(x))[1] << 8) | \ + ((uint8_t*)(x))[0]) +#endif + +extern unsigned int av_xiphlacing(unsigned char *s, unsigned int v); + +#ifdef __cplusplus +} +#endif + +#endif /* AVCODEC_H */ diff --git a/mpeg4/src/libavcodec/avs.c b/mpeg4/src/libavcodec/avs.c new file mode 100644 index 00000000..557e9bec --- /dev/null +++ b/mpeg4/src/libavcodec/avs.c @@ -0,0 +1,158 @@ +/* + * AVS video decoder. + * Copyright (c) 2006 Aurelien Jacobs + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "bitstream.h" + + +typedef struct { + AVFrame picture; +} avs_context_t; + +typedef enum { + AVS_VIDEO = 0x01, + AVS_AUDIO = 0x02, + AVS_PALETTE = 0x03, + AVS_GAME_DATA = 0x04, +} avs_block_type_t; + +typedef enum { + AVS_I_FRAME = 0x00, + AVS_P_FRAME_3X3 = 0x01, + AVS_P_FRAME_2X2 = 0x02, + AVS_P_FRAME_2X3 = 0x03, +} avs_video_sub_type_t; + + +static int +avs_decode_frame(AVCodecContext * avctx, + void *data, int *data_size, uint8_t * buf, int buf_size) +{ + avs_context_t *const avs = avctx->priv_data; + AVFrame *picture = data; + AVFrame *const p = (AVFrame *) & avs->picture; + uint8_t *table, *vect, *out; + int i, j, x, y, stride, vect_w = 3, vect_h = 3; + int sub_type; + avs_block_type_t type; + GetBitContext change_map; + + if (avctx->reget_buffer(avctx, p)) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + p->reference = 1; + p->pict_type = FF_P_TYPE; + p->key_frame = 0; + + out = avs->picture.data[0]; + stride = avs->picture.linesize[0]; + + sub_type = buf[0]; + type = buf[1]; + buf += 4; + + if (type == AVS_PALETTE) { + int first, last; + uint32_t *pal = (uint32_t *) avs->picture.data[1]; + + first = LE_16(buf); + last = first + LE_16(buf + 2); + buf += 4; + for (i=first; ipict_type = FF_I_TYPE; + p->key_frame = 1; + case AVS_P_FRAME_3X3: + vect_w = 3; + vect_h = 3; + break; + + case AVS_P_FRAME_2X2: + vect_w = 2; + vect_h = 2; + break; + + case AVS_P_FRAME_2X3: + vect_w = 2; + vect_h = 3; + break; + + default: + return -1; + } + + table = buf + (256 * vect_w * vect_h); + if (sub_type != AVS_I_FRAME) { + int map_size = ((318 / vect_w + 7) / 8) * (198 / vect_h); + init_get_bits(&change_map, table, map_size); + table += map_size; + } + + for (y=0; y<198; y+=vect_h) { + for (x=0; x<318; x+=vect_w) { + if (sub_type == AVS_I_FRAME || get_bits1(&change_map)) { + vect = &buf[*table++ * (vect_w * vect_h)]; + for (j=0; jpicture; + *data_size = sizeof(AVPicture); + + return buf_size; +} + +static int avs_decode_init(AVCodecContext * avctx) +{ + avctx->pix_fmt = PIX_FMT_PAL8; + return 0; +} + +AVCodec avs_decoder = { + "avs", + CODEC_TYPE_VIDEO, + CODEC_ID_AVS, + sizeof(avs_context_t), + avs_decode_init, + NULL, + NULL, + avs_decode_frame, + CODEC_CAP_DR1, +}; diff --git a/mpeg4/src/libavcodec/beosthread.c b/mpeg4/src/libavcodec/beosthread.c new file mode 100644 index 00000000..54595f24 --- /dev/null +++ b/mpeg4/src/libavcodec/beosthread.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2004 François Revol + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +//#define DEBUG + +#include "avcodec.h" +#include "common.h" + +#include + +typedef struct ThreadContext{ + AVCodecContext *avctx; + thread_id thread; + sem_id work_sem; + sem_id done_sem; + int (*func)(AVCodecContext *c, void *arg); + void *arg; + int ret; +}ThreadContext; + +// it's odd Be never patented that :D +struct benaphore { + vint32 atom; + sem_id sem; +}; +static inline int lock_ben(struct benaphore *ben) +{ + if (atomic_add(&ben->atom, 1) > 0) + return acquire_sem(ben->sem); + return B_OK; +} +static inline int unlock_ben(struct benaphore *ben) +{ + if (atomic_add(&ben->atom, -1) > 1) + return release_sem(ben->sem); + return B_OK; +} + +static struct benaphore av_thread_lib_ben; + +static int32 ff_thread_func(void *v){ + ThreadContext *c= v; + + for(;;){ +//printf("thread_func %X enter wait\n", (int)v); fflush(stdout); + acquire_sem(c->work_sem); +//printf("thread_func %X after wait (func=%X)\n", (int)v, (int)c->func); fflush(stdout); + if(c->func) + c->ret= c->func(c->avctx, c->arg); + else + return 0; +//printf("thread_func %X signal complete\n", (int)v); fflush(stdout); + release_sem(c->done_sem); + } + + return B_OK; +} + +/** + * free what has been allocated by avcodec_thread_init(). + * must be called after decoding has finished, especially dont call while avcodec_thread_execute() is running + */ +void avcodec_thread_free(AVCodecContext *s){ + ThreadContext *c= s->thread_opaque; + int i; + int32 ret; + + for(i=0; ithread_count; i++){ + + c[i].func= NULL; + release_sem(c[i].work_sem); + wait_for_thread(c[i].thread, &ret); + if(c[i].work_sem > B_OK) delete_sem(c[i].work_sem); + if(c[i].done_sem > B_OK) delete_sem(c[i].done_sem); + } + + av_freep(&s->thread_opaque); +} + +int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void **arg, int *ret, int count){ + ThreadContext *c= s->thread_opaque; + int i; + + assert(s == c->avctx); + assert(count <= s->thread_count); + + /* note, we can be certain that this is not called with the same AVCodecContext by different threads at the same time */ + + for(i=0; ithread_count= thread_count; + + assert(!s->thread_opaque); + c= av_mallocz(sizeof(ThreadContext)*thread_count); + s->thread_opaque= c; + + for(i=0; iexecute= avcodec_thread_execute; + + return 0; +fail: + avcodec_thread_free(s); + return -1; +} + +/* provide a mean to serialize calls to avcodec_*() for thread safety. */ + +int avcodec_thread_lock_lib(void) +{ + return lock_ben(&av_thread_lib_ben); +} + +int avcodec_thread_unlock_lib(void) +{ + return unlock_ben(&av_thread_lib_ben); +} + +/* our versions of _init and _fini (which are called by those actually from crt.o) */ + +void initialize_after(void) +{ + av_thread_lib_ben.atom = 0; + av_thread_lib_ben.sem = create_sem(0, "libavcodec benaphore"); +} + +void uninitialize_before(void) +{ + delete_sem(av_thread_lib_ben.sem); +} + + + diff --git a/mpeg4/src/libavcodec/bitstream.c b/mpeg4/src/libavcodec/bitstream.c new file mode 100644 index 00000000..49c6ece1 --- /dev/null +++ b/mpeg4/src/libavcodec/bitstream.c @@ -0,0 +1,293 @@ +/* + * Common bit i/o utils + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * alternative bitstream reader & writer by Michael Niedermayer + */ + +/** + * @file bitstream.c + * bitstream api. + */ + +#include "avcodec.h" +#include "bitstream.h" + +void align_put_bits(PutBitContext *s) +{ +#ifdef ALT_BITSTREAM_WRITER + put_bits(s,( - s->index) & 7,0); +#else + put_bits(s,s->bit_left & 7,0); +#endif +} + +void ff_put_string(PutBitContext * pbc, char *s, int put_zero) +{ + while(*s){ + put_bits(pbc, 8, *s); + s++; + } + if(put_zero) + put_bits(pbc, 8, 0); +} + +/* bit input functions */ + +/** + * reads 0-32 bits. + */ +unsigned int get_bits_long(GetBitContext *s, int n){ + if(n<=17) return get_bits(s, n); + else{ + int ret= get_bits(s, 16) << (n-16); + return ret | get_bits(s, n-16); + } +} + +/** + * shows 0-32 bits. + */ +unsigned int show_bits_long(GetBitContext *s, int n){ + if(n<=17) return show_bits(s, n); + else{ + GetBitContext gb= *s; + int ret= get_bits_long(s, n); + *s= gb; + return ret; + } +} + +void align_get_bits(GetBitContext *s) +{ + int n= (-get_bits_count(s)) & 7; + if(n) skip_bits(s, n); +} + +int check_marker(GetBitContext *s, const char *msg) +{ + int bit= get_bits1(s); + if(!bit) + av_log(NULL, AV_LOG_INFO, "Marker bit missing %s\n", msg); + + return bit; +} + +/* VLC decoding */ + +//#define DEBUG_VLC + +#define GET_DATA(v, table, i, wrap, size) \ +{\ + const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ + switch(size) {\ + case 1:\ + v = *(const uint8_t *)ptr;\ + break;\ + case 2:\ + v = *(const uint16_t *)ptr;\ + break;\ + default:\ + v = *(const uint32_t *)ptr;\ + break;\ + }\ +} + + +static int alloc_table(VLC *vlc, int size, int use_static) +{ + int index; + index = vlc->table_size; + vlc->table_size += size; + if (vlc->table_size > vlc->table_allocated) { + vlc->table_allocated += (1 << vlc->bits); + if(use_static) + vlc->table = av_realloc_static(vlc->table, + sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + else + vlc->table = av_realloc(vlc->table, + sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + if (!vlc->table) + return -1; + } + return index; +} + +static int build_table(VLC *vlc, int table_nb_bits, + int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + uint32_t code_prefix, int n_prefix, int flags) +{ + int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2; + uint32_t code; + VLC_TYPE (*table)[2]; + + table_size = 1 << table_nb_bits; + table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_STATIC); +#ifdef DEBUG_VLC + printf("new table index=%d size=%d code_prefix=%x n=%d\n", + table_index, table_size, code_prefix, n_prefix); +#endif + if (table_index < 0) + return -1; + table = &vlc->table[table_index]; + + for(i=0;i=32 ? 0xffffffff : (1 << n_prefix)-1); + else + code_prefix2= code >> n; + if (n > 0 && code_prefix2 == code_prefix) { + if (n <= table_nb_bits) { + /* no need to add another table */ + j = (code << (table_nb_bits - n)) & (table_size - 1); + nb = 1 << (table_nb_bits - n); + for(k=0;k> n_prefix) + (k<> ((flags & INIT_VLC_LE) ? n_prefix : n)) & ((1 << table_nb_bits) - 1); +#ifdef DEBUG_VLC + printf("%4x: n=%d (subtable)\n", + j, n); +#endif + /* compute table size */ + n1 = -table[j][1]; //bits + if (n > n1) + n1 = n; + table[j][1] = -n1; //bits + } + } + } + + /* second pass : fill auxillary tables recursively */ + for(i=0;i table_nb_bits) { + n = table_nb_bits; + table[i][1] = -n; //bits + } + index = build_table(vlc, n, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + (flags & INIT_VLC_LE) ? (code_prefix | (i << n_prefix)) : ((code_prefix << table_nb_bits) | i), + n_prefix + table_nb_bits, flags); + if (index < 0) + return -1; + /* note: realloc has been done, so reload tables */ + table = &vlc->table[table_index]; + table[i][0] = index; //code + } + } + return table_index; +} + + +/* Build VLC decoding tables suitable for use with get_vlc(). + + 'nb_bits' set thee decoding table size (2^nb_bits) entries. The + bigger it is, the faster is the decoding. But it should not be too + big to save memory and L1 cache. '9' is a good compromise. + + 'nb_codes' : number of vlcs codes + + 'bits' : table which gives the size (in bits) of each vlc code. + + 'codes' : table which gives the bit pattern of of each vlc code. + + 'xxx_wrap' : give the number of bytes between each entry of the + 'bits' or 'codes' tables. + + 'xxx_size' : gives the number of bytes of each entry of the 'bits' + or 'codes' tables. + + 'wrap' and 'size' allows to use any memory configuration and types + (byte/word/long) to store the 'bits' and 'codes' tables. + + 'use_static' should be set to 1 for tables, which should be freed + with av_free_static(), 0 if free_vlc() will be used. +*/ +int init_vlc(VLC *vlc, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + int use_static) +{ + vlc->bits = nb_bits; + if(!use_static) { + vlc->table = NULL; + vlc->table_allocated = 0; + vlc->table_size = 0; + } else { + /* Static tables are initially always NULL, return + if vlc->table != NULL to avoid double allocation */ + if(vlc->table) + return 0; + } + +#ifdef DEBUG_VLC + printf("build table nb_codes=%d\n", nb_codes); +#endif + + if (build_table(vlc, nb_bits, nb_codes, + bits, bits_wrap, bits_size, + codes, codes_wrap, codes_size, + 0, 0, use_static) < 0) { + av_free(vlc->table); + return -1; + } + return 0; +} + + +void free_vlc(VLC *vlc) +{ + av_free(vlc->table); +} + diff --git a/mpeg4/src/libavcodec/bitstream.h b/mpeg4/src/libavcodec/bitstream.h new file mode 100644 index 00000000..b4250499 --- /dev/null +++ b/mpeg4/src/libavcodec/bitstream.h @@ -0,0 +1,873 @@ +/** + * @file bitstream.h + * bitstream api header. + */ + +#ifndef BITSTREAM_H +#define BITSTREAM_H + +//#define ALT_BITSTREAM_WRITER +//#define ALIGNED_BITSTREAM_WRITER + +#define ALT_BITSTREAM_READER +//#define LIBMPEG2_BITSTREAM_READER +//#define A32_BITSTREAM_READER +#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO + +extern const uint8_t ff_reverse[256]; + +#if defined(ARCH_X86) || defined(ARCH_X86_64) +// avoid +32 for shift optimization (gcc should do that ...) +static inline int32_t NEG_SSR32( int32_t a, int8_t s){ + asm ("sarl %1, %0\n\t" + : "+r" (a) + : "ic" ((uint8_t)(-s)) + ); + return a; +} +static inline uint32_t NEG_USR32(uint32_t a, int8_t s){ + asm ("shrl %1, %0\n\t" + : "+r" (a) + : "ic" ((uint8_t)(-s)) + ); + return a; +} +#else +# define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s))) +# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) +#endif + +/* bit output */ + +/* buf and buf_end must be present and used by every alternative writer. */ +typedef struct PutBitContext { +#ifdef ALT_BITSTREAM_WRITER + uint8_t *buf, *buf_end; + int index; +#else + uint32_t bit_buf; + int bit_left; + uint8_t *buf, *buf_ptr, *buf_end; +#endif +} PutBitContext; + +static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size) +{ + if(buffer_size < 0) { + buffer_size = 0; + buffer = NULL; + } + + s->buf = buffer; + s->buf_end = s->buf + buffer_size; +#ifdef ALT_BITSTREAM_WRITER + s->index=0; + ((uint32_t*)(s->buf))[0]=0; +// memset(buffer, 0, buffer_size); +#else + s->buf_ptr = s->buf; + s->bit_left=32; + s->bit_buf=0; +#endif +} + +/* return the number of bits output */ +static inline int put_bits_count(PutBitContext *s) +{ +#ifdef ALT_BITSTREAM_WRITER + return s->index; +#else + return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; +#endif +} + +/* pad the end of the output stream with zeros */ +static inline void flush_put_bits(PutBitContext *s) +{ +#ifdef ALT_BITSTREAM_WRITER + align_put_bits(s); +#else + s->bit_buf<<= s->bit_left; + while (s->bit_left < 32) { + /* XXX: should test end of buffer */ + *s->buf_ptr++=s->bit_buf >> 24; + s->bit_buf<<=8; + s->bit_left+=8; + } + s->bit_left=32; + s->bit_buf=0; +#endif +} + +void align_put_bits(PutBitContext *s); +void ff_put_string(PutBitContext * pbc, char *s, int put_zero); + +/* bit input */ +/* buffer, buffer_end and size_in_bits must be present and used by every reader */ +typedef struct GetBitContext { + const uint8_t *buffer, *buffer_end; +#ifdef ALT_BITSTREAM_READER + int index; +#elif defined LIBMPEG2_BITSTREAM_READER + uint8_t *buffer_ptr; + uint32_t cache; + int bit_count; +#elif defined A32_BITSTREAM_READER + uint32_t *buffer_ptr; + uint32_t cache0; + uint32_t cache1; + int bit_count; +#endif + int size_in_bits; +} GetBitContext; + +#define VLC_TYPE int16_t + +typedef struct VLC { + int bits; + VLC_TYPE (*table)[2]; ///< code, bits + int table_size, table_allocated; +} VLC; + +typedef struct RL_VLC_ELEM { + int16_t level; + int8_t len; + uint8_t run; +} RL_VLC_ELEM; + +#if defined(ARCH_SPARC) || defined(ARCH_ARMV4L) +#define UNALIGNED_STORES_ARE_BAD +#endif + +/* used to avoid missaligned exceptions on some archs (alpha, ...) */ +#if defined(ARCH_X86) || defined(ARCH_X86_64) +# define unaligned32(a) (*(const uint32_t*)(a)) +#else +# ifdef __GNUC__ +static inline uint32_t unaligned32(const void *v) { + struct Unaligned { + uint32_t i; + } __attribute__((packed)); + + return ((const struct Unaligned *) v)->i; +} +# elif defined(__DECC) +static inline uint32_t unaligned32(const void *v) { + return *(const __unaligned uint32_t *) v; +} +# else +static inline uint32_t unaligned32(const void *v) { + return *(const uint32_t *) v; +} +# endif +#endif //!ARCH_X86 + +#ifndef ALT_BITSTREAM_WRITER +static inline void put_bits(PutBitContext *s, int n, unsigned int value) +{ + unsigned int bit_buf; + int bit_left; + +#ifdef STATS + st_out_bit_counts[st_current_index] += n; +#endif + // printf("put_bits=%d %x\n", n, value); + assert(n == 32 || value < (1U << n)); + + bit_buf = s->bit_buf; + bit_left = s->bit_left; + + // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf); + /* XXX: optimize */ + if (n < bit_left) { + bit_buf = (bit_buf<> (n - bit_left); +#ifdef UNALIGNED_STORES_ARE_BAD + if (3 & (intptr_t) s->buf_ptr) { + s->buf_ptr[0] = bit_buf >> 24; + s->buf_ptr[1] = bit_buf >> 16; + s->buf_ptr[2] = bit_buf >> 8; + s->buf_ptr[3] = bit_buf ; + } else +#endif + *(uint32_t *)s->buf_ptr = be2me_32(bit_buf); + //printf("bitbuf = %08x\n", bit_buf); + s->buf_ptr+=4; + bit_left+=32 - n; + bit_buf = value; + } + + s->bit_buf = bit_buf; + s->bit_left = bit_left; +} +#endif + + +#ifdef ALT_BITSTREAM_WRITER +static inline void put_bits(PutBitContext *s, int n, unsigned int value) +{ +# ifdef ALIGNED_BITSTREAM_WRITER +# if defined(ARCH_X86) || defined(ARCH_X86_64) + asm volatile( + "movl %0, %%ecx \n\t" + "xorl %%eax, %%eax \n\t" + "shrdl %%cl, %1, %%eax \n\t" + "shrl %%cl, %1 \n\t" + "movl %0, %%ecx \n\t" + "shrl $3, %%ecx \n\t" + "andl $0xFFFFFFFC, %%ecx \n\t" + "bswapl %1 \n\t" + "orl %1, (%2, %%ecx) \n\t" + "bswapl %%eax \n\t" + "addl %3, %0 \n\t" + "movl %%eax, 4(%2, %%ecx) \n\t" + : "=&r" (s->index), "=&r" (value) + : "r" (s->buf), "r" (n), "0" (s->index), "1" (value<<(-n)) + : "%eax", "%ecx" + ); +# else + int index= s->index; + uint32_t *ptr= ((uint32_t *)s->buf)+(index>>5); + + value<<= 32-n; + + ptr[0] |= be2me_32(value>>(index&31)); + ptr[1] = be2me_32(value<<(32-(index&31))); +//if(n>24) printf("%d %d\n", n, value); + index+= n; + s->index= index; +# endif +# else //ALIGNED_BITSTREAM_WRITER +# if defined(ARCH_X86) || defined(ARCH_X86_64) + asm volatile( + "movl $7, %%ecx \n\t" + "andl %0, %%ecx \n\t" + "addl %3, %%ecx \n\t" + "negl %%ecx \n\t" + "shll %%cl, %1 \n\t" + "bswapl %1 \n\t" + "movl %0, %%ecx \n\t" + "shrl $3, %%ecx \n\t" + "orl %1, (%%ecx, %2) \n\t" + "addl %3, %0 \n\t" + "movl $0, 4(%%ecx, %2) \n\t" + : "=&r" (s->index), "=&r" (value) + : "r" (s->buf), "r" (n), "0" (s->index), "1" (value) + : "%ecx" + ); +# else + int index= s->index; + uint32_t *ptr= (uint32_t*)(((uint8_t *)s->buf)+(index>>3)); + + ptr[0] |= be2me_32(value<<(32-n-(index&7) )); + ptr[1] = 0; +//if(n>24) printf("%d %d\n", n, value); + index+= n; + s->index= index; +# endif +# endif //!ALIGNED_BITSTREAM_WRITER +} +#endif + + +static inline uint8_t* pbBufPtr(PutBitContext *s) +{ +#ifdef ALT_BITSTREAM_WRITER + return s->buf + (s->index>>3); +#else + return s->buf_ptr; +#endif +} + +/** + * + * PutBitContext must be flushed & aligned to a byte boundary before calling this. + */ +static inline void skip_put_bytes(PutBitContext *s, int n){ + assert((put_bits_count(s)&7)==0); +#ifdef ALT_BITSTREAM_WRITER + FIXME may need some cleaning of the buffer + s->index += n<<3; +#else + assert(s->bit_left==32); + s->buf_ptr += n; +#endif +} + +/** + * skips the given number of bits. + * must only be used if the actual values in the bitstream dont matter + */ +static inline void skip_put_bits(PutBitContext *s, int n){ +#ifdef ALT_BITSTREAM_WRITER + s->index += n; +#else + s->bit_left -= n; + s->buf_ptr-= s->bit_left>>5; + s->bit_left &= 31; +#endif +} + +/** + * Changes the end of the buffer. + */ +static inline void set_put_bits_buffer_size(PutBitContext *s, int size){ + s->buf_end= s->buf + size; +} + +/* Bitstream reader API docs: +name + abritary name which is used as prefix for the internal variables + +gb + getbitcontext + +OPEN_READER(name, gb) + loads gb into local variables + +CLOSE_READER(name, gb) + stores local vars in gb + +UPDATE_CACHE(name, gb) + refills the internal cache from the bitstream + after this call at least MIN_CACHE_BITS will be available, + +GET_CACHE(name, gb) + will output the contents of the internal cache, next bit is MSB of 32 or 64 bit (FIXME 64bit) + +SHOW_UBITS(name, gb, num) + will return the next num bits + +SHOW_SBITS(name, gb, num) + will return the next num bits and do sign extension + +SKIP_BITS(name, gb, num) + will skip over the next num bits + note, this is equivalent to SKIP_CACHE; SKIP_COUNTER + +SKIP_CACHE(name, gb, num) + will remove the next num bits from the cache (note SKIP_COUNTER MUST be called before UPDATE_CACHE / CLOSE_READER) + +SKIP_COUNTER(name, gb, num) + will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS) + +LAST_SKIP_CACHE(name, gb, num) + will remove the next num bits from the cache if it is needed for UPDATE_CACHE otherwise it will do nothing + +LAST_SKIP_BITS(name, gb, num) + is equivalent to SKIP_LAST_CACHE; SKIP_COUNTER + +for examples see get_bits, show_bits, skip_bits, get_vlc +*/ + +static inline int unaligned32_be(const void *v) +{ +#ifdef CONFIG_ALIGN + const uint8_t *p=v; + return (((p[0]<<8) | p[1])<<16) | (p[2]<<8) | (p[3]); +#else + return be2me_32( unaligned32(v)); //original +#endif +} + +static inline int unaligned32_le(const void *v) +{ +#ifdef CONFIG_ALIGN + const uint8_t *p=v; + return (((p[3]<<8) | p[2])<<16) | (p[1]<<8) | (p[0]); +#else + return le2me_32( unaligned32(v)); //original +#endif +} + +#ifdef ALT_BITSTREAM_READER +# define MIN_CACHE_BITS 25 + +# define OPEN_READER(name, gb)\ + int name##_index= (gb)->index;\ + int name##_cache= 0;\ + +# define CLOSE_READER(name, gb)\ + (gb)->index= name##_index;\ + +# ifdef ALT_BITSTREAM_READER_LE +# define UPDATE_CACHE(name, gb)\ + name##_cache= unaligned32_le( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) >> (name##_index&0x07);\ + +# define SKIP_CACHE(name, gb, num)\ + name##_cache >>= (num); +# else +# define UPDATE_CACHE(name, gb)\ + name##_cache= unaligned32_be( ((const uint8_t *)(gb)->buffer)+(name##_index>>3) ) << (name##_index&0x07);\ + +# define SKIP_CACHE(name, gb, num)\ + name##_cache <<= (num); +# endif + +// FIXME name? +# define SKIP_COUNTER(name, gb, num)\ + name##_index += (num);\ + +# define SKIP_BITS(name, gb, num)\ + {\ + SKIP_CACHE(name, gb, num)\ + SKIP_COUNTER(name, gb, num)\ + }\ + +# define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) +# define LAST_SKIP_CACHE(name, gb, num) ; + +# ifdef ALT_BITSTREAM_READER_LE +# define SHOW_UBITS(name, gb, num)\ + ((name##_cache) & (NEG_USR32(0xffffffff,num))) +# else +# define SHOW_UBITS(name, gb, num)\ + NEG_USR32(name##_cache, num) +# endif + +# define SHOW_SBITS(name, gb, num)\ + NEG_SSR32(name##_cache, num) + +# define GET_CACHE(name, gb)\ + ((uint32_t)name##_cache) + +static inline int get_bits_count(GetBitContext *s){ + return s->index; +} +#elif defined LIBMPEG2_BITSTREAM_READER +//libmpeg2 like reader + +# define MIN_CACHE_BITS 17 + +# define OPEN_READER(name, gb)\ + int name##_bit_count=(gb)->bit_count;\ + int name##_cache= (gb)->cache;\ + uint8_t * name##_buffer_ptr=(gb)->buffer_ptr;\ + +# define CLOSE_READER(name, gb)\ + (gb)->bit_count= name##_bit_count;\ + (gb)->cache= name##_cache;\ + (gb)->buffer_ptr= name##_buffer_ptr;\ + +#ifdef LIBMPEG2_BITSTREAM_READER_HACK + +# define UPDATE_CACHE(name, gb)\ + if(name##_bit_count >= 0){\ + name##_cache+= (int)be2me_16(*(uint16_t*)name##_buffer_ptr) << name##_bit_count;\ + name##_buffer_ptr += 2;\ + name##_bit_count-= 16;\ + }\ + +#else + +# define UPDATE_CACHE(name, gb)\ + if(name##_bit_count >= 0){\ + name##_cache+= ((name##_buffer_ptr[0]<<8) + name##_buffer_ptr[1]) << name##_bit_count;\ + name##_buffer_ptr+=2;\ + name##_bit_count-= 16;\ + }\ + +#endif + +# define SKIP_CACHE(name, gb, num)\ + name##_cache <<= (num);\ + +# define SKIP_COUNTER(name, gb, num)\ + name##_bit_count += (num);\ + +# define SKIP_BITS(name, gb, num)\ + {\ + SKIP_CACHE(name, gb, num)\ + SKIP_COUNTER(name, gb, num)\ + }\ + +# define LAST_SKIP_BITS(name, gb, num) SKIP_BITS(name, gb, num) +# define LAST_SKIP_CACHE(name, gb, num) SKIP_CACHE(name, gb, num) + +# define SHOW_UBITS(name, gb, num)\ + NEG_USR32(name##_cache, num) + +# define SHOW_SBITS(name, gb, num)\ + NEG_SSR32(name##_cache, num) + +# define GET_CACHE(name, gb)\ + ((uint32_t)name##_cache) + +static inline int get_bits_count(GetBitContext *s){ + return (s->buffer_ptr - s->buffer)*8 - 16 + s->bit_count; +} + +#elif defined A32_BITSTREAM_READER + +# define MIN_CACHE_BITS 32 + +# define OPEN_READER(name, gb)\ + int name##_bit_count=(gb)->bit_count;\ + uint32_t name##_cache0= (gb)->cache0;\ + uint32_t name##_cache1= (gb)->cache1;\ + uint32_t * name##_buffer_ptr=(gb)->buffer_ptr;\ + +# define CLOSE_READER(name, gb)\ + (gb)->bit_count= name##_bit_count;\ + (gb)->cache0= name##_cache0;\ + (gb)->cache1= name##_cache1;\ + (gb)->buffer_ptr= name##_buffer_ptr;\ + +# define UPDATE_CACHE(name, gb)\ + if(name##_bit_count > 0){\ + const uint32_t next= be2me_32( *name##_buffer_ptr );\ + name##_cache0 |= NEG_USR32(next,name##_bit_count);\ + name##_cache1 |= next<buffer_ptr - s->buffer)*8 - 32 + s->bit_count; +} + +#endif + +/** + * read mpeg1 dc style vlc (sign bit + mantisse with no MSB). + * if MSB not set it is negative + * @param n length in bits + * @author BERO + */ +static inline int get_xbits(GetBitContext *s, int n){ + register int sign; + register int32_t cache; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + cache = GET_CACHE(re,s); + sign=(~cache)>>31; + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; +} + +static inline int get_sbits(GetBitContext *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_SBITS(re, s, n); + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return tmp; +} + +/** + * reads 0-17 bits. + * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't + */ +static inline unsigned int get_bits(GetBitContext *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_UBITS(re, s, n); + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) + return tmp; +} + +unsigned int get_bits_long(GetBitContext *s, int n); + +/** + * shows 0-17 bits. + * Note, the alt bitstream reader can read up to 25 bits, but the libmpeg2 reader can't + */ +static inline unsigned int show_bits(GetBitContext *s, int n){ + register int tmp; + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + tmp= SHOW_UBITS(re, s, n); +// CLOSE_READER(re, s) + return tmp; +} + +unsigned int show_bits_long(GetBitContext *s, int n); + +static inline void skip_bits(GetBitContext *s, int n){ + //Note gcc seems to optimize this to s->index+=n for the ALT_READER :)) + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + LAST_SKIP_BITS(re, s, n) + CLOSE_READER(re, s) +} + +static inline unsigned int get_bits1(GetBitContext *s){ +#ifdef ALT_BITSTREAM_READER + int index= s->index; + uint8_t result= s->buffer[ index>>3 ]; +#ifdef ALT_BITSTREAM_READER_LE + result>>= (index&0x07); + result&= 1; +#else + result<<= (index&0x07); + result>>= 8 - 1; +#endif + index++; + s->index= index; + + return result; +#else + return get_bits(s, 1); +#endif +} + +static inline unsigned int show_bits1(GetBitContext *s){ + return show_bits(s, 1); +} + +static inline void skip_bits1(GetBitContext *s){ + skip_bits(s, 1); +} + +/** + * init GetBitContext. + * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger then the actual read bits + * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end + * @param bit_size the size of the buffer in bits + */ +static inline void init_get_bits(GetBitContext *s, + const uint8_t *buffer, int bit_size) +{ + int buffer_size= (bit_size+7)>>3; + if(buffer_size < 0 || bit_size < 0) { + buffer_size = bit_size = 0; + buffer = NULL; + } + + s->buffer= buffer; + s->size_in_bits= bit_size; + s->buffer_end= buffer + buffer_size; +#ifdef ALT_BITSTREAM_READER + s->index=0; +#elif defined LIBMPEG2_BITSTREAM_READER +#ifdef LIBMPEG2_BITSTREAM_READER_HACK + if ((int)buffer&1) { + /* word alignment */ + s->cache = (*buffer++)<<24; + s->buffer_ptr = buffer; + s->bit_count = 16-8; + } else +#endif + { + s->buffer_ptr = buffer; + s->bit_count = 16; + s->cache = 0; + } +#elif defined A32_BITSTREAM_READER + s->buffer_ptr = (uint32_t*)buffer; + s->bit_count = 32; + s->cache0 = 0; + s->cache1 = 0; +#endif + { + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + UPDATE_CACHE(re, s) + CLOSE_READER(re, s) + } +#ifdef A32_BITSTREAM_READER + s->cache1 = 0; +#endif +} + +int check_marker(GetBitContext *s, const char *msg); +void align_get_bits(GetBitContext *s); +int init_vlc(VLC *vlc, int nb_bits, int nb_codes, + const void *bits, int bits_wrap, int bits_size, + const void *codes, int codes_wrap, int codes_size, + int flags); +#define INIT_VLC_USE_STATIC 1 +#define INIT_VLC_LE 2 +void free_vlc(VLC *vlc); + +/** + * + * if the vlc code is invalid and max_depth=1 than no bits will be removed + * if the vlc code is invalid and max_depth>1 than the number of bits removed + * is undefined + */ +#define GET_VLC(code, name, gb, table, bits, max_depth)\ +{\ + int n, index, nb_bits;\ +\ + index= SHOW_UBITS(name, gb, bits);\ + code = table[index][0];\ + n = table[index][1];\ +\ + if(max_depth > 1 && n < 0){\ + LAST_SKIP_BITS(name, gb, bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + if(max_depth > 2 && n < 0){\ + LAST_SKIP_BITS(name, gb, nb_bits)\ + UPDATE_CACHE(name, gb)\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + code;\ + code = table[index][0];\ + n = table[index][1];\ + }\ + }\ + SKIP_BITS(name, gb, n)\ +} + +#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update)\ +{\ + int n, index, nb_bits;\ +\ + index= SHOW_UBITS(name, gb, bits);\ + level = table[index].level;\ + n = table[index].len;\ +\ + if(max_depth > 1 && n < 0){\ + SKIP_BITS(name, gb, bits)\ + if(need_update){\ + UPDATE_CACHE(name, gb)\ + }\ +\ + nb_bits = -n;\ +\ + index= SHOW_UBITS(name, gb, nb_bits) + level;\ + level = table[index].level;\ + n = table[index].len;\ + }\ + run= table[index].run;\ + SKIP_BITS(name, gb, n)\ +} + + +/** + * parses a vlc code, faster then get_vlc() + * @param bits is the number of bits which will be read at once, must be + * identical to nb_bits in init_vlc() + * @param max_depth is the number of times bits bits must be readed to completly + * read the longest vlc code + * = (max_vlc_length + bits - 1) / bits + */ +static always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], + int bits, int max_depth) +{ + int code; + + OPEN_READER(re, s) + UPDATE_CACHE(re, s) + + GET_VLC(code, re, s, table, bits, max_depth) + + CLOSE_READER(re, s) + return code; +} + +//#define TRACE + +#ifdef TRACE +#include "avcodec.h" +static inline void print_bin(int bits, int n){ + int i; + + for(i=n-1; i>=0; i--){ + av_log(NULL, AV_LOG_DEBUG, "%d", (bits>>i)&1); + } + for(i=n; i<24; i++) + av_log(NULL, AV_LOG_DEBUG, " "); +} + +static inline int get_bits_trace(GetBitContext *s, int n, char *file, const char *func, int line){ + int r= get_bits(s, n); + + print_bin(r, n); + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d bit @%5d in %s %s:%d\n", r, n, r, get_bits_count(s)-n, file, func, line); + return r; +} +static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2], int bits, int max_depth, char *file, const char *func, int line){ + int show= show_bits(s, 24); + int pos= get_bits_count(s); + int r= get_vlc2(s, table, bits, max_depth); + int len= get_bits_count(s) - pos; + int bits2= show>>(24-len); + + print_bin(bits2, len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d vlc @%5d in %s %s:%d\n", bits2, len, r, pos, file, func, line); + return r; +} +static inline int get_xbits_trace(GetBitContext *s, int n, char *file, const char *func, int line){ + int show= show_bits(s, n); + int r= get_xbits(s, n); + + print_bin(show, n); + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d xbt @%5d in %s %s:%d\n", show, n, r, get_bits_count(s)-n, file, func, line); + return r; +} + +#define get_bits(s, n) get_bits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_bits1(s) get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_vlc(s, vlc) get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__) + +#define tprintf(...) av_log(NULL, AV_LOG_DEBUG, __VA_ARGS__) + +#else //TRACE +#define tprintf(...) {} +#endif + +static inline int decode012(GetBitContext *gb){ + int n; + n = get_bits1(gb); + if (n == 0) + return 0; + else + return get_bits1(gb) + 1; +} + +#endif /* BITSTREAM_H */ diff --git a/mpeg4/src/libavcodec/bmp.c b/mpeg4/src/libavcodec/bmp.c new file mode 100644 index 00000000..dc903063 --- /dev/null +++ b/mpeg4/src/libavcodec/bmp.c @@ -0,0 +1,251 @@ +/* + * BMP image format + * Copyright (c) 2005 Mans Rullgard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "bitstream.h" +#include "bswap.h" + +typedef struct BMPContext { + AVFrame picture; +} BMPContext; + +#define BMP_RGB 0 +#define BMP_RLE8 1 +#define BMP_RLE4 2 +#define BMP_BITFIELDS 3 + +#define read16(bits) bswap_16(get_bits(bits, 16)) +#define read32(bits) bswap_32(get_bits_long(bits, 32)) + +static int bmp_decode_init(AVCodecContext *avctx){ + BMPContext *s = avctx->priv_data; + + avcodec_get_frame_defaults((AVFrame*)&s->picture); + avctx->coded_frame = (AVFrame*)&s->picture; + + return 0; +} + +static int bmp_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + BMPContext *s = avctx->priv_data; + AVFrame *picture = data; + AVFrame *p = &s->picture; + GetBitContext bits; + unsigned int fsize, hsize; + int width, height; + unsigned int depth; + unsigned int comp; + unsigned int ihsize; + int i, j, n, linesize; + uint32_t rgb[3]; + uint8_t *ptr; + int dsize; + + if(buf_size < 14){ + av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); + return -1; + } + + init_get_bits(&bits, buf, buf_size); + + if(get_bits(&bits, 16) != 0x424d){ /* 'BM' */ + av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); + return -1; + } + + fsize = read32(&bits); + if(buf_size < fsize){ + av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", + buf_size, fsize); + return -1; + } + + skip_bits(&bits, 16); /* reserved1 */ + skip_bits(&bits, 16); /* reserved2 */ + + hsize = read32(&bits); /* header size */ + if(fsize <= hsize){ + av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", + fsize, hsize); + return -1; + } + + ihsize = read32(&bits); /* more header size */ + if(ihsize + 14 > hsize){ + av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize); + return -1; + } + + width = read32(&bits); + height = read32(&bits); + + if(read16(&bits) != 1){ /* planes */ + av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n"); + return -1; + } + + depth = read16(&bits); + + if(ihsize > 16) + comp = read32(&bits); + else + comp = BMP_RGB; + + if(comp != BMP_RGB && comp != BMP_BITFIELDS){ + av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp); + return -1; + } + + if(comp == BMP_BITFIELDS){ + skip_bits(&bits, 20 * 8); + rgb[0] = read32(&bits); + rgb[1] = read32(&bits); + rgb[2] = read32(&bits); + } + + avctx->codec_id = CODEC_ID_BMP; + avctx->width = width; + avctx->height = height > 0? height: -height; + + avctx->pix_fmt = PIX_FMT_NONE; + + switch(depth){ + case 32: + if(comp == BMP_BITFIELDS){ + rgb[0] = (rgb[0] >> 15) & 3; + rgb[1] = (rgb[1] >> 15) & 3; + rgb[2] = (rgb[2] >> 15) & 3; + + if(rgb[0] + rgb[1] + rgb[2] != 3 || + rgb[0] == rgb[1] || rgb[0] == rgb[2] || rgb[1] == rgb[2]){ + break; + } + } else { + rgb[0] = 2; + rgb[1] = 1; + rgb[2] = 0; + } + + avctx->pix_fmt = PIX_FMT_BGR24; + break; + case 24: + avctx->pix_fmt = PIX_FMT_BGR24; + break; + case 16: + if(comp == BMP_RGB) + avctx->pix_fmt = PIX_FMT_RGB555; + break; + default: + av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth); + return -1; + } + + if(avctx->pix_fmt == PIX_FMT_NONE){ + av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); + return -1; + } + + p->reference = 0; + if(avctx->get_buffer(avctx, p) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + p->pict_type = FF_I_TYPE; + p->key_frame = 1; + + buf += hsize; + dsize = buf_size - hsize; + + n = avctx->width * (depth / 8); + + if(n * avctx->height > dsize){ + av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", + dsize, n * avctx->height); + return -1; + } + + if(height > 0){ + ptr = p->data[0] + (avctx->height - 1) * p->linesize[0]; + linesize = -p->linesize[0]; + } else { + ptr = p->data[0]; + linesize = p->linesize[0]; + } + + switch(depth){ + case 24: + for(i = 0; i < avctx->height; i++){ + memcpy(ptr, buf, n); + buf += n; + ptr += linesize; + } + break; + case 16: + for(i = 0; i < avctx->height; i++){ + uint16_t *src = (uint16_t *) buf; + uint16_t *dst = (uint16_t *) ptr; + + for(j = 0; j < avctx->width; j++) + *dst++ = le2me_16(*src++); + + buf += n; + ptr += linesize; + } + break; + case 32: + for(i = 0; i < avctx->height; i++){ + uint8_t *src = buf; + uint8_t *dst = ptr; + + for(j = 0; j < avctx->width; j++){ + dst[0] = src[rgb[2]]; + dst[1] = src[rgb[1]]; + dst[2] = src[rgb[0]]; + dst += 3; + src += 4; + } + + buf += n; + ptr += linesize; + } + break; + default: + av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n"); + return -1; + } + + *picture = s->picture; + *data_size = sizeof(AVPicture); + + return buf_size; +} + +AVCodec bmp_decoder = { + "bmp", + CODEC_TYPE_VIDEO, + CODEC_ID_BMP, + sizeof(BMPContext), + bmp_decode_init, + NULL, + NULL, + bmp_decode_frame +}; diff --git a/mpeg4/src/libavcodec/cabac.c b/mpeg4/src/libavcodec/cabac.c new file mode 100644 index 00000000..88790a96 --- /dev/null +++ b/mpeg4/src/libavcodec/cabac.c @@ -0,0 +1,234 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder + * Copyright (c) 2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file cabac.c + * Context Adaptive Binary Arithmetic Coder. + */ + +#include + +#include "common.h" +#include "bitstream.h" +#include "cabac.h" + +const uint8_t ff_h264_lps_range[64][4]= { +{128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205}, +{116,142,169,195}, {111,135,160,185}, {105,128,152,175}, {100,122,144,166}, +{ 95,116,137,158}, { 90,110,130,150}, { 85,104,123,142}, { 81, 99,117,135}, +{ 77, 94,111,128}, { 73, 89,105,122}, { 69, 85,100,116}, { 66, 80, 95,110}, +{ 62, 76, 90,104}, { 59, 72, 86, 99}, { 56, 69, 81, 94}, { 53, 65, 77, 89}, +{ 51, 62, 73, 85}, { 48, 59, 69, 80}, { 46, 56, 66, 76}, { 43, 53, 63, 72}, +{ 41, 50, 59, 69}, { 39, 48, 56, 65}, { 37, 45, 54, 62}, { 35, 43, 51, 59}, +{ 33, 41, 48, 56}, { 32, 39, 46, 53}, { 30, 37, 43, 50}, { 29, 35, 41, 48}, +{ 27, 33, 39, 45}, { 26, 31, 37, 43}, { 24, 30, 35, 41}, { 23, 28, 33, 39}, +{ 22, 27, 32, 37}, { 21, 26, 30, 35}, { 20, 24, 29, 33}, { 19, 23, 27, 31}, +{ 18, 22, 26, 30}, { 17, 21, 25, 28}, { 16, 20, 23, 27}, { 15, 19, 22, 25}, +{ 14, 18, 21, 24}, { 14, 17, 20, 23}, { 13, 16, 19, 22}, { 12, 15, 18, 21}, +{ 12, 14, 17, 20}, { 11, 14, 16, 19}, { 11, 13, 15, 18}, { 10, 12, 15, 17}, +{ 10, 12, 14, 16}, { 9, 11, 13, 15}, { 9, 11, 12, 14}, { 8, 10, 12, 14}, +{ 8, 9, 11, 13}, { 7, 9, 11, 12}, { 7, 9, 10, 12}, { 7, 8, 10, 11}, +{ 6, 8, 9, 11}, { 6, 7, 9, 10}, { 6, 7, 8, 9}, { 2, 2, 2, 2}, +}; + +const uint8_t ff_h264_mps_state[64]= { + 1, 2, 3, 4, 5, 6, 7, 8, + 9,10,11,12,13,14,15,16, + 17,18,19,20,21,22,23,24, + 25,26,27,28,29,30,31,32, + 33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48, + 49,50,51,52,53,54,55,56, + 57,58,59,60,61,62,62,63, +}; + +const uint8_t ff_h264_lps_state[64]= { + 0, 0, 1, 2, 2, 4, 4, 5, + 6, 7, 8, 9, 9,11,11,12, + 13,13,15,15,16,16,18,18, + 19,19,21,21,22,22,23,24, + 24,25,26,26,27,27,28,29, + 29,30,30,30,31,32,32,33, + 33,33,34,34,35,35,35,36, + 36,36,37,37,37,38,38,63, +}; + +const uint8_t ff_h264_norm_shift[256]= { + 8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +}; + +/** + * + * @param buf_size size of buf in bits + */ +void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){ + init_put_bits(&c->pb, buf, buf_size); + + c->low= 0; + c->range= 0x1FE; + c->outstanding_count= 0; +#ifdef STRICT_LIMITS + c->sym_count =0; +#endif + + c->pb.bit_left++; //avoids firstBitFlag +} + +/** + * + * @param buf_size size of buf in bits + */ +void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){ + c->bytestream_start= + c->bytestream= buf; + c->bytestream_end= buf + buf_size; + +#if CABAC_BITS == 16 + c->low = (*c->bytestream++)<<18; + c->low+= (*c->bytestream++)<<10; +#else + c->low = (*c->bytestream++)<<10; +#endif + c->low+= ((*c->bytestream++)<<2) + 2; + c->range= 0x1FE<<(CABAC_BITS + 1); +} + +void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4], + uint8_t const *mps_state, uint8_t const *lps_state, int state_count){ + int i, j; + + for(i=0; ilps_range[2*i+0][j+4]= + c->lps_range[2*i+1][j+4]= lps_range[i][j]; + } + + c->mps_state[2*i+0]= 2*mps_state[i]; + c->mps_state[2*i+1]= 2*mps_state[i]+1; + + if( i ){ + c->lps_state[2*i+0]= 2*lps_state[i]; + c->lps_state[2*i+1]= 2*lps_state[i]+1; + }else{ + c->lps_state[2*i+0]= 1; + c->lps_state[2*i+1]= 0; + } + } +} + +#if 0 //selftest +#define SIZE 10240 + +#include "avcodec.h" + +int main(){ + CABACContext c; + uint8_t b[9*SIZE]; + uint8_t r[9*SIZE]; + int i; + uint8_t state[10]= {0}; + + ff_init_cabac_encoder(&c, b, SIZE); + ff_init_cabac_states(&c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); + + for(i=0; i + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file cabac.h + * Context Adaptive Binary Arithmetic Coder. + */ + + +#undef NDEBUG +#include + +#define CABAC_BITS 8 +#define CABAC_MASK ((1<pb, 1, b); + for(;c->outstanding_count; c->outstanding_count--){ + put_bits(&c->pb, 1, 1-b); + } +} + +static inline void renorm_cabac_encoder(CABACContext *c){ + while(c->range < 0x100){ + //FIXME optimize + if(c->low<0x100){ + put_cabac_bit(c, 0); + }else if(c->low<0x200){ + c->outstanding_count++; + c->low -= 0x100; + }else{ + put_cabac_bit(c, 1); + c->low -= 0x200; + } + + c->range+= c->range; + c->low += c->low; + } +} + +static inline void put_cabac(CABACContext *c, uint8_t * const state, int bit){ + int RangeLPS= c->lps_range[*state][c->range>>6]; + + if(bit == ((*state)&1)){ + c->range -= RangeLPS; + *state= c->mps_state[*state]; + }else{ + c->low += c->range - RangeLPS; + c->range = RangeLPS; + *state= c->lps_state[*state]; + } + + renorm_cabac_encoder(c); + +#ifdef STRICT_LIMITS + c->symCount++; +#endif +} + +static inline void put_cabac_static(CABACContext *c, int RangeLPS, int bit){ + assert(c->range > RangeLPS); + + if(!bit){ + c->range -= RangeLPS; + }else{ + c->low += c->range - RangeLPS; + c->range = RangeLPS; + } + + renorm_cabac_encoder(c); + +#ifdef STRICT_LIMITS + c->symCount++; +#endif +} + +/** + * @param bit 0 -> write zero bit, !=0 write one bit + */ +static inline void put_cabac_bypass(CABACContext *c, int bit){ + c->low += c->low; + + if(bit){ + c->low += c->range; + } +//FIXME optimize + if(c->low<0x200){ + put_cabac_bit(c, 0); + }else if(c->low<0x400){ + c->outstanding_count++; + c->low -= 0x200; + }else{ + put_cabac_bit(c, 1); + c->low -= 0x400; + } + +#ifdef STRICT_LIMITS + c->symCount++; +#endif +} + +/** + * + * @return the number of bytes written + */ +static inline int put_cabac_terminate(CABACContext *c, int bit){ + c->range -= 2; + + if(!bit){ + renorm_cabac_encoder(c); + }else{ + c->low += c->range; + c->range= 2; + + renorm_cabac_encoder(c); + + assert(c->low <= 0x1FF); + put_cabac_bit(c, c->low>>9); + put_bits(&c->pb, 2, ((c->low>>7)&3)|1); + + flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong + } + +#ifdef STRICT_LIMITS + c->symCount++; +#endif + + return (put_bits_count(&c->pb)+7)>>3; +} + +/** + * put (truncated) unary binarization. + */ +static inline void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){ + int i; + + assert(v <= max); + +#if 1 + for(i=0; i= m){ //FIXME optimize + put_cabac_bypass(c, 1); + v-= m; + m+= m; + } + put_cabac_bypass(c, 0); + while(m>>=1){ + put_cabac_bypass(c, v&m); + } + } + + if(is_signed) + put_cabac_bypass(c, sign); + } +} + +static void refill(CABACContext *c){ + if(c->bytestream <= c->bytestream_end) +#if CABAC_BITS == 16 + c->low+= ((c->bytestream[0]<<9) + (c->bytestream[1])<<1); +#else + c->low+= c->bytestream[0]<<1; +#endif + c->low -= CABAC_MASK; + c->bytestream+= CABAC_BITS/8; +} + +#if 0 /* all use commented */ +static void refill2(CABACContext *c){ + int i, x; + + x= c->low ^ (c->low-1); + i= 8 - ff_h264_norm_shift[x>>(CABAC_BITS+1)]; + + x= -CABAC_MASK; + + if(c->bytestream < c->bytestream_end) +#if CABAC_BITS == 16 + x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); +#else + x+= c->bytestream[0]<<1; +#endif + + c->low += x<bytestream+= CABAC_BITS/8; +} +#endif + +static inline void renorm_cabac_decoder(CABACContext *c){ + while(c->range < (0x200 << CABAC_BITS)){ + c->range+= c->range; + c->low+= c->low; + if(!(c->low & CABAC_MASK)) + refill(c); + } +} + +static inline void renorm_cabac_decoder_once(CABACContext *c){ + int mask= (c->range - (0x200 << CABAC_BITS))>>31; + c->range+= c->range&mask; + c->low += c->low &mask; + if(!(c->low & CABAC_MASK)) + refill(c); +} + +static inline int get_cabac(CABACContext *c, uint8_t * const state){ + int RangeLPS= c->lps_range[*state][c->range>>(CABAC_BITS+7)]<<(CABAC_BITS+1); + int bit, lps_mask attribute_unused; + + c->range -= RangeLPS; +#if 1 + if(c->low < c->range){ + bit= (*state)&1; + *state= c->mps_state[*state]; + renorm_cabac_decoder_once(c); + }else{ +// int shift= ff_h264_norm_shift[RangeLPS>>17]; + bit= ((*state)&1)^1; + c->low -= c->range; + *state= c->lps_state[*state]; + c->range = RangeLPS; + renorm_cabac_decoder(c); +/* c->range = RangeLPS<low <<= shift; + if(!(c->low & 0xFFFF)){ + refill2(c); + }*/ + } +#else + lps_mask= (c->range - c->low)>>31; + + c->low -= c->range & lps_mask; + c->range += (RangeLPS - c->range) & lps_mask; + + bit= ((*state)^lps_mask)&1; + *state= c->mps_state[(*state) - (128&lps_mask)]; + + lps_mask= ff_h264_norm_shift[c->range>>(CABAC_BITS+2)]; + c->range<<= lps_mask; + c->low <<= lps_mask; + if(!(c->low & CABAC_MASK)) + refill2(c); +#endif + + return bit; +} + +static inline int get_cabac_bypass(CABACContext *c){ + c->low += c->low; + + if(!(c->low & CABAC_MASK)) + refill(c); + + if(c->low < c->range){ + return 0; + }else{ + c->low -= c->range; + return 1; + } +} + +/** + * + * @return the number of bytes read or 0 if no end + */ +static inline int get_cabac_terminate(CABACContext *c){ + c->range -= 4<low < c->range){ + renorm_cabac_decoder_once(c); + return 0; + }else{ + return c->bytestream - c->bytestream_start; + } +} + +/** + * get (truncated) unnary binarization. + */ +static inline int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){ + int i; + + for(i=0; i>=1){ + v+= v + get_cabac_bypass(c); + } + i += v; + + if(is_signed && get_cabac_bypass(c)){ + return -i; + }else + return i; +} diff --git a/mpeg4/src/libavcodec/cinepak.c b/mpeg4/src/libavcodec/cinepak.c new file mode 100644 index 00000000..79768123 --- /dev/null +++ b/mpeg4/src/libavcodec/cinepak.c @@ -0,0 +1,451 @@ +/* + * Cinepak Video Decoder + * Copyright (C) 2003 the ffmpeg project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file cinepak.c + * Cinepak video decoder + * by Ewald Snel + * For more information on the Cinepak algorithm, visit: + * http://www.csse.monash.edu.au/~timf/ + */ + +#include +#include +#include +#include + +#include "common.h" +#include "avcodec.h" +#include "dsputil.h" + + +typedef struct { + uint8_t y0, y1, y2, y3; + uint8_t u, v; +} cvid_codebook_t; + +#define MAX_STRIPS 32 + +typedef struct { + uint16_t id; + uint16_t x1, y1; + uint16_t x2, y2; + cvid_codebook_t v4_codebook[256]; + cvid_codebook_t v1_codebook[256]; +} cvid_strip_t; + +typedef struct CinepakContext { + + AVCodecContext *avctx; + DSPContext dsp; + AVFrame frame; + + unsigned char *data; + int size; + + int width, height; + + int palette_video; + cvid_strip_t strips[MAX_STRIPS]; + +} CinepakContext; + +static void cinepak_decode_codebook (cvid_codebook_t *codebook, + int chunk_id, int size, uint8_t *data) +{ + uint8_t *eod = (data + size); + uint32_t flag, mask; + int i, n; + + /* check if this chunk contains 4- or 6-element vectors */ + n = (chunk_id & 0x0400) ? 4 : 6; + flag = 0; + mask = 0; + + for (i=0; i < 256; i++) { + if ((chunk_id & 0x0100) && !(mask >>= 1)) { + if ((data + 4) > eod) + break; + + flag = BE_32 (data); + data += 4; + mask = 0x80000000; + } + + if (!(chunk_id & 0x0100) || (flag & mask)) { + if ((data + n) > eod) + break; + + if (n == 6) { + codebook[i].y0 = *data++; + codebook[i].y1 = *data++; + codebook[i].y2 = *data++; + codebook[i].y3 = *data++; + codebook[i].u = 128 + *data++; + codebook[i].v = 128 + *data++; + } else { + /* this codebook type indicates either greyscale or + * palettized video; if palettized, U & V components will + * not be used so it is safe to set them to 128 for the + * benefit of greyscale rendering in YUV420P */ + codebook[i].y0 = *data++; + codebook[i].y1 = *data++; + codebook[i].y2 = *data++; + codebook[i].y3 = *data++; + codebook[i].u = 128; + codebook[i].v = 128; + } + } + } +} + +static int cinepak_decode_vectors (CinepakContext *s, cvid_strip_t *strip, + int chunk_id, int size, uint8_t *data) +{ + uint8_t *eod = (data + size); + uint32_t flag, mask; + cvid_codebook_t *codebook; + unsigned int x, y; + uint32_t iy[4]; + uint32_t iu[2]; + uint32_t iv[2]; + + flag = 0; + mask = 0; + + for (y=strip->y1; y < strip->y2; y+=4) { + + iy[0] = strip->x1 + (y * s->frame.linesize[0]); + iy[1] = iy[0] + s->frame.linesize[0]; + iy[2] = iy[1] + s->frame.linesize[0]; + iy[3] = iy[2] + s->frame.linesize[0]; + iu[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[1]); + iu[1] = iu[0] + s->frame.linesize[1]; + iv[0] = (strip->x1/2) + ((y/2) * s->frame.linesize[2]); + iv[1] = iv[0] + s->frame.linesize[2]; + + for (x=strip->x1; x < strip->x2; x+=4) { + if ((chunk_id & 0x0100) && !(mask >>= 1)) { + if ((data + 4) > eod) + return -1; + + flag = BE_32 (data); + data += 4; + mask = 0x80000000; + } + + if (!(chunk_id & 0x0100) || (flag & mask)) { + if (!(chunk_id & 0x0200) && !(mask >>= 1)) { + if ((data + 4) > eod) + return -1; + + flag = BE_32 (data); + data += 4; + mask = 0x80000000; + } + + if ((chunk_id & 0x0200) || (~flag & mask)) { + if (data >= eod) + return -1; + + codebook = &strip->v1_codebook[*data++]; + s->frame.data[0][iy[0] + 0] = codebook->y0; + s->frame.data[0][iy[0] + 1] = codebook->y0; + s->frame.data[0][iy[1] + 0] = codebook->y0; + s->frame.data[0][iy[1] + 1] = codebook->y0; + if (!s->palette_video) { + s->frame.data[1][iu[0]] = codebook->u; + s->frame.data[2][iv[0]] = codebook->v; + } + + s->frame.data[0][iy[0] + 2] = codebook->y1; + s->frame.data[0][iy[0] + 3] = codebook->y1; + s->frame.data[0][iy[1] + 2] = codebook->y1; + s->frame.data[0][iy[1] + 3] = codebook->y1; + if (!s->palette_video) { + s->frame.data[1][iu[0] + 1] = codebook->u; + s->frame.data[2][iv[0] + 1] = codebook->v; + } + + s->frame.data[0][iy[2] + 0] = codebook->y2; + s->frame.data[0][iy[2] + 1] = codebook->y2; + s->frame.data[0][iy[3] + 0] = codebook->y2; + s->frame.data[0][iy[3] + 1] = codebook->y2; + if (!s->palette_video) { + s->frame.data[1][iu[1]] = codebook->u; + s->frame.data[2][iv[1]] = codebook->v; + } + + s->frame.data[0][iy[2] + 2] = codebook->y3; + s->frame.data[0][iy[2] + 3] = codebook->y3; + s->frame.data[0][iy[3] + 2] = codebook->y3; + s->frame.data[0][iy[3] + 3] = codebook->y3; + if (!s->palette_video) { + s->frame.data[1][iu[1] + 1] = codebook->u; + s->frame.data[2][iv[1] + 1] = codebook->v; + } + + } else if (flag & mask) { + if ((data + 4) > eod) + return -1; + + codebook = &strip->v4_codebook[*data++]; + s->frame.data[0][iy[0] + 0] = codebook->y0; + s->frame.data[0][iy[0] + 1] = codebook->y1; + s->frame.data[0][iy[1] + 0] = codebook->y2; + s->frame.data[0][iy[1] + 1] = codebook->y3; + if (!s->palette_video) { + s->frame.data[1][iu[0]] = codebook->u; + s->frame.data[2][iv[0]] = codebook->v; + } + + codebook = &strip->v4_codebook[*data++]; + s->frame.data[0][iy[0] + 2] = codebook->y0; + s->frame.data[0][iy[0] + 3] = codebook->y1; + s->frame.data[0][iy[1] + 2] = codebook->y2; + s->frame.data[0][iy[1] + 3] = codebook->y3; + if (!s->palette_video) { + s->frame.data[1][iu[0] + 1] = codebook->u; + s->frame.data[2][iv[0] + 1] = codebook->v; + } + + codebook = &strip->v4_codebook[*data++]; + s->frame.data[0][iy[2] + 0] = codebook->y0; + s->frame.data[0][iy[2] + 1] = codebook->y1; + s->frame.data[0][iy[3] + 0] = codebook->y2; + s->frame.data[0][iy[3] + 1] = codebook->y3; + if (!s->palette_video) { + s->frame.data[1][iu[1]] = codebook->u; + s->frame.data[2][iv[1]] = codebook->v; + } + + codebook = &strip->v4_codebook[*data++]; + s->frame.data[0][iy[2] + 2] = codebook->y0; + s->frame.data[0][iy[2] + 3] = codebook->y1; + s->frame.data[0][iy[3] + 2] = codebook->y2; + s->frame.data[0][iy[3] + 3] = codebook->y3; + if (!s->palette_video) { + s->frame.data[1][iu[1] + 1] = codebook->u; + s->frame.data[2][iv[1] + 1] = codebook->v; + } + + } + } + + iy[0] += 4; iy[1] += 4; + iy[2] += 4; iy[3] += 4; + iu[0] += 2; iu[1] += 2; + iv[0] += 2; iv[1] += 2; + } + } + + return 0; +} + +static int cinepak_decode_strip (CinepakContext *s, + cvid_strip_t *strip, uint8_t *data, int size) +{ + uint8_t *eod = (data + size); + int chunk_id, chunk_size; + + /* coordinate sanity checks */ + if (strip->x1 >= s->width || strip->x2 > s->width || + strip->y1 >= s->height || strip->y2 > s->height || + strip->x1 >= strip->x2 || strip->y1 >= strip->y2) + return -1; + + while ((data + 4) <= eod) { + chunk_id = BE_16 (&data[0]); + chunk_size = BE_16 (&data[2]) - 4; + if(chunk_size < 0) + return -1; + + data += 4; + chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size; + + switch (chunk_id) { + + case 0x2000: + case 0x2100: + case 0x2400: + case 0x2500: + cinepak_decode_codebook (strip->v4_codebook, chunk_id, + chunk_size, data); + break; + + case 0x2200: + case 0x2300: + case 0x2600: + case 0x2700: + cinepak_decode_codebook (strip->v1_codebook, chunk_id, + chunk_size, data); + break; + + case 0x3000: + case 0x3100: + case 0x3200: + return cinepak_decode_vectors (s, strip, chunk_id, + chunk_size, data); + } + + data += chunk_size; + } + + return -1; +} + +static int cinepak_decode (CinepakContext *s) +{ + uint8_t *eod = (s->data + s->size); + int i, result, strip_size, frame_flags, num_strips; + int y0 = 0; + int encoded_buf_size; + /* if true, Cinepak data is from a Sega FILM/CPK file */ + int sega_film_data = 0; + + if (s->size < 10) + return -1; + + frame_flags = s->data[0]; + num_strips = BE_16 (&s->data[8]); + encoded_buf_size = ((s->data[1] << 16) | BE_16 (&s->data[2])); + if (encoded_buf_size != s->size) + sega_film_data = 1; + if (sega_film_data) + s->data += 12; + else + s->data += 10; + + if (num_strips > MAX_STRIPS) + num_strips = MAX_STRIPS; + + for (i=0; i < num_strips; i++) { + if ((s->data + 12) > eod) + return -1; + + s->strips[i].id = BE_16 (s->data); + s->strips[i].y1 = y0; + s->strips[i].x1 = 0; + s->strips[i].y2 = y0 + BE_16 (&s->data[8]); + s->strips[i].x2 = s->avctx->width; + + strip_size = BE_16 (&s->data[2]) - 12; + s->data += 12; + strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size; + + if ((i > 0) && !(frame_flags & 0x01)) { + memcpy (s->strips[i].v4_codebook, s->strips[i-1].v4_codebook, + sizeof(s->strips[i].v4_codebook)); + memcpy (s->strips[i].v1_codebook, s->strips[i-1].v1_codebook, + sizeof(s->strips[i].v1_codebook)); + } + + result = cinepak_decode_strip (s, &s->strips[i], s->data, strip_size); + + if (result != 0) + return result; + + s->data += strip_size; + y0 = s->strips[i].y2; + } + return 0; +} + +static int cinepak_decode_init(AVCodecContext *avctx) +{ + CinepakContext *s = (CinepakContext *)avctx->priv_data; + + s->avctx = avctx; + s->width = (avctx->width + 3) & ~3; + s->height = (avctx->height + 3) & ~3; + + // check for paletted data + if ((avctx->palctrl == NULL) || (avctx->bits_per_sample == 40)) { + s->palette_video = 0; + avctx->pix_fmt = PIX_FMT_YUV420P; + } else { + s->palette_video = 1; + avctx->pix_fmt = PIX_FMT_PAL8; + } + + avctx->has_b_frames = 0; + dsputil_init(&s->dsp, avctx); + + s->frame.data[0] = NULL; + + return 0; +} + +static int cinepak_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + CinepakContext *s = (CinepakContext *)avctx->priv_data; + + s->data = buf; + s->size = buf_size; + + s->frame.reference = 1; + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | + FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &s->frame)) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + + cinepak_decode(s); + + if (s->palette_video) { + memcpy (s->frame.data[1], avctx->palctrl->palette, AVPALETTE_SIZE); + if (avctx->palctrl->palette_changed) { + s->frame.palette_has_changed = 1; + avctx->palctrl->palette_changed = 0; + } else + s->frame.palette_has_changed = 0; + } + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = s->frame; + + /* report that the buffer was completely consumed */ + return buf_size; +} + +static int cinepak_decode_end(AVCodecContext *avctx) +{ + CinepakContext *s = (CinepakContext *)avctx->priv_data; + + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + return 0; +} + +AVCodec cinepak_decoder = { + "cinepak", + CODEC_TYPE_VIDEO, + CODEC_ID_CINEPAK, + sizeof(CinepakContext), + cinepak_decode_init, + NULL, + cinepak_decode_end, + cinepak_decode_frame, + CODEC_CAP_DR1, +}; diff --git a/mpeg4/src/libavcodec/cljr.c b/mpeg4/src/libavcodec/cljr.c new file mode 100644 index 00000000..feb0d8bb --- /dev/null +++ b/mpeg4/src/libavcodec/cljr.c @@ -0,0 +1,156 @@ +/* + * Cirrus Logic AccuPak (CLJR) codec + * Copyright (c) 2003 Alex Beregszaszi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file cljr.c + * Cirrus Logic AccuPak codec. + */ + +#include "avcodec.h" +#include "mpegvideo.h" + +typedef struct CLJRContext{ + AVCodecContext *avctx; + AVFrame picture; + int delta[16]; + int offset[4]; + GetBitContext gb; +} CLJRContext; + +static int decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + CLJRContext * const a = avctx->priv_data; + AVFrame *picture = data; + AVFrame * const p= (AVFrame*)&a->picture; + int x, y; + + if(p->data[0]) + avctx->release_buffer(avctx, p); + + p->reference= 0; + if(avctx->get_buffer(avctx, p) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + p->pict_type= I_TYPE; + p->key_frame= 1; + + init_get_bits(&a->gb, buf, buf_size); + + for(y=0; yheight; y++){ + uint8_t *luma= &a->picture.data[0][ y*a->picture.linesize[0] ]; + uint8_t *cb= &a->picture.data[1][ y*a->picture.linesize[1] ]; + uint8_t *cr= &a->picture.data[2][ y*a->picture.linesize[2] ]; + for(x=0; xwidth; x+=4){ + luma[3] = get_bits(&a->gb, 5) << 3; + luma[2] = get_bits(&a->gb, 5) << 3; + luma[1] = get_bits(&a->gb, 5) << 3; + luma[0] = get_bits(&a->gb, 5) << 3; + luma+= 4; + *(cb++) = get_bits(&a->gb, 6) << 2; + *(cr++) = get_bits(&a->gb, 6) << 2; + } + } + + *picture= *(AVFrame*)&a->picture; + *data_size = sizeof(AVPicture); + + emms_c(); + + return buf_size; +} + +#if 0 +static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + CLJRContext * const a = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p= (AVFrame*)&a->picture; + int size; + int mb_x, mb_y; + + *p = *pict; + p->pict_type= I_TYPE; + p->key_frame= 1; + + emms_c(); + + align_put_bits(&a->pb); + while(get_bit_count(&a->pb)&31) + put_bits(&a->pb, 8, 0); + + size= get_bit_count(&a->pb)/32; + + return size*4; +} +#endif + +static void common_init(AVCodecContext *avctx){ + CLJRContext * const a = avctx->priv_data; + + avctx->coded_frame= (AVFrame*)&a->picture; + a->avctx= avctx; +} + +static int decode_init(AVCodecContext *avctx){ + + common_init(avctx); + + avctx->pix_fmt= PIX_FMT_YUV411P; + + return 0; +} + +#if 0 +static int encode_init(AVCodecContext *avctx){ + + common_init(avctx); + + return 0; +} +#endif + +AVCodec cljr_decoder = { + "cljr", + CODEC_TYPE_VIDEO, + CODEC_ID_CLJR, + sizeof(CLJRContext), + decode_init, + NULL, + NULL, + decode_frame, + CODEC_CAP_DR1, +}; +#if 0 +#ifdef CONFIG_ENCODERS + +AVCodec cljr_encoder = { + "cljr", + CODEC_TYPE_VIDEO, + CODEC_ID_cljr, + sizeof(CLJRContext), + encode_init, + encode_frame, + //encode_end, +}; + +#endif //CONFIG_ENCODERS +#endif diff --git a/mpeg4/src/libavcodec/cook.c b/mpeg4/src/libavcodec/cook.c new file mode 100644 index 00000000..07368ca4 --- /dev/null +++ b/mpeg4/src/libavcodec/cook.c @@ -0,0 +1,1307 @@ +/* + * COOK compatible decoder + * Copyright (c) 2003 Sascha Sommer + * Copyright (c) 2005 Benjamin Larsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file cook.c + * Cook compatible decoder. + * This decoder handles RealNetworks, RealAudio G2 data. + * Cook is identified by the codec name cook in RM files. + * + * To use this decoder, a calling application must supply the extradata + * bytes provided from the RM container; 8+ bytes for mono streams and + * 16+ for stereo streams (maybe more). + * + * Codec technicalities (all this assume a buffer length of 1024): + * Cook works with several different techniques to achieve its compression. + * In the timedomain the buffer is divided into 8 pieces and quantized. If + * two neighboring pieces have different quantization index a smooth + * quantization curve is used to get a smooth overlap between the different + * pieces. + * To get to the transformdomain Cook uses a modulated lapped transform. + * The transform domain has 50 subbands with 20 elements each. This + * means only a maximum of 50*20=1000 coefficients are used out of the 1024 + * available. + */ + +#include +#include +#include + +#define ALT_BITSTREAM_READER +#include "avcodec.h" +#include "bitstream.h" +#include "dsputil.h" + +#include "cookdata.h" + +/* the different Cook versions */ +#define MONO_COOK1 0x1000001 +#define MONO_COOK2 0x1000002 +#define JOINT_STEREO 0x1000003 +#define MC_COOK 0x2000000 //multichannel Cook, not supported + +#define SUBBAND_SIZE 20 +//#define COOKDEBUG + +typedef struct { + int size; + int qidx_table1[8]; + int qidx_table2[8]; +} COOKgain; + +typedef struct __attribute__((__packed__)){ + /* codec data start */ + uint32_t cookversion; //in network order, bigendian + uint16_t samples_per_frame; //amount of samples per frame per channel, bigendian + uint16_t subbands; //amount of bands used in the frequency domain, bigendian + /* Mono extradata ends here. */ + uint32_t unused; + uint16_t js_subband_start; //bigendian + uint16_t js_vlc_bits; //bigendian + /* Stereo extradata ends here. */ +} COOKextradata; + + +typedef struct { + GetBitContext gb; + /* stream data */ + int nb_channels; + int joint_stereo; + int bit_rate; + int sample_rate; + int samples_per_channel; + int samples_per_frame; + int subbands; + int log2_numvector_size; + int numvector_size; //1 << log2_numvector_size; + int js_subband_start; + int total_subbands; + int num_vectors; + int bits_per_subpacket; + /* states */ + int random_state; + + /* transform data */ + FFTContext fft_ctx; + FFTSample mlt_tmp[1024] __attribute__((aligned(16))); /* temporary storage for imlt */ + float* mlt_window; + float* mlt_precos; + float* mlt_presin; + float* mlt_postcos; + int fft_size; + int fft_order; + int mlt_size; //modulated lapped transform size + + /* gain buffers */ + COOKgain* gain_now_ptr; + COOKgain* gain_previous_ptr; + COOKgain gain_current; + COOKgain gain_now; + COOKgain gain_previous; + COOKgain gain_channel1[2]; + COOKgain gain_channel2[2]; + + /* VLC data */ + int js_vlc_bits; + VLC envelope_quant_index[13]; + VLC sqvh[7]; //scalar quantization + VLC ccpl; //channel coupling + + /* generatable tables and related variables */ + int gain_size_factor; + float gain_table[23]; + float pow2tab[127]; + float rootpow2tab[127]; + + /* data buffers */ + + uint8_t* decoded_bytes_buffer; + float mono_mdct_output[2048] __attribute__((aligned(16))); + float* previous_buffer_ptr[2]; + float mono_previous_buffer1[1024]; + float mono_previous_buffer2[1024]; + float* decode_buf_ptr[4]; + float* decode_buf_ptr2[2]; + float decode_buffer_1[1024]; + float decode_buffer_2[1024]; + float decode_buffer_3[1024]; + float decode_buffer_4[1024]; +} COOKContext; + +/* debug functions */ + +#ifdef COOKDEBUG +static void dump_float_table(float* table, int size, int delimiter) { + int i=0; + av_log(NULL,AV_LOG_ERROR,"\n[%d]: ",i); + for (i=0 ; ipow2tab[63] = 1.0; + for (i=1 ; i<64 ; i++){ + q->pow2tab[63+i]=(float)((uint64_t)1<pow2tab[63-i]=1.0/(float)((uint64_t)1<rootpow2tab[63] = 1.0; + for (i=1 ; i<64 ; i++){ + q->rootpow2tab[63+i]=sqrt((float)((uint64_t)1<rootpow2tab[63-i]=sqrt(1.0/(float)((uint64_t)1<gain_size_factor = q->samples_per_channel/8; + for (i=0 ; i<23 ; i++) { + q->gain_table[i] = pow((double)q->pow2tab[i+52] , + (1.0/(double)q->gain_size_factor)); + } +} + + +static int init_cook_vlc_tables(COOKContext *q) { + int i, result; + + result = 0; + for (i=0 ; i<13 ; i++) { + result &= init_vlc (&q->envelope_quant_index[i], 9, 24, + envelope_quant_index_huffbits[i], 1, 1, + envelope_quant_index_huffcodes[i], 2, 2, 0); + } + av_log(NULL,AV_LOG_DEBUG,"sqvh VLC init\n"); + for (i=0 ; i<7 ; i++) { + result &= init_vlc (&q->sqvh[i], vhvlcsize_tab[i], vhsize_tab[i], + cvh_huffbits[i], 1, 1, + cvh_huffcodes[i], 2, 2, 0); + } + + if (q->nb_channels==2 && q->joint_stereo==1){ + result &= init_vlc (&q->ccpl, 6, (1<js_vlc_bits)-1, + ccpl_huffbits[q->js_vlc_bits-2], 1, 1, + ccpl_huffcodes[q->js_vlc_bits-2], 2, 2, 0); + av_log(NULL,AV_LOG_DEBUG,"Joint-stereo VLC used.\n"); + } + + av_log(NULL,AV_LOG_DEBUG,"VLC tables initialized.\n"); + return result; +} + +static int init_cook_mlt(COOKContext *q) { + int j; + float alpha; + + /* Allocate the buffers, could be replaced with a static [512] + array if needed. */ + q->mlt_size = q->samples_per_channel; + q->mlt_window = av_malloc(sizeof(float)*q->mlt_size); + q->mlt_precos = av_malloc(sizeof(float)*q->mlt_size/2); + q->mlt_presin = av_malloc(sizeof(float)*q->mlt_size/2); + q->mlt_postcos = av_malloc(sizeof(float)*q->mlt_size/2); + + /* Initialize the MLT window: simple sine window. */ + alpha = M_PI / (2.0 * (float)q->mlt_size); + for(j=0 ; jmlt_size ; j++) { + q->mlt_window[j] = sin((j + 512.0/(float)q->mlt_size) * alpha); + } + + /* pre/post twiddle factors */ + for (j=0 ; jmlt_size/2 ; j++){ + q->mlt_precos[j] = cos( ((j+0.25)*M_PI)/q->mlt_size); + q->mlt_presin[j] = sin( ((j+0.25)*M_PI)/q->mlt_size); + q->mlt_postcos[j] = (float)sqrt(2.0/(float)q->mlt_size)*cos( ((float)j*M_PI) /q->mlt_size); //sqrt(2/MLT_size) = scalefactor + } + + /* Initialize the FFT. */ + ff_fft_init(&q->fft_ctx, av_log2(q->mlt_size)-1, 0); + av_log(NULL,AV_LOG_DEBUG,"FFT initialized, order = %d.\n", + av_log2(q->samples_per_channel)-1); + + return (int)(q->mlt_window && q->mlt_precos && q->mlt_presin && q->mlt_postcos); +} + +/*************** init functions end ***********/ + +/** + * Cook indata decoding, every 32 bits are XORed with 0x37c511f2. + * Why? No idea, some checksum/error detection method maybe. + * Nice way to waste CPU cycles. + * + * @param in pointer to 32bit array of indata + * @param bits amount of bits + * @param out pointer to 32bit array of outdata + */ + +static inline void decode_bytes(uint8_t* inbuffer, uint8_t* out, int bytes){ + int i; + uint32_t* buf = (uint32_t*) inbuffer; + uint32_t* obuf = (uint32_t*) out; + /* FIXME: 64 bit platforms would be able to do 64 bits at a time. + * I'm too lazy though, should be something like + * for(i=0 ; ipriv_data; + av_log(NULL,AV_LOG_DEBUG, "Deallocating memory.\n"); + + /* Free allocated memory buffers. */ + av_free(q->mlt_window); + av_free(q->mlt_precos); + av_free(q->mlt_presin); + av_free(q->mlt_postcos); + av_free(q->decoded_bytes_buffer); + + /* Free the transform. */ + ff_fft_end(&q->fft_ctx); + + /* Free the VLC tables. */ + for (i=0 ; i<13 ; i++) { + free_vlc(&q->envelope_quant_index[i]); + } + for (i=0 ; i<7 ; i++) { + free_vlc(&q->sqvh[i]); + } + if(q->nb_channels==2 && q->joint_stereo==1 ){ + free_vlc(&q->ccpl); + } + + av_log(NULL,AV_LOG_DEBUG,"Memory deallocated.\n"); + + return 0; +} + +/** + * Fill the COOKgain structure for the timedomain quantization. + * + * @param q pointer to the COOKContext + * @param gaininfo pointer to the COOKgain + */ + +static void decode_gain_info(GetBitContext *gb, COOKgain* gaininfo) { + int i; + + while (get_bits1(gb)) {} + + gaininfo->size = get_bits_count(gb) - 1; //amount of elements*2 to update + + if (get_bits_count(gb) - 1 <= 0) return; + + for (i=0 ; isize ; i++){ + gaininfo->qidx_table1[i] = get_bits(gb,3); + if (get_bits1(gb)) { + gaininfo->qidx_table2[i] = get_bits(gb,4) - 7; //convert to signed + } else { + gaininfo->qidx_table2[i] = -1; + } + } +} + +/** + * Create the quant index table needed for the envelope. + * + * @param q pointer to the COOKContext + * @param quant_index_table pointer to the array + */ + +static void decode_envelope(COOKContext *q, int* quant_index_table) { + int i,j, vlc_index; + int bitbias; + + bitbias = get_bits_count(&q->gb); + quant_index_table[0]= get_bits(&q->gb,6) - 6; //This is used later in categorize + + for (i=1 ; i < q->total_subbands ; i++){ + vlc_index=i; + if (i >= q->js_subband_start * 2) { + vlc_index-=q->js_subband_start; + } else { + vlc_index/=2; + if(vlc_index < 1) vlc_index = 1; + } + if (vlc_index>13) vlc_index = 13; //the VLC tables >13 are identical to No. 13 + + j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index-1].table, + q->envelope_quant_index[vlc_index-1].bits,2); + quant_index_table[i] = quant_index_table[i-1] + j - 12; //differential encoding + } +} + +/** + * Create the quant value table. + * + * @param q pointer to the COOKContext + * @param quant_value_table pointer to the array + */ + +static void inline dequant_envelope(COOKContext *q, int* quant_index_table, + float* quant_value_table){ + + int i; + for(i=0 ; i < q->total_subbands ; i++){ + quant_value_table[i] = q->rootpow2tab[quant_index_table[i]+63]; + } +} + +/** + * Calculate the category and category_index vector. + * + * @param q pointer to the COOKContext + * @param quant_index_table pointer to the array + * @param category pointer to the category array + * @param category_index pointer to the category_index array + */ + +static void categorize(COOKContext *q, int* quant_index_table, + int* category, int* category_index){ + int exp_idx, bias, tmpbias, bits_left, num_bits, index, v, i, j; + int exp_index2[102]; + int exp_index1[102]; + + int tmp_categorize_array1[128]; + int tmp_categorize_array1_idx=0; + int tmp_categorize_array2[128]; + int tmp_categorize_array2_idx=0; + int category_index_size=0; + + bits_left = q->bits_per_subpacket - get_bits_count(&q->gb); + + if(bits_left > q->samples_per_channel) { + bits_left = q->samples_per_channel + + ((bits_left - q->samples_per_channel)*5)/8; + //av_log(NULL, AV_LOG_ERROR, "bits_left = %d\n",bits_left); + } + + memset(&exp_index1,0,102*sizeof(int)); + memset(&exp_index2,0,102*sizeof(int)); + memset(&tmp_categorize_array1,0,128*sizeof(int)); + memset(&tmp_categorize_array2,0,128*sizeof(int)); + + bias=-32; + + /* Estimate bias. */ + for (i=32 ; i>0 ; i=i/2){ + num_bits = 0; + index = 0; + for (j=q->total_subbands ; j>0 ; j--){ + exp_idx = (i - quant_index_table[index] + bias) / 2; + if (exp_idx<0){ + exp_idx=0; + } else if(exp_idx >7) { + exp_idx=7; + } + index++; + num_bits+=expbits_tab[exp_idx]; + } + if(num_bits >= bits_left - 32){ + bias+=i; + } + } + + /* Calculate total number of bits. */ + num_bits=0; + for (i=0 ; itotal_subbands ; i++) { + exp_idx = (bias - quant_index_table[i]) / 2; + if (exp_idx<0) { + exp_idx=0; + } else if(exp_idx >7) { + exp_idx=7; + } + num_bits += expbits_tab[exp_idx]; + exp_index1[i] = exp_idx; + exp_index2[i] = exp_idx; + } + tmpbias = bias = num_bits; + + for (j = 1 ; j < q->numvector_size ; j++) { + if (tmpbias + bias > 2*bits_left) { /* ---> */ + int max = -999999; + index=-1; + for (i=0 ; itotal_subbands ; i++){ + if (exp_index1[i] < 7) { + v = (-2*exp_index1[i]) - quant_index_table[i] - 32; + if ( v >= max) { + max = v; + index = i; + } + } + } + if(index==-1)break; + tmp_categorize_array1[tmp_categorize_array1_idx++] = index; + tmpbias -= expbits_tab[exp_index1[index]] - + expbits_tab[exp_index1[index]+1]; + ++exp_index1[index]; + } else { /* <--- */ + int min = 999999; + index=-1; + for (i=0 ; itotal_subbands ; i++){ + if(exp_index2[i] > 0){ + v = (-2*exp_index2[i])-quant_index_table[i]; + if ( v < min) { + min = v; + index = i; + } + } + } + if(index == -1)break; + tmp_categorize_array2[tmp_categorize_array2_idx++] = index; + tmpbias -= expbits_tab[exp_index2[index]] - + expbits_tab[exp_index2[index]-1]; + --exp_index2[index]; + } + } + + for(i=0 ; itotal_subbands ; i++) + category[i] = exp_index2[i]; + + /* Concatenate the two arrays. */ + for(i=tmp_categorize_array2_idx-1 ; i >= 0; i--) + category_index[category_index_size++] = tmp_categorize_array2[i]; + + for(i=0;inumvector_size;i++) + category_index[i]=0; + +} + + +/** + * Expand the category vector. + * + * @param q pointer to the COOKContext + * @param category pointer to the category array + * @param category_index pointer to the category_index array + */ + +static void inline expand_category(COOKContext *q, int* category, + int* category_index){ + int i; + for(i=0 ; inum_vectors ; i++){ + ++category[category_index[i]]; + } +} + +/** + * The real requantization of the mltcoefs + * + * @param q pointer to the COOKContext + * @param index index + * @param band current subband + * @param quant_value_table pointer to the array + * @param subband_coef_index array of indexes to quant_centroid_tab + * @param subband_coef_noise use random noise instead of predetermined value + * @param mlt_buffer pointer to the mlt buffer + */ + + +static void scalar_dequant(COOKContext *q, int index, int band, + float* quant_value_table, int* subband_coef_index, + int* subband_coef_noise, float* mlt_buffer){ + int i; + float f1; + + for(i=0 ; irandom_state = q->random_state * 214013 + 2531011; //typical RNG numbers + f1 = randsign[(q->random_state/0x1000000)&1] * dither_tab[index]; //>>31 + } + mlt_buffer[band*20+ i] = f1 * quant_value_table[band]; + } +} +/** + * Unpack the subband_coef_index and subband_coef_noise vectors. + * + * @param q pointer to the COOKContext + * @param category pointer to the category array + * @param subband_coef_index array of indexes to quant_centroid_tab + * @param subband_coef_noise use random noise instead of predetermined value + */ + +static int unpack_SQVH(COOKContext *q, int category, int* subband_coef_index, + int* subband_coef_noise) { + int i,j; + int vlc, vd ,tmp, result; + int ub; + int cb; + + vd = vd_tab[category]; + result = 0; + for(i=0 ; igb); + vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3); + cb = get_bits_count(&q->gb); + if (q->bits_per_subpacket < get_bits_count(&q->gb)){ + vlc = 0; + result = 1; + } + for(j=vd-1 ; j>=0 ; j--){ + tmp = (vlc * invradix_tab[category])/0x100000; + subband_coef_index[vd*i+j] = vlc - tmp * (kmax_tab[category]+1); + vlc = tmp; + } + for(j=0 ; jgb) < q->bits_per_subpacket){ + subband_coef_noise[i*vd+j] = get_bits1(&q->gb); + } else { + result=1; + subband_coef_noise[i*vd+j]=0; + } + } else { + subband_coef_noise[i*vd+j]=0; + } + } + } + return result; +} + + +/** + * Fill the mlt_buffer with mlt coefficients. + * + * @param q pointer to the COOKContext + * @param category pointer to the category array + * @param quant_value_table pointer to the array + * @param mlt_buffer pointer to mlt coefficients + */ + + +static void decode_vectors(COOKContext* q, int* category, + float* quant_value_table, float* mlt_buffer){ + /* A zero in this table means that the subband coefficient is + random noise coded. */ + int subband_coef_noise[SUBBAND_SIZE]; + /* A zero in this table means that the subband coefficient is a + positive multiplicator. */ + int subband_coef_index[SUBBAND_SIZE]; + int band, j; + int index=0; + + for(band=0 ; bandtotal_subbands ; band++){ + index = category[band]; + if(category[band] < 7){ + if(unpack_SQVH(q, category[band], subband_coef_index, subband_coef_noise)){ + index=7; + for(j=0 ; jtotal_subbands ; j++) category[band+j]=7; + } + } + if(index==7) { + memset(subband_coef_index, 0, sizeof(subband_coef_index)); + memset(subband_coef_noise, 0, sizeof(subband_coef_noise)); + } + scalar_dequant(q, index, band, quant_value_table, subband_coef_index, + subband_coef_noise, mlt_buffer); + } + + if(q->total_subbands*SUBBAND_SIZE >= q->samples_per_channel){ + return; + } +} + + +/** + * function for decoding mono data + * + * @param q pointer to the COOKContext + * @param mlt_buffer1 pointer to left channel mlt coefficients + * @param mlt_buffer2 pointer to right channel mlt coefficients + */ + +static void mono_decode(COOKContext *q, float* mlt_buffer) { + + int category_index[128]; + float quant_value_table[102]; + int quant_index_table[102]; + int category[128]; + + memset(&category, 0, 128*sizeof(int)); + memset(&quant_value_table, 0, 102*sizeof(int)); + memset(&category_index, 0, 128*sizeof(int)); + + decode_envelope(q, quant_index_table); + q->num_vectors = get_bits(&q->gb,q->log2_numvector_size); + dequant_envelope(q, quant_index_table, quant_value_table); + categorize(q, quant_index_table, category, category_index); + expand_category(q, category, category_index); + decode_vectors(q, category, quant_value_table, mlt_buffer); +} + + +/** + * The modulated lapped transform, this takes transform coefficients + * and transforms them into timedomain samples. This is done through + * an FFT-based algorithm with pre- and postrotation steps. + * A window and reorder step is also included. + * + * @param q pointer to the COOKContext + * @param inbuffer pointer to the mltcoefficients + * @param outbuffer pointer to the timedomain buffer + * @param mlt_tmp pointer to temporary storage space + */ + +static void cook_imlt(COOKContext *q, float* inbuffer, float* outbuffer, + float* mlt_tmp){ + int i; + + /* prerotation */ + for(i=0 ; imlt_size ; i+=2){ + outbuffer[i] = (q->mlt_presin[i/2] * inbuffer[q->mlt_size-1-i]) + + (q->mlt_precos[i/2] * inbuffer[i]); + outbuffer[i+1] = (q->mlt_precos[i/2] * inbuffer[q->mlt_size-1-i]) - + (q->mlt_presin[i/2] * inbuffer[i]); + } + + /* FFT */ + ff_fft_permute(&q->fft_ctx, (FFTComplex *) outbuffer); + ff_fft_calc (&q->fft_ctx, (FFTComplex *) outbuffer); + + /* postrotation */ + for(i=0 ; imlt_size ; i+=2){ + mlt_tmp[i] = (q->mlt_postcos[(q->mlt_size-1-i)/2] * outbuffer[i+1]) + + (q->mlt_postcos[i/2] * outbuffer[i]); + mlt_tmp[q->mlt_size-1-i] = (q->mlt_postcos[(q->mlt_size-1-i)/2] * outbuffer[i]) - + (q->mlt_postcos[i/2] * outbuffer[i+1]); + } + + /* window and reorder */ + for(i=0 ; imlt_size/2 ; i++){ + outbuffer[i] = mlt_tmp[q->mlt_size/2-1-i] * q->mlt_window[i]; + outbuffer[q->mlt_size-1-i]= mlt_tmp[q->mlt_size/2-1-i] * + q->mlt_window[q->mlt_size-1-i]; + outbuffer[q->mlt_size+i]= mlt_tmp[q->mlt_size/2+i] * + q->mlt_window[q->mlt_size-1-i]; + outbuffer[2*q->mlt_size-1-i]= -(mlt_tmp[q->mlt_size/2+i] * + q->mlt_window[i]); + } +} + + +/** + * the actual requantization of the timedomain samples + * + * @param q pointer to the COOKContext + * @param buffer pointer to the timedomain buffer + * @param gain_index index for the block multiplier + * @param gain_index_next index for the next block multiplier + */ + +static void interpolate(COOKContext *q, float* buffer, + int gain_index, int gain_index_next){ + int i; + float fc1, fc2; + fc1 = q->pow2tab[gain_index+63]; + + if(gain_index == gain_index_next){ //static gain + for(i=0 ; igain_size_factor ; i++){ + buffer[i]*=fc1; + } + return; + } else { //smooth gain + fc2 = q->gain_table[11 + (gain_index_next-gain_index)]; + for(i=0 ; igain_size_factor ; i++){ + buffer[i]*=fc1; + fc1*=fc2; + } + return; + } +} + +/** + * timedomain requantization of the timedomain samples + * + * @param q pointer to the COOKContext + * @param buffer pointer to the timedomain buffer + * @param gain_now current gain structure + * @param gain_previous previous gain structure + */ + +static void gain_window(COOKContext *q, float* buffer, COOKgain* gain_now, + COOKgain* gain_previous){ + int i, index; + int gain_index[9]; + int tmp_gain_index; + + gain_index[8]=0; + index = gain_previous->size; + for (i=7 ; i>=0 ; i--) { + if(index && gain_previous->qidx_table1[index-1]==i) { + gain_index[i] = gain_previous->qidx_table2[index-1]; + index--; + } else { + gain_index[i]=gain_index[i+1]; + } + } + /* This is applied to the to be previous data buffer. */ + for(i=0;i<8;i++){ + interpolate(q, &buffer[q->samples_per_channel+q->gain_size_factor*i], + gain_index[i], gain_index[i+1]); + } + + tmp_gain_index = gain_index[0]; + index = gain_now->size; + for (i=7 ; i>=0 ; i--) { + if(index && gain_now->qidx_table1[index-1]==i) { + gain_index[i]= gain_now->qidx_table2[index-1]; + index--; + } else { + gain_index[i]=gain_index[i+1]; + } + } + + /* This is applied to the to be current block. */ + for(i=0;i<8;i++){ + interpolate(q, &buffer[i*q->gain_size_factor], + tmp_gain_index+gain_index[i], + tmp_gain_index+gain_index[i+1]); + } +} + + +/** + * mlt overlapping and buffer management + * + * @param q pointer to the COOKContext + * @param buffer pointer to the timedomain buffer + * @param gain_now current gain structure + * @param gain_previous previous gain structure + * @param previous_buffer pointer to the previous buffer to be used for overlapping + * + */ + +static void gain_compensate(COOKContext *q, float* buffer, COOKgain* gain_now, + COOKgain* gain_previous, float* previous_buffer) { + int i; + if((gain_now->size || gain_previous->size)) { + gain_window(q, buffer, gain_now, gain_previous); + } + + /* Overlap with the previous block. */ + for(i=0 ; isamples_per_channel ; i++) buffer[i]+=previous_buffer[i]; + + /* Save away the current to be previous block. */ + memcpy(previous_buffer, buffer+q->samples_per_channel, + sizeof(float)*q->samples_per_channel); +} + + +/** + * function for getting the jointstereo coupling information + * + * @param q pointer to the COOKContext + * @param decouple_tab decoupling array + * + */ + +static void decouple_info(COOKContext *q, int* decouple_tab){ + int length, i; + + if(get_bits1(&q->gb)) { + if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return; + + length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1; + for (i=0 ; ijs_subband_start] + i] = get_vlc2(&q->gb, q->ccpl.table, q->ccpl.bits, 2); + } + return; + } + + if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return; + + length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1; + for (i=0 ; ijs_subband_start] + i] = get_bits(&q->gb, q->js_vlc_bits); + } + return; +} + + +/** + * function for decoding joint stereo data + * + * @param q pointer to the COOKContext + * @param mlt_buffer1 pointer to left channel mlt coefficients + * @param mlt_buffer2 pointer to right channel mlt coefficients + */ + +static void joint_decode(COOKContext *q, float* mlt_buffer1, + float* mlt_buffer2) { + int i,j; + int decouple_tab[SUBBAND_SIZE]; + float decode_buffer[1060]; + int idx, cpl_tmp,tmp_idx; + float f1,f2; + float* cplscale; + + memset(decouple_tab, 0, sizeof(decouple_tab)); + memset(decode_buffer, 0, sizeof(decode_buffer)); + + /* Make sure the buffers are zeroed out. */ + memset(mlt_buffer1,0, 1024*sizeof(float)); + memset(mlt_buffer2,0, 1024*sizeof(float)); + decouple_info(q, decouple_tab); + mono_decode(q, decode_buffer); + + /* The two channels are stored interleaved in decode_buffer. */ + for (i=0 ; ijs_subband_start ; i++) { + for (j=0 ; jjs_vlc_bits) - 1; + for (i=q->js_subband_start ; isubbands ; i++) { + cpl_tmp = cplband[i]; + idx -=decouple_tab[cpl_tmp]; + cplscale = (float*)cplscales[q->js_vlc_bits-2]; //choose decoupler table + f1 = cplscale[decouple_tab[cpl_tmp]]; + f2 = cplscale[idx-1]; + for (j=0 ; jjs_subband_start + i)*20)+j; + mlt_buffer1[20*i + j] = f1 * decode_buffer[tmp_idx]; + mlt_buffer2[20*i + j] = f2 * decode_buffer[tmp_idx]; + } + idx = (1 << q->js_vlc_bits) - 1; + } +} + +/** + * Cook subpacket decoding. This function returns one decoded subpacket, + * usually 1024 samples per channel. + * + * @param q pointer to the COOKContext + * @param inbuffer pointer to the inbuffer + * @param sub_packet_size subpacket size + * @param outbuffer pointer to the outbuffer + */ + + +static int decode_subpacket(COOKContext *q, uint8_t *inbuffer, + int sub_packet_size, int16_t *outbuffer) { + int i,j; + int value; + float* tmp_ptr; + + /* packet dump */ +// for (i=0 ; idecoded_bytes_buffer, sub_packet_size); + init_get_bits(&q->gb, q->decoded_bytes_buffer, sub_packet_size*8); + decode_gain_info(&q->gb, &q->gain_current); + + if(q->nb_channels==2 && q->joint_stereo==1){ + joint_decode(q, q->decode_buf_ptr[0], q->decode_buf_ptr[2]); + + /* Swap buffer pointers. */ + tmp_ptr = q->decode_buf_ptr[1]; + q->decode_buf_ptr[1] = q->decode_buf_ptr[0]; + q->decode_buf_ptr[0] = tmp_ptr; + tmp_ptr = q->decode_buf_ptr[3]; + q->decode_buf_ptr[3] = q->decode_buf_ptr[2]; + q->decode_buf_ptr[2] = tmp_ptr; + + /* FIXME: Rethink the gainbuffer handling, maybe a rename? + now/previous swap */ + q->gain_now_ptr = &q->gain_now; + q->gain_previous_ptr = &q->gain_previous; + for (i=0 ; inb_channels ; i++){ + + cook_imlt(q, q->decode_buf_ptr[i*2], q->mono_mdct_output, q->mlt_tmp); + gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr, + q->gain_previous_ptr, q->previous_buffer_ptr[0]); + + /* Swap out the previous buffer. */ + tmp_ptr = q->previous_buffer_ptr[0]; + q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1]; + q->previous_buffer_ptr[1] = tmp_ptr; + + /* Clip and convert the floats to 16 bits. */ + for (j=0 ; jsamples_per_frame ; j++){ + value = lrintf(q->mono_mdct_output[j]); + if(value < -32768) value = -32768; + else if(value > 32767) value = 32767; + outbuffer[2*j+i] = value; + } + } + + memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain)); + memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain)); + + } else if (q->nb_channels==2 && q->joint_stereo==0) { + /* channel 0 */ + mono_decode(q, q->decode_buf_ptr2[0]); + + tmp_ptr = q->decode_buf_ptr2[0]; + q->decode_buf_ptr2[0] = q->decode_buf_ptr2[1]; + q->decode_buf_ptr2[1] = tmp_ptr; + + memcpy(&q->gain_channel1[0], &q->gain_current ,sizeof(COOKgain)); + q->gain_now_ptr = &q->gain_channel1[0]; + q->gain_previous_ptr = &q->gain_channel1[1]; + + cook_imlt(q, q->decode_buf_ptr2[0], q->mono_mdct_output,q->mlt_tmp); + gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr, + q->gain_previous_ptr, q->mono_previous_buffer1); + + memcpy(&q->gain_channel1[1], &q->gain_channel1[0],sizeof(COOKgain)); + + + for (j=0 ; jsamples_per_frame ; j++){ + value = lrintf(q->mono_mdct_output[j]); + if(value < -32768) value = -32768; + else if(value > 32767) value = 32767; + outbuffer[2*j+1] = value; + } + + /* channel 1 */ + //av_log(NULL,AV_LOG_ERROR,"bits = %d\n",get_bits_count(&q->gb)); + init_get_bits(&q->gb, q->decoded_bytes_buffer, sub_packet_size*8+q->bits_per_subpacket); + + q->gain_now_ptr = &q->gain_channel2[0]; + q->gain_previous_ptr = &q->gain_channel2[1]; + + decode_gain_info(&q->gb, &q->gain_channel2[0]); + mono_decode(q, q->decode_buf_ptr[0]); + + tmp_ptr = q->decode_buf_ptr[0]; + q->decode_buf_ptr[0] = q->decode_buf_ptr[1]; + q->decode_buf_ptr[1] = tmp_ptr; + + cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp); + gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr, + q->gain_previous_ptr, q->mono_previous_buffer2); + + /* Swap out the previous buffer. */ + tmp_ptr = q->previous_buffer_ptr[0]; + q->previous_buffer_ptr[0] = q->previous_buffer_ptr[1]; + q->previous_buffer_ptr[1] = tmp_ptr; + + memcpy(&q->gain_channel2[1], &q->gain_channel2[0] ,sizeof(COOKgain)); + + for (j=0 ; jsamples_per_frame ; j++){ + value = lrintf(q->mono_mdct_output[j]); + if(value < -32768) value = -32768; + else if(value > 32767) value = 32767; + outbuffer[2*j] = value; + } + + } else { + mono_decode(q, q->decode_buf_ptr[0]); + + /* Swap buffer pointers. */ + tmp_ptr = q->decode_buf_ptr[1]; + q->decode_buf_ptr[1] = q->decode_buf_ptr[0]; + q->decode_buf_ptr[0] = tmp_ptr; + + /* FIXME: Rethink the gainbuffer handling, maybe a rename? + now/previous swap */ + q->gain_now_ptr = &q->gain_now; + q->gain_previous_ptr = &q->gain_previous; + + cook_imlt(q, q->decode_buf_ptr[0], q->mono_mdct_output,q->mlt_tmp); + gain_compensate(q, q->mono_mdct_output, q->gain_now_ptr, + q->gain_previous_ptr, q->mono_previous_buffer1); + + /* Clip and convert the floats to 16 bits */ + for (j=0 ; jsamples_per_frame ; j++){ + value = lrintf(q->mono_mdct_output[j]); + if(value < -32768) value = -32768; + else if(value > 32767) value = 32767; + outbuffer[j] = value; + } + memcpy(&q->gain_now, &q->gain_previous, sizeof(COOKgain)); + memcpy(&q->gain_previous, &q->gain_current, sizeof(COOKgain)); + } + return q->samples_per_frame * sizeof(int16_t); +} + + +/** + * Cook frame decoding + * + * @param avctx pointer to the AVCodecContext + */ + +static int cook_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) { + COOKContext *q = avctx->priv_data; + + if (buf_size < avctx->block_align) + return buf_size; + + *data_size = decode_subpacket(q, buf, avctx->block_align, data); + + return avctx->block_align; +} + +#ifdef COOKDEBUG +static void dump_cook_context(COOKContext *q, COOKextradata *e) +{ + //int i=0; +#define PRINT(a,b) av_log(NULL,AV_LOG_ERROR," %s = %d\n", a, b); + av_log(NULL,AV_LOG_ERROR,"COOKextradata\n"); + av_log(NULL,AV_LOG_ERROR,"cookversion=%x\n",e->cookversion); + if (e->cookversion > MONO_COOK2) { + PRINT("js_subband_start",e->js_subband_start); + PRINT("js_vlc_bits",e->js_vlc_bits); + } + av_log(NULL,AV_LOG_ERROR,"COOKContext\n"); + PRINT("nb_channels",q->nb_channels); + PRINT("bit_rate",q->bit_rate); + PRINT("sample_rate",q->sample_rate); + PRINT("samples_per_channel",q->samples_per_channel); + PRINT("samples_per_frame",q->samples_per_frame); + PRINT("subbands",q->subbands); + PRINT("random_state",q->random_state); + PRINT("mlt_size",q->mlt_size); + PRINT("js_subband_start",q->js_subband_start); + PRINT("log2_numvector_size",q->log2_numvector_size); + PRINT("numvector_size",q->numvector_size); + PRINT("total_subbands",q->total_subbands); +} +#endif + +/** + * Cook initialization + * + * @param avctx pointer to the AVCodecContext + */ + +static int cook_decode_init(AVCodecContext *avctx) +{ + COOKextradata *e = avctx->extradata; + COOKContext *q = avctx->priv_data; + + /* Take care of the codec specific extradata. */ + if (avctx->extradata_size <= 0) { + av_log(NULL,AV_LOG_ERROR,"Necessary extradata missing!\n"); + return -1; + } else { + /* 8 for mono, 16 for stereo, ? for multichannel + Swap to right endianness so we don't need to care later on. */ + av_log(NULL,AV_LOG_DEBUG,"codecdata_length=%d\n",avctx->extradata_size); + if (avctx->extradata_size >= 8){ + e->cookversion = be2me_32(e->cookversion); + e->samples_per_frame = be2me_16(e->samples_per_frame); + e->subbands = be2me_16(e->subbands); + } + if (avctx->extradata_size >= 16){ + e->js_subband_start = be2me_16(e->js_subband_start); + e->js_vlc_bits = be2me_16(e->js_vlc_bits); + } + } + + /* Take data from the AVCodecContext (RM container). */ + q->sample_rate = avctx->sample_rate; + q->nb_channels = avctx->channels; + q->bit_rate = avctx->bit_rate; + + /* Initialize state. */ + q->random_state = 1; + + /* Initialize extradata related variables. */ + q->samples_per_channel = e->samples_per_frame / q->nb_channels; + q->samples_per_frame = e->samples_per_frame; + q->subbands = e->subbands; + q->bits_per_subpacket = avctx->block_align * 8; + + /* Initialize default data states. */ + q->js_subband_start = 0; + q->log2_numvector_size = 5; + q->total_subbands = q->subbands; + + /* Initialize version-dependent variables */ + av_log(NULL,AV_LOG_DEBUG,"e->cookversion=%x\n",e->cookversion); + switch (e->cookversion) { + case MONO_COOK1: + if (q->nb_channels != 1) { + av_log(NULL,AV_LOG_ERROR,"Container channels != 1, report sample!\n"); + return -1; + } + av_log(NULL,AV_LOG_DEBUG,"MONO_COOK1\n"); + break; + case MONO_COOK2: + if (q->nb_channels != 1) { + q->joint_stereo = 0; + q->bits_per_subpacket = q->bits_per_subpacket/2; + } + av_log(NULL,AV_LOG_DEBUG,"MONO_COOK2\n"); + break; + case JOINT_STEREO: + if (q->nb_channels != 2) { + av_log(NULL,AV_LOG_ERROR,"Container channels != 2, report sample!\n"); + return -1; + } + av_log(NULL,AV_LOG_DEBUG,"JOINT_STEREO\n"); + if (avctx->extradata_size >= 16){ + q->total_subbands = q->subbands + e->js_subband_start; + q->js_subband_start = e->js_subband_start; + q->joint_stereo = 1; + q->js_vlc_bits = e->js_vlc_bits; + } + if (q->samples_per_channel > 256) { + q->log2_numvector_size = 6; + } + if (q->samples_per_channel > 512) { + q->log2_numvector_size = 7; + } + break; + case MC_COOK: + av_log(NULL,AV_LOG_ERROR,"MC_COOK not supported!\n"); + return -1; + break; + default: + av_log(NULL,AV_LOG_ERROR,"Unknown Cook version, report sample!\n"); + return -1; + break; + } + + /* Initialize variable relations */ + q->mlt_size = q->samples_per_channel; + q->numvector_size = (1 << q->log2_numvector_size); + + /* Generate tables */ + init_rootpow2table(q); + init_pow2table(q); + init_gain_table(q); + + if (init_cook_vlc_tables(q) != 0) + return -1; + + /* Pad the databuffer with FF_INPUT_BUFFER_PADDING_SIZE, + this is for the bitstreamreader. */ + if ((q->decoded_bytes_buffer = av_mallocz((avctx->block_align+(4-avctx->block_align%4) + FF_INPUT_BUFFER_PADDING_SIZE)*sizeof(uint8_t))) == NULL) + return -1; + + q->decode_buf_ptr[0] = q->decode_buffer_1; + q->decode_buf_ptr[1] = q->decode_buffer_2; + q->decode_buf_ptr[2] = q->decode_buffer_3; + q->decode_buf_ptr[3] = q->decode_buffer_4; + + q->decode_buf_ptr2[0] = q->decode_buffer_3; + q->decode_buf_ptr2[1] = q->decode_buffer_4; + + q->previous_buffer_ptr[0] = q->mono_previous_buffer1; + q->previous_buffer_ptr[1] = q->mono_previous_buffer2; + + /* Initialize transform. */ + if ( init_cook_mlt(q) == 0 ) + return -1; + + /* Try to catch some obviously faulty streams, othervise it might be exploitable */ + if (q->total_subbands > 53) { + av_log(NULL,AV_LOG_ERROR,"total_subbands > 53, report sample!\n"); + return -1; + } + if (q->subbands > 50) { + av_log(NULL,AV_LOG_ERROR,"subbands > 50, report sample!\n"); + return -1; + } + if ((q->samples_per_channel == 256) || (q->samples_per_channel == 512) || (q->samples_per_channel == 1024)) { + } else { + av_log(NULL,AV_LOG_ERROR,"unknown amount of samples_per_channel = %d, report sample!\n",q->samples_per_channel); + return -1; + } + +#ifdef COOKDEBUG + dump_cook_context(q,e); +#endif + return 0; +} + + +AVCodec cook_decoder = +{ + .name = "cook", + .type = CODEC_TYPE_AUDIO, + .id = CODEC_ID_COOK, + .priv_data_size = sizeof(COOKContext), + .init = cook_decode_init, + .close = cook_decode_close, + .decode = cook_decode_frame, +}; diff --git a/mpeg4/src/libavcodec/cookdata.h b/mpeg4/src/libavcodec/cookdata.h new file mode 100644 index 00000000..1247d9d9 --- /dev/null +++ b/mpeg4/src/libavcodec/cookdata.h @@ -0,0 +1,557 @@ +/* + * COOK compatible decoder data + * Copyright (c) 2003 Sascha Sommer + * Copyright (c) 2005 Benjamin Larsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file cookdata.h + * Cook AKA RealAudio G2 compatible decoderdata + */ + +/* various data tables */ + +static const int expbits_tab[8] = { + 52,47,43,37,29,22,16,0, +}; + +static const float dither_tab[8] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.176777, 0.25, 0.707107, +}; + +static const float randsign[2] = {1.0, -1.0}; + +static const float quant_centroid_tab[7][14] = { + { 0.000, 0.392, 0.761, 1.120, 1.477, 1.832, 2.183, 2.541, 2.893, 3.245, 3.598, 3.942, 4.288, 4.724 }, + { 0.000, 0.544, 1.060, 1.563, 2.068, 2.571, 3.072, 3.562, 4.070, 4.620, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 0.746, 1.464, 2.180, 2.882, 3.584, 4.316, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 1.006, 2.000, 2.993, 3.985, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 1.321, 2.703, 3.983, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 1.657, 3.491, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 }, + { 0.000, 1.964, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 } +}; + +static const int invradix_tab[7] = { + 74899, 104858, 149797, 209716, 262144, 349526, 524288, +}; + +static const int kmax_tab[7] = { + 13, 9, 6, 4, 3, 2, 1, +}; + +static const int vd_tab[7] = { + 2, 2, 2, 4, 4, 5, 5, +}; + +static const int vpr_tab[7] = { + 10, 10, 10, 5, 5, 4, 4, +}; + + + +/* VLC data */ + +static const int vhsize_tab[7] = { + 191, 97, 48, 607, 246, 230, 32, +}; + +static const int vhvlcsize_tab[7] = { + 8, 7, 7, 10, 9, 9, 6, +}; + +static const uint8_t envelope_quant_index_huffbits[13][24] = { + { 4, 6, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 5, 7, 8, 9, 11, 11, 12, 12, 12, 12 }, + { 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 7, 9, 11, 12, 13, 15, 15, 15, 16, 16 }, + { 12, 10, 8, 6, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 4, 5, 5, 7, 9, 11, 13, 14, 14 }, + { 13, 10, 9, 9, 7, 7, 5, 5, 4, 3, 3, 3, 3, 3, 4, 4, 4, 5, 7, 9, 11, 13, 13, 13 }, + { 12, 13, 10, 8, 6, 6, 5, 5, 4, 4, 3, 3, 3, 3, 3, 4, 5, 5, 6, 7, 9, 11, 14, 14 }, + { 12, 11, 9, 8, 8, 7, 5, 4, 4, 3, 3, 3, 3, 3, 4, 4, 5, 5, 7, 8, 10, 13, 14, 14 }, + { 15, 16, 15, 12, 10, 8, 6, 5, 4, 3, 3, 3, 2, 3, 4, 5, 5, 7, 9, 11, 13, 16, 16, 16 }, + { 14, 14, 11, 10, 9, 7, 7, 5, 5, 4, 3, 3, 2, 3, 3, 4, 5, 7, 9, 9, 12, 14, 15, 15 }, + { 9, 9, 9, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 13 }, + { 14, 12, 10, 8, 6, 6, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 8, 8, 9, 11, 14, 14, 14 }, + { 13, 10, 9, 8, 6, 6, 5, 4, 4, 4, 3, 3, 2, 3, 4, 5, 6, 8, 9, 9, 11, 12, 14, 14 }, + { 16, 13, 12, 11, 9, 6, 5, 5, 4, 4, 4, 3, 2, 3, 3, 4, 5, 7, 8, 10, 14, 16, 16, 16 }, + { 13, 14, 14, 14, 10, 8, 7, 7, 5, 4, 3, 3, 2, 3, 3, 4, 5, 5, 7, 9, 11, 14, 14, 14 }, +}; + +static const uint16_t envelope_quant_index_huffcodes[13][24] = { + {0x0006, 0x003e, 0x001c, 0x001d, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x0000, 0x0001, + 0x0002, 0x000d, 0x001e, 0x007e, 0x00fe, 0x01fe, 0x07fc, 0x07fd, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff}, + {0x03fe, 0x00fe, 0x003e, 0x001c, 0x001d, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x000d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x0ffe, 0x1ffe, 0x7ffc, 0x7ffd, 0x7ffe, 0xfffe, 0xffff}, + {0x0ffe, 0x03fe, 0x00fe, 0x003e, 0x001c, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x0000, + 0x0001, 0x0002, 0x000c, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffe, 0x3ffe, 0x3fff}, + {0x1ffc, 0x03fe, 0x01fc, 0x01fd, 0x007c, 0x007d, 0x001c, 0x001d, 0x000a, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x000b, 0x000c, 0x000d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffd, 0x1ffe, 0x1fff}, + {0x0ffe, 0x1ffe, 0x03fe, 0x00fe, 0x003c, 0x003d, 0x001a, 0x001b, 0x000a, 0x000b, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x000c, 0x001c, 0x001d, 0x003e, 0x007e, 0x01fe, 0x07fe, 0x3ffe, 0x3fff}, + {0x0ffe, 0x07fe, 0x01fe, 0x00fc, 0x00fd, 0x007c, 0x001c, 0x000a, 0x000b, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x000c, 0x000d, 0x001d, 0x001e, 0x007d, 0x00fe, 0x03fe, 0x1ffe, 0x3ffe, 0x3fff}, + {0x7ffc, 0xfffc, 0x7ffd, 0x0ffe, 0x03fe, 0x00fe, 0x003e, 0x001c, 0x000c, 0x0002, 0x0003, 0x0004, + 0x0000, 0x0005, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x1ffe, 0xfffd, 0xfffe, 0xffff}, + {0x3ffc, 0x3ffd, 0x07fe, 0x03fe, 0x01fc, 0x007c, 0x007d, 0x001c, 0x001d, 0x000c, 0x0002, 0x0003, + 0x0000, 0x0004, 0x0005, 0x000d, 0x001e, 0x007e, 0x01fd, 0x01fe, 0x0ffe, 0x3ffe, 0x7ffe, 0x7fff}, + {0x01fc, 0x01fd, 0x01fe, 0x00fc, 0x007c, 0x003c, 0x001c, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x000d, 0x001d, 0x003d, 0x007d, 0x00fd, 0x03fe, 0x07fe, 0x0ffe, 0x1ffe, 0x1fff}, + {0x3ffc, 0x0ffe, 0x03fe, 0x00fc, 0x003c, 0x003d, 0x001c, 0x000c, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x000d, 0x001d, 0x003e, 0x00fd, 0x00fe, 0x01fe, 0x07fe, 0x3ffd, 0x3ffe, 0x3fff}, + {0x1ffe, 0x03fe, 0x01fc, 0x00fc, 0x003c, 0x003d, 0x001c, 0x000a, 0x000b, 0x000c, 0x0002, 0x0003, + 0x0000, 0x0004, 0x000d, 0x001d, 0x003e, 0x00fd, 0x01fd, 0x01fe, 0x07fe, 0x0ffe, 0x3ffe, 0x3fff}, + {0xfffc, 0x1ffe, 0x0ffe, 0x07fe, 0x01fe, 0x003e, 0x001c, 0x001d, 0x000a, 0x000b, 0x000c, 0x0002, + 0x0000, 0x0003, 0x0004, 0x000d, 0x001e, 0x007e, 0x00fe, 0x03fe, 0x3ffe, 0xfffd, 0xfffe, 0xffff}, + {0x1ffc, 0x3ffa, 0x3ffb, 0x3ffc, 0x03fe, 0x00fe, 0x007c, 0x007d, 0x001c, 0x000c, 0x0002, 0x0003, + 0x0000, 0x0004, 0x0005, 0x000d, 0x001d, 0x001e, 0x007e, 0x01fe, 0x07fe, 0x3ffd, 0x3ffe, 0x3fff}, +}; + + +static const uint8_t cvh_huffbits0[191] = { + 1, 4, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, + 11, 11, 4, 5, 6, 7, 7, 8, 8, 9, 9, 9, + 9, 10, 11, 11, 5, 6, 7, 8, 8, 9, 9, 9, + 9, 10, 10, 10, 11, 12, 6, 7, 8, 9, 9, 9, + 9, 10, 10, 10, 10, 11, 12, 13, 7, 7, 8, 9, + 9, 9, 10, 10, 10, 10, 11, 11, 12, 13, 8, 8, + 9, 9, 9, 10, 10, 10, 10, 11, 11, 12, 13, 14, + 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, + 13, 15, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, + 12, 13, 14, 15, 9, 9, 9, 10, 10, 10, 11, 11, + 12, 13, 12, 14, 15, 16, 9, 9, 10, 10, 10, 10, + 11, 12, 12, 14, 14, 16, 16, 0, 9, 9, 10, 10, + 11, 11, 12, 13, 13, 14, 14, 15, 0, 0, 10, 10, + 10, 11, 11, 12, 12, 13, 15, 15, 16, 0, 0, 0, + 11, 11, 11, 12, 13, 13, 13, 15, 16, 16, 0, 0, + 0, 0, 11, 11, 12, 13, 13, 14, 15, 16, 16, +}; + +static const uint16_t cvh_huffcodes0[191] = { + 0x0000,0x0008,0x002c,0x002d,0x0062,0x0063,0x00d4,0x00d5,0x00d6,0x01c6,0x01c7,0x03ca, + 0x07d6,0x07d7,0x0009,0x0014,0x002e,0x0064,0x0065,0x00d7,0x00d8,0x01c8,0x01c9,0x01ca, + 0x01cb,0x03cb,0x07d8,0x07d9,0x0015,0x002f,0x0066,0x00d9,0x00da,0x01cc,0x01cd,0x01ce, + 0x01cf,0x03cc,0x03cd,0x03ce,0x07da,0x0fe4,0x0030,0x0067,0x00db,0x01d0,0x01d1,0x01d2, + 0x01d3,0x03cf,0x03d0,0x03d1,0x03d2,0x07db,0x0fe5,0x1fea,0x0068,0x0069,0x00dc,0x01d4, + 0x01d5,0x01d6,0x03d3,0x03d4,0x03d5,0x03d6,0x07dc,0x07dd,0x0fe6,0x1feb,0x00dd,0x00de, + 0x01d7,0x01d8,0x01d9,0x03d7,0x03d8,0x03d9,0x03da,0x07de,0x07df,0x0fe7,0x1fec,0x3ff2, + 0x00df,0x00e0,0x01da,0x01db,0x03db,0x03dc,0x07e0,0x07e1,0x07e2,0x0fe8,0x0fe9,0x1fed, + 0x1fee,0x7ff4,0x00e1,0x00e2,0x01dc,0x01dd,0x03dd,0x03de,0x07e3,0x07e4,0x07e5,0x0fea, + 0x0feb,0x1fef,0x3ff3,0x7ff5,0x01de,0x01df,0x01e0,0x03df,0x03e0,0x03e1,0x07e6,0x07e7, + 0x0fec,0x1ff0,0x0fed,0x3ff4,0x7ff6,0xfff8,0x01e1,0x01e2,0x03e2,0x03e3,0x03e4,0x03e5, + 0x07e8,0x0fee,0x0fef,0x3ff5,0x3ff6,0xfff9,0xfffa,0xfffa,0x01e3,0x01e4,0x03e6,0x03e7, + 0x07e9,0x07ea,0x0ff0,0x1ff1,0x1ff2,0x3ff7,0x3ff8,0x7ff7,0x7ff7,0xfffa,0x03e8,0x03e9, + 0x03ea,0x07eb,0x07ec,0x0ff1,0x0ff2,0x1ff3,0x7ff8,0x7ff9,0xfffb,0x3ff8,0x7ff7,0x7ff7, + 0x07ed,0x07ee,0x07ef,0x0ff3,0x1ff4,0x1ff5,0x1ff6,0x7ffa,0xfffc,0xfffd,0xfffb,0xfffb, + 0x3ff8,0x7ff7,0x07f0,0x07f1,0x0ff4,0x1ff7,0x1ff8,0x3ff9,0x7ffb,0xfffe,0xffff, +}; + + +static const uint8_t cvh_huffbits1[97] = { + 1, 4, 5, 6, 7, 8, 8, 9, 10, 10, 4, 5, + 6, 7, 7, 8, 8, 9, 9, 11, 5, 5, 6, 7, + 8, 8, 9, 9, 10, 11, 6, 6, 7, 8, 8, 9, + 9, 10, 11, 12, 7, 7, 8, 8, 9, 9, 10, 11, + 11, 13, 8, 8, 8, 9, 9, 10, 10, 11, 12, 14, + 8, 8, 8, 9, 10, 11, 11, 12, 13, 15, 9, 9, + 9, 10, 11, 12, 12, 14, 14, 0, 9, 9, 9, 10, + 11, 12, 14, 16, 0, 0, 10, 10, 11, 12, 13, 14, + 16, +}; + + +static const uint16_t cvh_huffcodes1[97] = { + 0x0000,0x0008,0x0014,0x0030,0x006a,0x00e2,0x00e3,0x01e4,0x03ec,0x03ed,0x0009,0x0015, + 0x0031,0x006b,0x006c,0x00e4,0x00e5,0x01e5,0x01e6,0x07f0,0x0016,0x0017,0x0032,0x006d, + 0x00e6,0x00e7,0x01e7,0x01e8,0x03ee,0x07f1,0x0033,0x0034,0x006e,0x00e8,0x00e9,0x01e9, + 0x01ea,0x03ef,0x07f2,0x0ff6,0x006f,0x0070,0x00ea,0x00eb,0x01eb,0x01ec,0x03f0,0x07f3, + 0x07f4,0x1ffa,0x00ec,0x00ed,0x00ee,0x01ed,0x01ee,0x03f1,0x03f2,0x07f5,0x0ff7,0x3ffa, + 0x00ef,0x00f0,0x00f1,0x01ef,0x03f3,0x07f6,0x07f7,0x0ff8,0x1ffb,0x7ffe,0x01f0,0x01f1, + 0x01f2,0x03f4,0x07f8,0x0ff9,0x0ffa,0x3ffb,0x3ffc,0x0000,0x01f3,0x01f4,0x01f5,0x03f5, + 0x07f9,0x0ffb,0x3ffd,0xfffe,0x0000,0x0000,0x03f6,0x03f7,0x07fa,0x0ffc,0x1ffc,0x3ffe, + 0xffff, +}; + +static const uint8_t cvh_huffbits2[48] = { + 1, 4, 5, 7, 8, 9, 10, 3, 4, 5, 7, 8, + 9, 10, 5, 5, 6, 7, 8, 10, 10, 7, 6, 7, + 8, 9, 10, 12, 8, 8, 8, 9, 10, 12, 14, 8, + 9, 9, 10, 11, 15, 16, 9, 10, 11, 12, 13, 16, +}; + +static const uint16_t cvh_huffcodes2[48] = { + 0x0000,0x000a,0x0018,0x0074,0x00f2,0x01f4,0x03f6,0x0004,0x000b,0x0019,0x0075,0x00f3, + 0x01f5,0x03f7,0x001a,0x001b,0x0038,0x0076,0x00f4,0x03f8,0x03f9,0x0077,0x0039,0x0078, + 0x00f5,0x01f6,0x03fa,0x0ffc,0x00f6,0x00f7,0x00f8,0x01f7,0x03fb,0x0ffd,0x3ffe,0x00f9, + 0x01f8,0x01f9,0x03fc,0x07fc,0x7ffe,0xfffe,0x01fa,0x03fd,0x07fd,0x0ffe,0x1ffe,0xffff, +}; + +static const uint8_t cvh_huffbits3[607] = { + 2, 4, 6, 8, 10, 5, 5, 6, 8, 10, 7, 8, + 8, 10, 12, 9, 9, 10, 12, 15, 10, 11, 13, 16, + 16, 5, 6, 8, 10, 11, 5, 6, 8, 10, 12, 7, + 7, 8, 10, 13, 9, 9, 10, 12, 15, 12, 11, 13, + 16, 16, 7, 9, 10, 12, 15, 7, 8, 10, 12, 13, + 9, 9, 11, 13, 16, 11, 11, 12, 14, 16, 12, 12, + 14, 16, 0, 9, 11, 12, 16, 16, 9, 10, 13, 15, + 16, 10, 11, 12, 16, 16, 13, 13, 16, 16, 16, 16, + 16, 15, 16, 0, 11, 13, 16, 16, 15, 11, 13, 15, + 16, 16, 13, 13, 16, 16, 0, 14, 16, 16, 16, 0, + 16, 16, 0, 0, 0, 4, 6, 8, 10, 13, 6, 6, + 8, 10, 13, 9, 8, 10, 12, 16, 10, 10, 11, 15, + 16, 13, 12, 14, 16, 16, 5, 6, 8, 11, 13, 6, + 6, 8, 10, 13, 8, 8, 9, 11, 14, 10, 10, 12, + 12, 16, 13, 12, 13, 15, 16, 7, 8, 9, 12, 16, + 7, 8, 10, 12, 14, 9, 9, 10, 13, 16, 11, 10, + 12, 15, 16, 13, 13, 16, 16, 0, 9, 11, 13, 16, + 16, 9, 10, 12, 15, 16, 10, 11, 13, 16, 16, 13, + 12, 16, 16, 16, 16, 16, 16, 16, 0, 11, 13, 16, + 16, 16, 11, 13, 16, 16, 16, 12, 13, 15, 16, 0, + 16, 16, 16, 16, 0, 16, 16, 0, 0, 0, 6, 8, + 11, 13, 16, 8, 8, 10, 12, 16, 11, 10, 11, 13, + 16, 12, 13, 13, 15, 16, 16, 16, 14, 16, 0, 6, + 8, 10, 13, 16, 8, 8, 10, 12, 16, 10, 10, 11, + 13, 16, 13, 12, 13, 16, 16, 14, 14, 14, 16, 0, + 8, 9, 11, 13, 16, 8, 9, 11, 16, 14, 10, 10, + 12, 15, 16, 12, 12, 13, 16, 16, 15, 16, 16, 16, + 0, 10, 12, 15, 16, 16, 10, 12, 12, 14, 16, 12, + 12, 13, 16, 16, 14, 15, 16, 16, 0, 16, 16, 16, + 0, 0, 12, 15, 15, 16, 0, 13, 13, 16, 16, 0, + 14, 16, 16, 16, 0, 16, 16, 16, 0, 0, 0, 0, + 0, 0, 0, 8, 10, 13, 15, 16, 10, 11, 13, 16, + 16, 13, 13, 14, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 0, 8, 10, 11, 15, 16, 9, 10, 12, + 16, 16, 12, 12, 15, 16, 16, 16, 14, 16, 16, 16, + 16, 16, 16, 16, 0, 9, 11, 14, 16, 16, 10, 11, + 13, 16, 16, 14, 13, 14, 16, 16, 16, 15, 15, 16, + 0, 16, 16, 16, 0, 0, 11, 13, 16, 16, 16, 11, + 13, 15, 16, 16, 13, 16, 16, 16, 0, 16, 16, 16, + 16, 0, 16, 16, 0, 0, 0, 15, 16, 16, 16, 0, + 14, 16, 16, 16, 0, 16, 16, 16, 0, 0, 16, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 13, 16, 16, + 16, 11, 13, 16, 16, 16, 14, 15, 16, 16, 0, 15, + 16, 16, 16, 0, 16, 16, 0, 0, 0, 9, 13, 15, + 15, 16, 12, 13, 14, 16, 16, 16, 15, 16, 16, 0, + 16, 16, 16, 16, 0, 16, 16, 0, 0, 0, 11, 13, + 15, 16, 0, 12, 14, 16, 16, 0, 16, 16, 16, 16, + 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16, + 16, 16, 16, 0, 16, 16, 16, 16, 0, 16, 16, 16, + 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 16, 0, 0, 0, 16, 16, +}; + + +static const uint16_t cvh_huffcodes3[607] = { + 0x0000,0x0004,0x0022,0x00c6,0x03b0,0x000c,0x000d,0x0023,0x00c7,0x03b1,0x005c,0x00c8, + 0x00c9,0x03b2,0x0fa4,0x01c2,0x01c3,0x03b3,0x0fa5,0x7f72,0x03b4,0x07b2,0x1f9a,0xff24, + 0xff25,0x000e,0x0024,0x00ca,0x03b5,0x07b3,0x000f,0x0025,0x00cb,0x03b6,0x0fa6,0x005d, + 0x005e,0x00cc,0x03b7,0x1f9b,0x01c4,0x01c5,0x03b8,0x0fa7,0x7f73,0x0fa8,0x07b4,0x1f9c, + 0xff26,0xff27,0x005f,0x01c6,0x03b9,0x0fa9,0x7f74,0x0060,0x00cd,0x03ba,0x0faa,0x1f9d, + 0x01c7,0x01c8,0x07b5,0x1f9e,0xff28,0x07b6,0x07b7,0x0fab,0x3fa2,0xff29,0x0fac,0x0fad, + 0x3fa3,0xff2a,0x3fa2,0x01c9,0x07b8,0x0fae,0xff2b,0xff2c,0x01ca,0x03bb,0x1f9f,0x7f75, + 0xff2d,0x03bc,0x07b9,0x0faf,0xff2e,0xff2f,0x1fa0,0x1fa1,0xff30,0xff31,0xff32,0xff33, + 0xff34,0x7f76,0xff35,0xff31,0x07ba,0x1fa2,0xff36,0xff37,0x7f77,0x07bb,0x1fa3,0x7f78, + 0xff38,0xff39,0x1fa4,0x1fa5,0xff3a,0xff3b,0xff2e,0x3fa4,0xff3c,0xff3d,0xff3e,0xff31, + 0xff3f,0xff40,0xff30,0xff31,0xff31,0x0005,0x0026,0x00ce,0x03bd,0x1fa6,0x0027,0x0028, + 0x00cf,0x03be,0x1fa7,0x01cb,0x00d0,0x03bf,0x0fb0,0xff41,0x03c0,0x03c1,0x07bc,0x7f79, + 0xff42,0x1fa8,0x0fb1,0x3fa5,0xff43,0xff44,0x0010,0x0029,0x00d1,0x07bd,0x1fa9,0x002a, + 0x002b,0x00d2,0x03c2,0x1faa,0x00d3,0x00d4,0x01cc,0x07be,0x3fa6,0x03c3,0x03c4,0x0fb2, + 0x0fb3,0xff45,0x1fab,0x0fb4,0x1fac,0x7f7a,0xff46,0x0061,0x00d5,0x01cd,0x0fb5,0xff47, + 0x0062,0x00d6,0x03c5,0x0fb6,0x3fa7,0x01ce,0x01cf,0x03c6,0x1fad,0xff48,0x07bf,0x03c7, + 0x0fb7,0x7f7b,0xff49,0x1fae,0x1faf,0xff4a,0xff4b,0x7f7b,0x01d0,0x07c0,0x1fb0,0xff4c, + 0xff4d,0x01d1,0x03c8,0x0fb8,0x7f7c,0xff4e,0x03c9,0x07c1,0x1fb1,0xff4f,0xff50,0x1fb2, + 0x0fb9,0xff51,0xff52,0xff53,0xff54,0xff55,0xff56,0xff57,0xff52,0x07c2,0x1fb3,0xff58, + 0xff59,0xff5a,0x07c3,0x1fb4,0xff5b,0xff5c,0xff5d,0x0fba,0x1fb5,0x7f7d,0xff5e,0xff4f, + 0xff5f,0xff60,0xff61,0xff62,0xff52,0xff63,0xff64,0xff51,0xff52,0xff52,0x002c,0x00d7, + 0x07c4,0x1fb6,0xff65,0x00d8,0x00d9,0x03ca,0x0fbb,0xff66,0x07c5,0x03cb,0x07c6,0x1fb7, + 0xff67,0x0fbc,0x1fb8,0x1fb9,0x7f7e,0xff68,0xff69,0xff6a,0x3fa8,0xff6b,0x7f7e,0x002d, + 0x00da,0x03cc,0x1fba,0xff6c,0x00db,0x00dc,0x03cd,0x0fbd,0xff6d,0x03ce,0x03cf,0x07c7, + 0x1fbb,0xff6e,0x1fbc,0x0fbe,0x1fbd,0xff6f,0xff70,0x3fa9,0x3faa,0x3fab,0xff71,0xff6f, + 0x00dd,0x01d2,0x07c8,0x1fbe,0xff72,0x00de,0x01d3,0x07c9,0xff73,0x3fac,0x03d0,0x03d1, + 0x0fbf,0x7f7f,0xff74,0x0fc0,0x0fc1,0x1fbf,0xff75,0xff76,0x7f80,0xff77,0xff78,0xff79, + 0xff75,0x03d2,0x0fc2,0x7f81,0xff7a,0xff7b,0x03d3,0x0fc3,0x0fc4,0x3fad,0xff7c,0x0fc5, + 0x0fc6,0x1fc0,0xff7d,0xff7e,0x3fae,0x7f82,0xff7f,0xff80,0xff80,0xff81,0xff82,0xff83, + 0xff80,0xff80,0x0fc7,0x7f83,0x7f84,0xff84,0xff7a,0x1fc1,0x1fc2,0xff85,0xff86,0x3fad, + 0x3faf,0xff87,0xff88,0xff89,0xff7d,0xff8a,0xff8b,0xff8c,0xff80,0xff80,0x3fae,0x7f82, + 0xff7f,0xff80,0xff80,0x00df,0x03d4,0x1fc3,0x7f85,0xff8d,0x03d5,0x07ca,0x1fc4,0xff8e, + 0xff8f,0x1fc5,0x1fc6,0x3fb0,0xff90,0xff91,0xff92,0xff93,0xff94,0xff95,0xff96,0xff97, + 0xff98,0xff99,0xff9a,0xff95,0x00e0,0x03d6,0x07cb,0x7f86,0xff9b,0x01d4,0x03d7,0x0fc8, + 0xff9c,0xff9d,0x0fc9,0x0fca,0x7f87,0xff9e,0xff9f,0xffa0,0x3fb1,0xffa1,0xffa2,0xffa3, + 0xffa4,0xffa5,0xffa6,0xffa7,0xffa2,0x01d5,0x07cc,0x3fb2,0xffa8,0xffa9,0x03d8,0x07cd, + 0x1fc7,0xffaa,0xffab,0x3fb3,0x1fc8,0x3fb4,0xffac,0xffad,0xffae,0x7f88,0x7f89,0xffaf, + 0xffaf,0xffb0,0xffb1,0xffb2,0xffaf,0xffaf,0x07ce,0x1fc9,0xffb3,0xffb4,0xffb5,0x07cf, + 0x1fca,0x7f8a,0xffb6,0xffb7,0x1fcb,0xffb8,0xffb9,0xffba,0xffba,0xffbb,0xffbc,0xffbd, + 0xffbe,0xffbe,0xffbf,0xffc0,0xffbd,0xffbe,0xffbe,0x7f8b,0xffc1,0xffc2,0xffc3,0xffb4, + 0x3fb5,0xffc4,0xffc5,0xffc6,0xffb6,0xffc7,0xffc8,0xffc9,0xffba,0xffba,0xffca,0xffcb, + 0xffbd,0xffbe,0xffbe,0xffbb,0xffbc,0xffbd,0xffbe,0xffbe,0x01d6,0x1fcc,0xffcc,0xffcd, + 0xffce,0x07d0,0x1fcd,0xffcf,0xffd0,0xffd1,0x3fb6,0x7f8c,0xffd2,0xffd3,0xff90,0x7f8d, + 0xffd4,0xffd5,0xffd6,0xff95,0xffd7,0xffd8,0xff94,0xff95,0xff95,0x01d7,0x1fce,0x7f8e, + 0x7f8f,0xffd9,0x0fcb,0x1fcf,0x3fb7,0xffda,0xffdb,0xffdc,0x7f90,0xffdd,0xffde,0xff9e, + 0xffdf,0xffe0,0xffe1,0xffe2,0xffa2,0xffe3,0xffe4,0xffa1,0xffa2,0xffa2,0x07d1,0x1fd0, + 0x7f91,0xffe5,0xffa8,0x0fcc,0x3fb8,0xffe6,0xffe7,0xffaa,0xffe8,0xffe9,0xffea,0xffeb, + 0xffac,0xffec,0xffed,0xffee,0xffaf,0xffaf,0xffae,0x7f88,0x7f89,0xffaf,0xffaf,0xffef, + 0xfff0,0xfff1,0xfff2,0xffb4,0xfff3,0xfff4,0xfff5,0xfff6,0xffb6,0xfff7,0xfff8,0xfff9, + 0xffba,0xffba,0xfffa,0xfffb,0xffbd,0xffbe,0xffbe,0xffbb,0xffbc,0xffbd,0xffbe,0xffbe, + 0xfffc,0xfffd,0xffb3,0xffb4,0xffb4,0xfffe,0xffff, +}; + +static const uint8_t cvh_huffbits4[246] = { + 2, 4, 7, 10, 4, 5, 7, 10, 7, 8, 10, 14, + 11, 11, 15, 15, 4, 5, 9, 12, 5, 5, 8, 12, + 8, 7, 10, 15, 11, 11, 15, 15, 7, 9, 12, 15, + 8, 8, 12, 15, 10, 10, 13, 15, 14, 14, 15, 0, + 11, 13, 15, 15, 11, 13, 15, 15, 14, 15, 15, 0, + 15, 15, 0, 0, 4, 5, 9, 13, 5, 6, 9, 13, + 9, 9, 11, 15, 14, 13, 15, 15, 4, 6, 9, 12, + 5, 6, 9, 13, 9, 8, 11, 15, 13, 12, 15, 15, + 7, 9, 12, 15, 7, 8, 11, 15, 10, 10, 14, 15, + 14, 15, 15, 0, 10, 12, 15, 15, 11, 13, 15, 15, + 15, 15, 15, 0, 15, 15, 0, 0, 6, 9, 13, 14, + 8, 9, 12, 15, 12, 12, 15, 15, 15, 15, 15, 0, + 7, 9, 13, 15, 8, 9, 12, 15, 11, 12, 15, 15, + 15, 15, 15, 0, 9, 11, 15, 15, 9, 11, 15, 15, + 14, 14, 15, 0, 15, 15, 0, 0, 14, 15, 15, 0, + 14, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 0, + 9, 12, 15, 15, 12, 13, 15, 15, 15, 15, 15, 0, + 15, 15, 0, 0, 10, 12, 15, 15, 12, 14, 15, 15, + 15, 15, 15, 0, 15, 15, 0, 0, 14, 15, 15, 0, + 15, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 0, + 15, 15, 0, 0, 15, 15, +}; + + +static const uint16_t cvh_huffcodes4[246] = { + 0x0000,0x0004,0x006c,0x03e6,0x0005,0x0012,0x006d,0x03e7,0x006e,0x00e8,0x03e8,0x3fc4, + 0x07e0,0x07e1,0x7fa4,0x7fa5,0x0006,0x0013,0x01e2,0x0fda,0x0014,0x0015,0x00e9,0x0fdb, + 0x00ea,0x006f,0x03e9,0x7fa6,0x07e2,0x07e3,0x7fa7,0x7fa8,0x0070,0x01e3,0x0fdc,0x7fa9, + 0x00eb,0x00ec,0x0fdd,0x7faa,0x03ea,0x03eb,0x1fd6,0x7fab,0x3fc5,0x3fc6,0x7fac,0x1fd6, + 0x07e4,0x1fd7,0x7fad,0x7fae,0x07e5,0x1fd8,0x7faf,0x7fb0,0x3fc7,0x7fb1,0x7fb2,0x1fd6, + 0x7fb3,0x7fb4,0x1fd6,0x1fd6,0x0007,0x0016,0x01e4,0x1fd9,0x0017,0x0032,0x01e5,0x1fda, + 0x01e6,0x01e7,0x07e6,0x7fb5,0x3fc8,0x1fdb,0x7fb6,0x7fb7,0x0008,0x0033,0x01e8,0x0fde, + 0x0018,0x0034,0x01e9,0x1fdc,0x01ea,0x00ed,0x07e7,0x7fb8,0x1fdd,0x0fdf,0x7fb9,0x7fba, + 0x0071,0x01eb,0x0fe0,0x7fbb,0x0072,0x00ee,0x07e8,0x7fbc,0x03ec,0x03ed,0x3fc9,0x7fbd, + 0x3fca,0x7fbe,0x7fbf,0x3fc9,0x03ee,0x0fe1,0x7fc0,0x7fc1,0x07e9,0x1fde,0x7fc2,0x7fc3, + 0x7fc4,0x7fc5,0x7fc6,0x3fc9,0x7fc7,0x7fc8,0x3fc9,0x3fc9,0x0035,0x01ec,0x1fdf,0x3fcb, + 0x00ef,0x01ed,0x0fe2,0x7fc9,0x0fe3,0x0fe4,0x7fca,0x7fcb,0x7fcc,0x7fcd,0x7fce,0x7fca, + 0x0073,0x01ee,0x1fe0,0x7fcf,0x00f0,0x01ef,0x0fe5,0x7fd0,0x07ea,0x0fe6,0x7fd1,0x7fd2, + 0x7fd3,0x7fd4,0x7fd5,0x7fd1,0x01f0,0x07eb,0x7fd6,0x7fd7,0x01f1,0x07ec,0x7fd8,0x7fd9, + 0x3fcc,0x3fcd,0x7fda,0x7fda,0x7fdb,0x7fdc,0x7fda,0x7fda,0x3fce,0x7fdd,0x7fde,0x7fd6, + 0x3fcf,0x7fdf,0x7fe0,0x7fd8,0x7fe1,0x7fe2,0x7fda,0x7fda,0x3fcc,0x3fcd,0x7fda,0x7fda, + 0x01f2,0x0fe7,0x7fe3,0x7fe4,0x0fe8,0x1fe1,0x7fe5,0x7fe6,0x7fe7,0x7fe8,0x7fe9,0x7fca, + 0x7fea,0x7feb,0x7fca,0x7fca,0x03ef,0x0fe9,0x7fec,0x7fed,0x0fea,0x3fd0,0x7fee,0x7fef, + 0x7ff0,0x7ff1,0x7ff2,0x7fd1,0x7ff3,0x7ff4,0x7fd1,0x7fd1,0x3fd1,0x7ff5,0x7ff6,0x7fd6, + 0x7ff7,0x7ff8,0x7ff9,0x7fd8,0x7ffa,0x7ffb,0x7fda,0x7fda,0x3fcc,0x3fcd,0x7fda,0x7fda, + 0x7ffc,0x7ffd,0x7fd6,0x7fd6,0x7ffe,0x7fff, +}; + + +static const uint8_t cvh_huffbits5[230] = { + 2, 4, 8, 4, 5, 9, 9, 10, 14, 4, 6, 11, + 5, 6, 12, 10, 11, 15, 9, 11, 15, 10, 13, 15, + 14, 15, 0, 4, 6, 12, 6, 7, 12, 12, 12, 15, + 5, 7, 13, 6, 7, 13, 12, 13, 15, 10, 12, 15, + 11, 13, 15, 15, 15, 0, 8, 13, 15, 11, 12, 15, + 15, 15, 0, 10, 13, 15, 12, 15, 15, 15, 15, 0, + 15, 15, 0, 15, 15, 0, 0, 0, 0, 4, 5, 11, + 5, 7, 12, 11, 12, 15, 6, 7, 13, 7, 8, 14, + 12, 14, 15, 11, 13, 15, 12, 13, 15, 15, 15, 0, + 5, 6, 13, 7, 8, 15, 12, 14, 15, 6, 8, 14, + 7, 8, 15, 14, 15, 15, 12, 12, 15, 12, 13, 15, + 15, 15, 0, 9, 13, 15, 12, 13, 15, 15, 15, 0, + 11, 13, 15, 13, 13, 15, 15, 15, 0, 14, 15, 0, + 15, 15, 0, 0, 0, 0, 8, 10, 15, 11, 12, 15, + 15, 15, 0, 10, 12, 15, 12, 13, 15, 15, 15, 0, + 14, 15, 0, 15, 15, 0, 0, 0, 0, 8, 12, 15, + 12, 13, 15, 15, 15, 0, 11, 13, 15, 13, 15, 15, + 15, 15, 0, 15, 15, 0, 15, 15, 0, 0, 0, 0, + 14, 15, 0, 15, 15, 0, 0, 0, 0, 15, 15, 0, + 15, 15, +}; + + + +static const uint16_t cvh_huffcodes5[230] = { + 0x0000,0x0004,0x00f0,0x0005,0x0012,0x01f0,0x01f1,0x03e8,0x3fce,0x0006,0x0030,0x07de, + 0x0013,0x0031,0x0fd2,0x03e9,0x07df,0x7fb0,0x01f2,0x07e0,0x7fb1,0x03ea,0x1fd2,0x7fb2, + 0x3fcf,0x7fb3,0x0031,0x0007,0x0032,0x0fd3,0x0033,0x0070,0x0fd4,0x0fd5,0x0fd6,0x7fb4, + 0x0014,0x0071,0x1fd3,0x0034,0x0072,0x1fd4,0x0fd7,0x1fd5,0x7fb5,0x03eb,0x0fd8,0x7fb6, + 0x07e1,0x1fd6,0x7fb7,0x7fb8,0x7fb9,0x0072,0x00f1,0x1fd7,0x7fba,0x07e2,0x0fd9,0x7fbb, + 0x7fbc,0x7fbd,0x0070,0x03ec,0x1fd8,0x7fbe,0x0fda,0x7fbf,0x7fc0,0x7fc1,0x7fc2,0x0072, + 0x7fc3,0x7fc4,0x0071,0x7fc5,0x7fc6,0x0072,0x0034,0x0072,0x0072,0x0008,0x0015,0x07e3, + 0x0016,0x0073,0x0fdb,0x07e4,0x0fdc,0x7fc7,0x0035,0x0074,0x1fd9,0x0075,0x00f2,0x3fd0, + 0x0fdd,0x3fd1,0x7fc8,0x07e5,0x1fda,0x7fc9,0x0fde,0x1fdb,0x7fca,0x7fcb,0x7fcc,0x00f2, + 0x0017,0x0036,0x1fdc,0x0076,0x00f3,0x7fcd,0x0fdf,0x3fd2,0x7fce,0x0037,0x00f4,0x3fd3, + 0x0077,0x00f5,0x7fcf,0x3fd4,0x7fd0,0x7fd1,0x0fe0,0x0fe1,0x7fd2,0x0fe2,0x1fdd,0x7fd3, + 0x7fd4,0x7fd5,0x00f5,0x01f3,0x1fde,0x7fd6,0x0fe3,0x1fdf,0x7fd7,0x7fd8,0x7fd9,0x00f3, + 0x07e6,0x1fe0,0x7fda,0x1fe1,0x1fe2,0x7fdb,0x7fdc,0x7fdd,0x00f5,0x3fd5,0x7fde,0x00f4, + 0x7fdf,0x7fe0,0x00f5,0x0077,0x00f5,0x00f5,0x00f6,0x03ed,0x7fe1,0x07e7,0x0fe4,0x7fe2, + 0x7fe3,0x7fe4,0x0073,0x03ee,0x0fe5,0x7fe5,0x0fe6,0x1fe3,0x7fe6,0x7fe7,0x7fe8,0x00f2, + 0x3fd6,0x7fe9,0x0074,0x7fea,0x7feb,0x00f2,0x0075,0x00f2,0x00f2,0x00f7,0x0fe7,0x7fec, + 0x0fe8,0x1fe4,0x7fed,0x7fee,0x7fef,0x00f3,0x07e8,0x1fe5,0x7ff0,0x1fe6,0x7ff1,0x7ff2, + 0x7ff3,0x7ff4,0x00f5,0x7ff5,0x7ff6,0x00f4,0x7ff7,0x7ff8,0x00f5,0x0077,0x00f5,0x00f5, + 0x3fd7,0x7ff9,0x0036,0x7ffa,0x7ffb,0x00f3,0x0076,0x00f3,0x00f3,0x7ffc,0x7ffd,0x0000, + 0x7ffe,0x7fff, +}; + + +static const uint8_t cvh_huffbits6[32] = { + 1, 4, 4, 6, 4, 6, 6, 8, 4, 6, 6, 8, + 6, 9, 8, 10, 4, 6, 7, 8, 6, 9, 8, 11, + 6, 9, 8, 10, 8, 10, 9, 11, +}; + +static const uint16_t cvh_huffcodes6[32] = { + 0x0000,0x0008,0x0009,0x0034,0x000a,0x0035,0x0036,0x00f6,0x000b,0x0037,0x0038,0x00f7, + 0x0039,0x01fa,0x00f8,0x03fc,0x000c,0x003a,0x007a,0x00f9,0x003b,0x01fb,0x00fa,0x07fe, + 0x003c,0x01fc,0x00fb,0x03fd,0x00fc,0x03fe,0x01fd,0x07ff, +}; + +static const uint16_t* cvh_huffcodes[7] = { + cvh_huffcodes0, cvh_huffcodes1, cvh_huffcodes2, cvh_huffcodes3, + cvh_huffcodes4, cvh_huffcodes5, cvh_huffcodes6, +}; + +static const uint8_t* cvh_huffbits[7] = { + cvh_huffbits0, cvh_huffbits1, cvh_huffbits2, cvh_huffbits3, + cvh_huffbits4, cvh_huffbits5, cvh_huffbits6, +}; + + +static const uint16_t ccpl_huffcodes2[3] = { + 0x02,0x00,0x03, +}; + +static const uint16_t ccpl_huffcodes3[7] = { + 0x3e,0x1e,0x02,0x00,0x06,0x0e,0x3f, +}; + +static const uint16_t ccpl_huffcodes4[15] = { + 0xfc,0xfd,0x7c,0x3c,0x1c,0x0c,0x04,0x00,0x05,0x0d,0x1d,0x3d, + 0x7d,0xfe,0xff, +}; + +static const uint16_t ccpl_huffcodes5[31] = { + 0x03f8,0x03f9,0x03fa,0x03fb,0x01f8,0x01f9,0x00f8,0x00f9,0x0078,0x0079,0x0038,0x0039, + 0x0018,0x0019,0x0004,0x0000,0x0005,0x001a,0x001b,0x003a,0x003b,0x007a,0x007b,0x00fa, + 0x00fb,0x01fa,0x01fb,0x03fc,0x03fd,0x03fe,0x03ff, +}; + +static const uint16_t ccpl_huffcodes6[63] = { + 0x0004,0x0005,0x0005,0x0006,0x0006,0x0007,0x0007,0x0007,0x0007,0x0008,0x0008,0x0008, + 0x0008,0x0009,0x0009,0x0009,0x0009,0x000a,0x000a,0x000a,0x000a,0x000a,0x000b,0x000b, + 0x000b,0x000b,0x000c,0x000d,0x000e,0x000e,0x0010,0x0000,0x000a,0x0018,0x0019,0x0036, + 0x0037,0x0074,0x0075,0x0076,0x0077,0x00f4,0x00f5,0x00f6,0x00f7,0x01f5,0x01f6,0x01f7, + 0x01f8,0x03f6,0x03f7,0x03f8,0x03f9,0x03fa,0x07fa,0x07fb,0x07fc,0x07fd,0x0ffd,0x1ffd, + 0x3ffd,0x3ffe,0xffff, +}; + +static const uint8_t ccpl_huffbits2[3] = { + 2,1,2, +}; + +static const uint8_t ccpl_huffbits3[7] = { + 6,5,2,1,3,4,6, +}; + +static const uint8_t ccpl_huffbits4[15] = { + 8,8,7,6,5,4,3,1,3,4,5,6,7,8,8, +}; + +static const uint8_t ccpl_huffbits5[31] = { + 10,10,10,10,9,9,8,8,7,7,6,6, + 5,5,3,1,3,5,5,6,6,7,7,8, + 8,9,9,10,10,10,10, +}; + +static const uint8_t ccpl_huffbits6[63] = { + 16,15,14,13,12,11,11,11,11,10,10,10, + 10,9,9,9,9,9,8,8,8,8,7,7, + 7,7,6,6,5,5,3,1,4,5,5,6, + 6,7,7,7,7,8,8,8,8,9,9,9, + 9,10,10,10,10,10,11,11,11,11,12,13, + 14,14,16, +}; + +static const uint16_t* ccpl_huffcodes[5] = { + ccpl_huffcodes2,ccpl_huffcodes3, + ccpl_huffcodes4,ccpl_huffcodes5,ccpl_huffcodes6 +}; + +static const uint8_t* ccpl_huffbits[5] = { + ccpl_huffbits2,ccpl_huffbits3, + ccpl_huffbits4,ccpl_huffbits5,ccpl_huffbits6 +}; + + +//Coupling tables + +static const int cplband[51] = { + 0,1,2,3,4,5,6,7,8,9, + 10,11,11,12,12,13,13,14,14,14, + 15,15,15,15,16,16,16,16,16,17, + 17,17,17,17,17,18,18,18,18,18, + 18,18,19,19,19,19,19,19,19,19, + 19, +}; + +static const float cplscale2[3] = { +0.953020632266998,0.70710676908493,0.302905440330505, +}; + +static const float cplscale3[7] = { +0.981279790401459,0.936997592449188,0.875934481620789,0.70710676908493, +0.482430040836334,0.349335819482803,0.192587479948997, +}; + +static const float cplscale4[15] = { +0.991486728191376,0.973249018192291,0.953020632266998,0.930133521556854, +0.903453230857849,0.870746195316315,0.826180458068848,0.70710676908493, +0.563405573368073,0.491732746362686,0.428686618804932,0.367221474647522, +0.302905440330505,0.229752898216248,0.130207896232605, +}; + +static const float cplscale5[31] = { +0.995926380157471,0.987517595291138,0.978726446628571,0.969505727291107, +0.95979779958725,0.949531257152557,0.938616216182709,0.926936149597168, +0.914336204528809,0.900602877140045,0.885426938533783,0.868331849575043, +0.84851086139679,0.824381768703461,0.791833400726318,0.70710676908493, +0.610737144947052,0.566034197807312,0.529177963733673,0.495983630418777, +0.464778542518616,0.434642940759659,0.404955863952637,0.375219136476517, +0.344963222742081,0.313672333955765,0.280692428350449,0.245068684220314, +0.205169528722763,0.157508864998817,0.0901700109243393, +}; + +static const float cplscale6[63] = { +0.998005926609039,0.993956744670868,0.989822506904602,0.985598564147949, +0.981279790401459,0.976860702037811,0.972335040569305,0.967696130275726, +0.962936460971832,0.958047747612000,0.953020632266998,0.947844684123993, +0.942508161067963,0.936997592449188,0.931297719478607,0.925390899181366, +0.919256627559662,0.912870943546295,0.906205296516418,0.899225592613220, +0.891890347003937,0.884148240089417,0.875934481620789,0.867165684700012, +0.857730865478516,0.847477376461029,0.836184680461884,0.823513329029083, +0.808890223503113,0.791194140911102,0.767520070075989,0.707106769084930, +0.641024887561798,0.611565053462982,0.587959706783295,0.567296981811523, +0.548448026180267,0.530831515789032,0.514098942279816,0.498019754886627, +0.482430040836334,0.467206478118896,0.452251672744751,0.437485188245773, +0.422837972640991,0.408248275518417,0.393658757209778,0.379014074802399, +0.364258885383606,0.349335819482803,0.334183186292648,0.318732559680939, +0.302905440330505,0.286608695983887,0.269728302955627,0.252119421958923, +0.233590632677078,0.213876649737358,0.192587479948997,0.169101938605309, +0.142307326197624,0.109772264957428,0.0631198287010193, +}; + +static const float* cplscales[5] = { + cplscale2, cplscale3, cplscale4, cplscale5, cplscale6, +}; diff --git a/mpeg4/src/libavcodec/cscd.c b/mpeg4/src/libavcodec/cscd.c new file mode 100644 index 00000000..0d6e0452 --- /dev/null +++ b/mpeg4/src/libavcodec/cscd.c @@ -0,0 +1,262 @@ +/* + * CamStudio decoder + * Copyright (c) 2006 Reimar Doeffinger + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include + +#include "common.h" +#include "avcodec.h" + +#ifdef CONFIG_ZLIB +#include +#endif +#include "lzo.h" + +typedef struct { + AVFrame pic; + int linelen, height, bpp; + unsigned int decomp_size; + unsigned char* decomp_buf; +} CamStudioContext; + +static void copy_frame_default(AVFrame *f, uint8_t *src, + int linelen, int height) { + int i; + uint8_t *dst = f->data[0]; + dst += (height - 1) * f->linesize[0]; + for (i = height; i; i--) { + memcpy(dst, src, linelen); + src += linelen; + dst -= f->linesize[0]; + } +} + +static void add_frame_default(AVFrame *f, uint8_t *src, + int linelen, int height) { + int i, j; + uint8_t *dst = f->data[0]; + dst += (height - 1) * f->linesize[0]; + for (i = height; i; i--) { + for (j = linelen; j; j--) + *dst++ += *src++; + dst -= f->linesize[0] + linelen; + } +} + +#ifndef WORDS_BIGENDIAN +#define copy_frame_16 copy_frame_default +#define copy_frame_32 copy_frame_default +#define add_frame_16 add_frame_default +#define add_frame_32 add_frame_default +#else +static void copy_frame_16(AVFrame *f, uint8_t *src, + int linelen, int height) { + int i, j; + uint8_t *dst = f->data[0]; + dst += (height - 1) * f->linesize[0]; + for (i = height; i; i--) { + for (j = linelen / 2; j; j--) { + dst[0] = src[1]; + dst[1] = src[0]; + src += 2; + dst += 2; + } + dst -= f->linesize[0] + linelen; + } +} + +static void copy_frame_32(AVFrame *f, uint8_t *src, + int linelen, int height) { + int i, j; + uint8_t *dst = f->data[0]; + dst += (height - 1) * f->linesize[0]; + for (i = height; i; i--) { + for (j = linelen / 4; j; j--) { + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; + src += 4; + dst += 4; + } + dst -= f->linesize[0] + linelen; + } +} + +static void add_frame_16(AVFrame *f, uint8_t *src, + int linelen, int height) { + int i, j; + uint8_t *dst = f->data[0]; + dst += (height - 1) * f->linesize[0]; + for (i = height; i; i--) { + for (j = linelen / 2; j; j--) { + dst[0] += src[1]; + dst[1] += src[0]; + src += 2; + dst += 2; + } + dst -= f->linesize[0] + linelen; + } +} + +static void add_frame_32(AVFrame *f, uint8_t *src, + int linelen, int height) { + int i, j; + uint8_t *dst = f->data[0]; + dst += (height - 1) * f->linesize[0]; + for (i = height; i; i--) { + for (j = linelen / 4; j; j--) { + dst[0] += src[3]; + dst[1] += src[2]; + dst[2] += src[1]; + dst[3] += src[0]; + src += 4; + dst += 4; + } + dst -= f->linesize[0] + linelen; + } +} +#endif + +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, + uint8_t *buf, int buf_size) { + CamStudioContext *c = (CamStudioContext *)avctx->priv_data; + AVFrame *picture = data; + + if (buf_size < 2) { + av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); + return -1; + } + + if (c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + c->pic.reference = 1; + c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | + FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->get_buffer(avctx, &c->pic) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + // decompress data + switch ((buf[0] >> 1) & 7) { + case 0: { // lzo compression + int outlen = c->decomp_size, inlen = buf_size - 2; + if (lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen)) + av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); + break; + } + case 1: { // zlib compression +#ifdef CONFIG_ZLIB + unsigned long dlen = c->decomp_size; + if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK) + av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n"); + break; +#else + av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n"); + return -1; +#endif + } + default: + av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); + return -1; + } + + // flip upside down, add difference frame + if (buf[0] & 1) { // keyframe + c->pic.pict_type = FF_I_TYPE; + c->pic.key_frame = 1; + switch (c->bpp) { + case 16: + copy_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); + break; + case 32: + copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); + break; + default: + copy_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height); + } + } else { + c->pic.pict_type = FF_P_TYPE; + c->pic.key_frame = 0; + switch (c->bpp) { + case 16: + add_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height); + break; + case 32: + add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height); + break; + default: + add_frame_default(&c->pic, c->decomp_buf, c->linelen, c->height); + } + } + + *picture = c->pic; + *data_size = sizeof(AVFrame); + return buf_size; +} + +static int decode_init(AVCodecContext *avctx) { + CamStudioContext *c = (CamStudioContext *)avctx->priv_data; + if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) { + return 1; + } + avctx->has_b_frames = 0; + switch (avctx->bits_per_sample) { + case 16: avctx->pix_fmt = PIX_FMT_RGB565; break; + case 24: avctx->pix_fmt = PIX_FMT_BGR24; break; + case 32: avctx->pix_fmt = PIX_FMT_RGBA32; break; + default: + av_log(avctx, AV_LOG_ERROR, + "CamStudio codec error: unvalid depth %i bpp\n", + avctx->bits_per_sample); + return 1; + } + c->bpp = avctx->bits_per_sample; + c->pic.data[0] = NULL; + c->linelen = avctx->width * avctx->bits_per_sample / 8; + c->height = avctx->height; + c->decomp_size = c->height * c->linelen; + c->decomp_buf = av_malloc(c->decomp_size + LZO_OUTPUT_PADDING); + if (!c->decomp_buf) { + av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); + return 1; + } + return 0; +} + +static int decode_end(AVCodecContext *avctx) { + CamStudioContext *c = (CamStudioContext *)avctx->priv_data; + av_freep(&c->decomp_buf); + if (c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + return 0; +} + +AVCodec cscd_decoder = { + "camstudio", + CODEC_TYPE_VIDEO, + CODEC_ID_CSCD, + sizeof(CamStudioContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; + diff --git a/mpeg4/src/libavcodec/cyuv.c b/mpeg4/src/libavcodec/cyuv.c new file mode 100644 index 00000000..b64e1a58 --- /dev/null +++ b/mpeg4/src/libavcodec/cyuv.c @@ -0,0 +1,188 @@ +/* + * + * Copyright (C) 2003 the ffmpeg project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Creative YUV (CYUV) Video Decoder + * by Mike Melanson (melanson@pcisys.net) + * based on "Creative YUV (CYUV) stream format for AVI": + * http://www.csse.monash.edu.au/~timf/videocodec/cyuv.txt + * + */ + +/** + * @file cyuv.c + * Creative YUV (CYUV) Video Decoder. + */ + +#include +#include +#include +#include + +#include "common.h" +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + + +typedef struct CyuvDecodeContext { + AVCodecContext *avctx; + int width, height; + AVFrame frame; +} CyuvDecodeContext; + +static int cyuv_decode_init(AVCodecContext *avctx) +{ + CyuvDecodeContext *s = avctx->priv_data; + + s->avctx = avctx; + s->width = avctx->width; + /* width needs to be divisible by 4 for this codec to work */ + if (s->width & 0x3) + return -1; + s->height = avctx->height; + avctx->pix_fmt = PIX_FMT_YUV411P; + avctx->has_b_frames = 0; + + return 0; +} + +static int cyuv_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + CyuvDecodeContext *s=avctx->priv_data; + + unsigned char *y_plane; + unsigned char *u_plane; + unsigned char *v_plane; + int y_ptr; + int u_ptr; + int v_ptr; + + /* prediction error tables (make it clear that they are signed values) */ + signed char *y_table = buf + 0; + signed char *u_table = buf + 16; + signed char *v_table = buf + 32; + + unsigned char y_pred, u_pred, v_pred; + int stream_ptr; + unsigned char cur_byte; + int pixel_groups; + + /* sanity check the buffer size: A buffer has 3x16-bytes tables + * followed by (height) lines each with 3 bytes to represent groups + * of 4 pixels. Thus, the total size of the buffer ought to be: + * (3 * 16) + height * (width * 3 / 4) */ + if (buf_size != 48 + s->height * (s->width * 3 / 4)) { + av_log(avctx, AV_LOG_ERROR, "ffmpeg: cyuv: got a buffer with %d bytes when %d were expected\n", + buf_size, + 48 + s->height * (s->width * 3 / 4)); + return -1; + } + + /* pixel data starts 48 bytes in, after 3x16-byte tables */ + stream_ptr = 48; + + if(s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID; + s->frame.reference = 0; + if(avctx->get_buffer(avctx, &s->frame) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + y_plane = s->frame.data[0]; + u_plane = s->frame.data[1]; + v_plane = s->frame.data[2]; + + /* iterate through each line in the height */ + for (y_ptr = 0, u_ptr = 0, v_ptr = 0; + y_ptr < (s->height * s->frame.linesize[0]); + y_ptr += s->frame.linesize[0] - s->width, + u_ptr += s->frame.linesize[1] - s->width / 4, + v_ptr += s->frame.linesize[2] - s->width / 4) { + + /* reset predictors */ + cur_byte = buf[stream_ptr++]; + u_plane[u_ptr++] = u_pred = cur_byte & 0xF0; + y_plane[y_ptr++] = y_pred = (cur_byte & 0x0F) << 4; + + cur_byte = buf[stream_ptr++]; + v_plane[v_ptr++] = v_pred = cur_byte & 0xF0; + y_pred += y_table[cur_byte & 0x0F]; + y_plane[y_ptr++] = y_pred; + + cur_byte = buf[stream_ptr++]; + y_pred += y_table[cur_byte & 0x0F]; + y_plane[y_ptr++] = y_pred; + y_pred += y_table[(cur_byte & 0xF0) >> 4]; + y_plane[y_ptr++] = y_pred; + + /* iterate through the remaining pixel groups (4 pixels/group) */ + pixel_groups = s->width / 4 - 1; + while (pixel_groups--) { + + cur_byte = buf[stream_ptr++]; + u_pred += u_table[(cur_byte & 0xF0) >> 4]; + u_plane[u_ptr++] = u_pred; + y_pred += y_table[cur_byte & 0x0F]; + y_plane[y_ptr++] = y_pred; + + cur_byte = buf[stream_ptr++]; + v_pred += v_table[(cur_byte & 0xF0) >> 4]; + v_plane[v_ptr++] = v_pred; + y_pred += y_table[cur_byte & 0x0F]; + y_plane[y_ptr++] = y_pred; + + cur_byte = buf[stream_ptr++]; + y_pred += y_table[cur_byte & 0x0F]; + y_plane[y_ptr++] = y_pred; + y_pred += y_table[(cur_byte & 0xF0) >> 4]; + y_plane[y_ptr++] = y_pred; + + } + } + + *data_size=sizeof(AVFrame); + *(AVFrame*)data= s->frame; + + return buf_size; +} + +static int cyuv_decode_end(AVCodecContext *avctx) +{ +/* CyuvDecodeContext *s = avctx->priv_data;*/ + + return 0; +} + +AVCodec cyuv_decoder = { + "cyuv", + CODEC_TYPE_VIDEO, + CODEC_ID_CYUV, + sizeof(CyuvDecodeContext), + cyuv_decode_init, + NULL, + cyuv_decode_end, + cyuv_decode_frame, + CODEC_CAP_DR1, + NULL +}; + diff --git a/mpeg4/src/libavcodec/dct-test.c b/mpeg4/src/libavcodec/dct-test.c new file mode 100644 index 00000000..232278c8 --- /dev/null +++ b/mpeg4/src/libavcodec/dct-test.c @@ -0,0 +1,516 @@ +/** + * @file dct-test.c + * DCT test. (c) 2001 Fabrice Bellard. + * Started from sample code by Juan J. Sierralta P. + */ + +#include +#include +#include +#include +#include + +#include "dsputil.h" + +#include "i386/mmx.h" +#include "simple_idct.h" +#include "faandct.h" + +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#undef printf + +void *fast_memcpy(void *a, const void *b, size_t c){return memcpy(a,b,c);}; + +/* reference fdct/idct */ +extern void fdct(DCTELEM *block); +extern void idct(DCTELEM *block); +extern void ff_idct_xvid_mmx(DCTELEM *block); +extern void ff_idct_xvid_mmx2(DCTELEM *block); +extern void init_fdct(); + +extern void j_rev_dct(DCTELEM *data); +extern void ff_mmx_idct(DCTELEM *data); +extern void ff_mmxext_idct(DCTELEM *data); + +extern void odivx_idct_c (short *block); + +#define AANSCALE_BITS 12 +static const unsigned short aanscales[64] = { + /* precomputed values scaled up by 14 bits */ + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 +}; + +uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; + +int64_t gettime(void) +{ + struct timeval tv; + gettimeofday(&tv,NULL); + return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; +} + +#define NB_ITS 20000 +#define NB_ITS_SPEED 50000 + +static short idct_mmx_perm[64]; + +static short idct_simple_mmx_perm[64]={ + 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, + 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, + 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, + 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, + 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, + 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, + 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, + 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, +}; + +void idct_mmx_init(void) +{ + int i; + + /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */ + for (i = 0; i < 64; i++) { + idct_mmx_perm[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2); +// idct_simple_mmx_perm[i] = simple_block_permute_op(i); + } +} + +static DCTELEM block[64] __attribute__ ((aligned (8))); +static DCTELEM block1[64] __attribute__ ((aligned (8))); +static DCTELEM block_org[64] __attribute__ ((aligned (8))); + +void dct_error(const char *name, int is_idct, + void (*fdct_func)(DCTELEM *block), + void (*fdct_ref)(DCTELEM *block), int test) +{ + int it, i, scale; + int err_inf, v; + int64_t err2, ti, ti1, it1; + int64_t sysErr[64], sysErrMax=0; + int maxout=0; + int blockSumErrMax=0, blockSumErr; + + srandom(0); + + err_inf = 0; + err2 = 0; + for(i=0; i<64; i++) sysErr[i]=0; + for(it=0;it>=3; + } + break; + case 1:{ + int num= (random()%10)+1; + for(i=0;i> AANSCALE_BITS; + } + } + + fdct_ref(block1); + + blockSumErr=0; + for(i=0;i<64;i++) { + v = abs(block[i] - block1[i]); + if (v > err_inf) + err_inf = v; + err2 += v * v; + sysErr[i] += block[i] - block1[i]; + blockSumErr += v; + if( abs(block[i])>maxout) maxout=abs(block[i]); + } + if(blockSumErrMax < blockSumErr) blockSumErrMax= blockSumErr; +#if 0 // print different matrix pairs + if(blockSumErr){ + printf("\n"); + for(i=0; i<64; i++){ + if((i&7)==0) printf("\n"); + printf("%4d ", block_org[i]); + } + for(i=0; i<64; i++){ + if((i&7)==0) printf("\n"); + printf("%4d ", block[i] - block1[i]); + } + } +#endif + } + for(i=0; i<64; i++) sysErrMax= MAX(sysErrMax, ABS(sysErr[i])); + +#if 1 // dump systematic errors + for(i=0; i<64; i++){ + if(i%8==0) printf("\n"); + printf("%5d ", (int)sysErr[i]); + } + printf("\n"); +#endif + + printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n", + is_idct ? "IDCT" : "DCT", + name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax); +#if 1 //Speed test + /* speed test */ + for(i=0;i<64;i++) + block1[i] = 0; + switch(test){ + case 0: + for(i=0;i<64;i++) + block1[i] = (random() % 512) -256; + if (is_idct){ + fdct(block1); + + for(i=0;i<64;i++) + block1[i]>>=3; + } + break; + case 1:{ + case 2: + block1[0] = (random() % 512) -256; + block1[1] = (random() % 512) -256; + block1[2] = (random() % 512) -256; + block1[3] = (random() % 512) -256; + }break; + } + + if (fdct_func == ff_mmx_idct || + fdct_func == j_rev_dct || fdct_func == ff_mmxext_idct) { + for(i=0;i<64;i++) + block[idct_mmx_perm[i]] = block1[i]; + } else if(fdct_func == ff_simple_idct_mmx ) { + for(i=0;i<64;i++) + block[idct_simple_mmx_perm[i]] = block1[i]; + } else { + for(i=0; i<64; i++) + block[i]= block1[i]; + } + + ti = gettime(); + it1 = 0; + do { + for(it=0;it 255) + v = 255; + dest[i * linesize + j] = (int)rint(v); + } + } +} + +void idct248_error(const char *name, + void (*idct248_put)(uint8_t *dest, int line_size, int16_t *block)) +{ + int it, i, it1, ti, ti1, err_max, v; + + srandom(0); + + /* just one test to see if code is correct (precision is less + important here) */ + err_max = 0; + for(it=0;it err_max) + err_max = v; + } +#if 0 + printf("ref=\n"); + for(i=0;i<8;i++) { + int j; + for(j=0;j<8;j++) { + printf(" %3d", img_dest1[i*8+j]); + } + printf("\n"); + } + + printf("out=\n"); + for(i=0;i<8;i++) { + int j; + for(j=0;j<8;j++) { + printf(" %3d", img_dest[i*8+j]); + } + printf("\n"); + } +#endif + } + printf("%s %s: err_inf=%d\n", + 1 ? "IDCT248" : "DCT248", + name, err_max); + + ti = gettime(); + it1 = 0; + do { + for(it=0;it]\n" + "test-number 0 -> test with random matrixes\n" + " 1 -> test with random sparse matrixes\n" + " 2 -> do 3. test from mpeg4 std\n" + "-i test IDCT implementations\n" + "-4 test IDCT248 implementations\n"); + exit(1); +} + +int main(int argc, char **argv) +{ + int test_idct = 0, test_248_dct = 0; + int c,i; + int test=1; + + init_fdct(); + idct_mmx_init(); + + for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; + for(i=0;i 32767) x = 32767; +#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; + +static int interplay_delta_table[] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 47, 51, 56, 61, + 66, 72, 79, 86, 94, 102, 112, 122, + 133, 145, 158, 173, 189, 206, 225, 245, + 267, 292, 318, 348, 379, 414, 452, 493, + 538, 587, 640, 699, 763, 832, 908, 991, + 1081, 1180, 1288, 1405, 1534, 1673, 1826, 1993, + 2175, 2373, 2590, 2826, 3084, 3365, 3672, 4008, + 4373, 4772, 5208, 5683, 6202, 6767, 7385, 8059, + 8794, 9597, 10472, 11428, 12471, 13609, 14851, 16206, + 17685, 19298, 21060, 22981, 25078, 27367, 29864, 32589, + -29973, -26728, -23186, -19322, -15105, -10503, -5481, -1, + 1, 1, 5481, 10503, 15105, 19322, 23186, 26728, + 29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298, + -17685, -16206, -14851, -13609, -12471, -11428, -10472, -9597, + -8794, -8059, -7385, -6767, -6202, -5683, -5208, -4772, + -4373, -4008, -3672, -3365, -3084, -2826, -2590, -2373, + -2175, -1993, -1826, -1673, -1534, -1405, -1288, -1180, + -1081, -991, -908, -832, -763, -699, -640, -587, + -538, -493, -452, -414, -379, -348, -318, -292, + -267, -245, -225, -206, -189, -173, -158, -145, + -133, -122, -112, -102, -94, -86, -79, -72, + -66, -61, -56, -51, -47, -43, -42, -41, + -40, -39, -38, -37, -36, -35, -34, -33, + -32, -31, -30, -29, -28, -27, -26, -25, + -24, -23, -22, -21, -20, -19, -18, -17, + -16, -15, -14, -13, -12, -11, -10, -9, + -8, -7, -6, -5, -4, -3, -2, -1 + +}; + +static int sol_table_old[16] = + { 0x0, 0x1, 0x2 , 0x3, 0x6, 0xA, 0xF, 0x15, + -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0}; + +static int sol_table_new[16] = + { 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15, + 0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15}; + +static int sol_table_16[128] = { + 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, + 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, + 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, + 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, + 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280, + 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0, + 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, + 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, + 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0, + 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480, + 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, + 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00, + 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 +}; + + + +static int dpcm_decode_init(AVCodecContext *avctx) +{ + DPCMContext *s = avctx->priv_data; + int i; + short square; + + s->channels = avctx->channels; + s->sample[0] = s->sample[1] = 0; + + switch(avctx->codec->id) { + + case CODEC_ID_ROQ_DPCM: + /* initialize square table */ + for (i = 0; i < 128; i++) { + square = i * i; + s->roq_square_array[i] = square; + s->roq_square_array[i + 128] = -square; + } + break; + + + case CODEC_ID_SOL_DPCM: + switch(avctx->codec_tag){ + case 1: + s->sol_table=sol_table_old; + s->sample[0] = s->sample[1] = 0x80; + break; + case 2: + s->sol_table=sol_table_new; + s->sample[0] = s->sample[1] = 0x80; + break; + case 3: + s->sol_table=sol_table_16; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n"); + return -1; + } + break; + + default: + break; + } + + return 0; +} + +static int dpcm_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + DPCMContext *s = avctx->priv_data; + int in, out = 0; + int predictor[2]; + int channel_number = 0; + short *output_samples = data; + int shift[2]; + unsigned char byte; + short diff; + + if (!buf_size) + return 0; + + switch(avctx->codec->id) { + + case CODEC_ID_ROQ_DPCM: + if (s->channels == 1) + predictor[0] = LE_16(&buf[6]); + else { + predictor[0] = buf[7] << 8; + predictor[1] = buf[6] << 8; + } + SE_16BIT(predictor[0]); + SE_16BIT(predictor[1]); + + /* decode the samples */ + for (in = 8, out = 0; in < buf_size; in++, out++) { + predictor[channel_number] += s->roq_square_array[buf[in]]; + SATURATE_S16(predictor[channel_number]); + output_samples[out] = predictor[channel_number]; + + /* toggle channel */ + channel_number ^= s->channels - 1; + } + break; + + case CODEC_ID_INTERPLAY_DPCM: + in = 6; /* skip over the stream mask and stream length */ + predictor[0] = LE_16(&buf[in]); + in += 2; + SE_16BIT(predictor[0]) + output_samples[out++] = predictor[0]; + if (s->channels == 2) { + predictor[1] = LE_16(&buf[in]); + in += 2; + SE_16BIT(predictor[1]) + output_samples[out++] = predictor[1]; + } + + while (in < buf_size) { + predictor[channel_number] += interplay_delta_table[buf[in++]]; + SATURATE_S16(predictor[channel_number]); + output_samples[out++] = predictor[channel_number]; + + /* toggle channel */ + channel_number ^= s->channels - 1; + } + + break; + + case CODEC_ID_XAN_DPCM: + in = 0; + shift[0] = shift[1] = 4; + predictor[0] = LE_16(&buf[in]); + in += 2; + SE_16BIT(predictor[0]); + if (s->channels == 2) { + predictor[1] = LE_16(&buf[in]); + in += 2; + SE_16BIT(predictor[1]); + } + + while (in < buf_size) { + byte = buf[in++]; + diff = (byte & 0xFC) << 8; + if ((byte & 0x03) == 3) + shift[channel_number]++; + else + shift[channel_number] -= (2 * (byte & 3)); + /* saturate the shifter to a lower limit of 0 */ + if (shift[channel_number] < 0) + shift[channel_number] = 0; + + diff >>= shift[channel_number]; + predictor[channel_number] += diff; + + SATURATE_S16(predictor[channel_number]); + output_samples[out++] = predictor[channel_number]; + + /* toggle channel */ + channel_number ^= s->channels - 1; + } + break; + case CODEC_ID_SOL_DPCM: + in = 0; + if (avctx->codec_tag != 3) { + while (in < buf_size) { + int n1, n2; + n1 = (buf[in] >> 4) & 0xF; + n2 = buf[in++] & 0xF; + s->sample[0] += s->sol_table[n1]; + if (s->sample[0] < 0) s->sample[0] = 0; + if (s->sample[0] > 255) s->sample[0] = 255; + output_samples[out++] = (s->sample[0] - 128) << 8; + s->sample[s->channels - 1] += s->sol_table[n2]; + if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0; + if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255; + output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8; + } + } else { + while (in < buf_size) { + int n; + n = buf[in++]; + if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F]; + else s->sample[channel_number] += s->sol_table[n & 0x7F]; + SATURATE_S16(s->sample[channel_number]); + output_samples[out++] = s->sample[channel_number]; + /* toggle channel */ + channel_number ^= s->channels - 1; + } + } + break; + } + + *data_size = out * sizeof(short); + return buf_size; +} + +AVCodec roq_dpcm_decoder = { + "roq_dpcm", + CODEC_TYPE_AUDIO, + CODEC_ID_ROQ_DPCM, + sizeof(DPCMContext), + dpcm_decode_init, + NULL, + NULL, + dpcm_decode_frame, +}; + +AVCodec interplay_dpcm_decoder = { + "interplay_dpcm", + CODEC_TYPE_AUDIO, + CODEC_ID_INTERPLAY_DPCM, + sizeof(DPCMContext), + dpcm_decode_init, + NULL, + NULL, + dpcm_decode_frame, +}; + +AVCodec xan_dpcm_decoder = { + "xan_dpcm", + CODEC_TYPE_AUDIO, + CODEC_ID_XAN_DPCM, + sizeof(DPCMContext), + dpcm_decode_init, + NULL, + NULL, + dpcm_decode_frame, +}; + +AVCodec sol_dpcm_decoder = { + "sol_dpcm", + CODEC_TYPE_AUDIO, + CODEC_ID_SOL_DPCM, + sizeof(DPCMContext), + dpcm_decode_init, + NULL, + NULL, + dpcm_decode_frame, +}; diff --git a/mpeg4/src/libavcodec/dsputil.c b/mpeg4/src/libavcodec/dsputil.c new file mode 100644 index 00000000..ad1bfd48 --- /dev/null +++ b/mpeg4/src/libavcodec/dsputil.c @@ -0,0 +1,4116 @@ +/* + * DSP utils + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer + */ + +/** + * @file dsputil.c + * DSP utils + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "simple_idct.h" +#include "faandct.h" +#include "snow.h" + +/* snow.c */ +void ff_spatial_dwt(int *buffer, int width, int height, int stride, int type, int decomposition_count); + +uint8_t cropTbl[256 + 2 * MAX_NEG_CROP] = {0, }; +uint32_t squareTbl[512] = {0, }; + +const uint8_t ff_zigzag_direct[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 +}; + +/* Specific zigzag scan for 248 idct. NOTE that unlike the + specification, we interleave the fields */ +const uint8_t ff_zigzag248_direct[64] = { + 0, 8, 1, 9, 16, 24, 2, 10, + 17, 25, 32, 40, 48, 56, 33, 41, + 18, 26, 3, 11, 4, 12, 19, 27, + 34, 42, 49, 57, 50, 58, 35, 43, + 20, 28, 5, 13, 6, 14, 21, 29, + 36, 44, 51, 59, 52, 60, 37, 45, + 22, 30, 7, 15, 23, 31, 38, 46, + 53, 61, 54, 62, 39, 47, 55, 63, +}; + +/* not permutated inverse zigzag_direct + 1 for MMX quantizer */ +DECLARE_ALIGNED_8(uint16_t, inv_zigzag_direct16[64]) = {0, }; + +const uint8_t ff_alternate_horizontal_scan[64] = { + 0, 1, 2, 3, 8, 9, 16, 17, + 10, 11, 4, 5, 6, 7, 15, 14, + 13, 12, 19, 18, 24, 25, 32, 33, + 26, 27, 20, 21, 22, 23, 28, 29, + 30, 31, 34, 35, 40, 41, 48, 49, + 42, 43, 36, 37, 38, 39, 44, 45, + 46, 47, 50, 51, 56, 57, 58, 59, + 52, 53, 54, 55, 60, 61, 62, 63, +}; + +const uint8_t ff_alternate_vertical_scan[64] = { + 0, 8, 16, 24, 1, 9, 2, 10, + 17, 25, 32, 40, 48, 56, 57, 49, + 41, 33, 26, 18, 3, 11, 4, 12, + 19, 27, 34, 42, 50, 58, 35, 43, + 51, 59, 20, 28, 5, 13, 6, 14, + 21, 29, 36, 44, 52, 60, 37, 45, + 53, 61, 22, 30, 7, 15, 23, 31, + 38, 46, 54, 62, 39, 47, 55, 63, +}; + +/* a*inverse[b]>>32 == a/b for all 0<=a<=65536 && 2<=b<=255 */ +const uint32_t inverse[256]={ + 0, 4294967295U,2147483648U,1431655766, 1073741824, 858993460, 715827883, 613566757, + 536870912, 477218589, 429496730, 390451573, 357913942, 330382100, 306783379, 286331154, + 268435456, 252645136, 238609295, 226050911, 214748365, 204522253, 195225787, 186737709, + 178956971, 171798692, 165191050, 159072863, 153391690, 148102321, 143165577, 138547333, + 134217728, 130150525, 126322568, 122713352, 119304648, 116080198, 113025456, 110127367, + 107374183, 104755300, 102261127, 99882961, 97612894, 95443718, 93368855, 91382283, + 89478486, 87652394, 85899346, 84215046, 82595525, 81037119, 79536432, 78090315, + 76695845, 75350304, 74051161, 72796056, 71582789, 70409300, 69273667, 68174085, + 67108864, 66076420, 65075263, 64103990, 63161284, 62245903, 61356676, 60492498, + 59652324, 58835169, 58040099, 57266231, 56512728, 55778797, 55063684, 54366675, + 53687092, 53024288, 52377650, 51746594, 51130564, 50529028, 49941481, 49367441, + 48806447, 48258060, 47721859, 47197443, 46684428, 46182445, 45691142, 45210183, + 44739243, 44278014, 43826197, 43383509, 42949673, 42524429, 42107523, 41698712, + 41297763, 40904451, 40518560, 40139882, 39768216, 39403370, 39045158, 38693400, + 38347923, 38008561, 37675152, 37347542, 37025581, 36709123, 36398028, 36092163, + 35791395, 35495598, 35204650, 34918434, 34636834, 34359739, 34087043, 33818641, + 33554432, 33294321, 33038210, 32786010, 32537632, 32292988, 32051995, 31814573, + 31580642, 31350127, 31122952, 30899046, 30678338, 30460761, 30246249, 30034737, + 29826162, 29620465, 29417585, 29217465, 29020050, 28825284, 28633116, 28443493, + 28256364, 28071682, 27889399, 27709467, 27531842, 27356480, 27183338, 27012373, + 26843546, 26676816, 26512144, 26349493, 26188825, 26030105, 25873297, 25718368, + 25565282, 25414008, 25264514, 25116768, 24970741, 24826401, 24683721, 24542671, + 24403224, 24265352, 24129030, 23994231, 23860930, 23729102, 23598722, 23469767, + 23342214, 23216040, 23091223, 22967740, 22845571, 22724695, 22605092, 22486740, + 22369622, 22253717, 22139007, 22025474, 21913099, 21801865, 21691755, 21582751, + 21474837, 21367997, 21262215, 21157475, 21053762, 20951060, 20849356, 20748635, + 20648882, 20550083, 20452226, 20355296, 20259280, 20164166, 20069941, 19976593, + 19884108, 19792477, 19701685, 19611723, 19522579, 19434242, 19346700, 19259944, + 19173962, 19088744, 19004281, 18920561, 18837576, 18755316, 18673771, 18592933, + 18512791, 18433337, 18354562, 18276457, 18199014, 18122225, 18046082, 17970575, + 17895698, 17821442, 17747799, 17674763, 17602325, 17530479, 17459217, 17388532, + 17318417, 17248865, 17179870, 17111424, 17043522, 16976156, 16909321, 16843010, +}; + +/* Input permutation for the simple_idct_mmx */ +static const uint8_t simple_mmx_permutation[64]={ + 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, + 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, + 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, + 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, + 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, + 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, + 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, + 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, +}; + +static int pix_sum_c(uint8_t * pix, int line_size) +{ + int s, i, j; + + s = 0; + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j += 8) { + s += pix[0]; + s += pix[1]; + s += pix[2]; + s += pix[3]; + s += pix[4]; + s += pix[5]; + s += pix[6]; + s += pix[7]; + pix += 8; + } + pix += line_size - 16; + } + return s; +} + +static int pix_norm1_c(uint8_t * pix, int line_size) +{ + int s, i, j; + uint32_t *sq = squareTbl + 256; + + s = 0; + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j += 8) { +#if 0 + s += sq[pix[0]]; + s += sq[pix[1]]; + s += sq[pix[2]]; + s += sq[pix[3]]; + s += sq[pix[4]]; + s += sq[pix[5]]; + s += sq[pix[6]]; + s += sq[pix[7]]; +#else +#if LONG_MAX > 2147483647 + register uint64_t x=*(uint64_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; + s += sq[(x>>32)&0xff]; + s += sq[(x>>40)&0xff]; + s += sq[(x>>48)&0xff]; + s += sq[(x>>56)&0xff]; +#else + register uint32_t x=*(uint32_t*)pix; + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; + x=*(uint32_t*)(pix+4); + s += sq[x&0xff]; + s += sq[(x>>8)&0xff]; + s += sq[(x>>16)&0xff]; + s += sq[(x>>24)&0xff]; +#endif +#endif + pix += 8; + } + pix += line_size - 16; + } + return s; +} + +static void bswap_buf(uint32_t *dst, uint32_t *src, int w){ + int i; + + for(i=0; i+8<=w; i+=8){ + dst[i+0]= bswap_32(src[i+0]); + dst[i+1]= bswap_32(src[i+1]); + dst[i+2]= bswap_32(src[i+2]); + dst[i+3]= bswap_32(src[i+3]); + dst[i+4]= bswap_32(src[i+4]); + dst[i+5]= bswap_32(src[i+5]); + dst[i+6]= bswap_32(src[i+6]); + dst[i+7]= bswap_32(src[i+7]); + } + for(;i>1 : 0; + int size= 1<=0); + + return s>>2; +#endif +} + +static int w53_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 8, h, 1); +} + +static int w97_8_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 8, h, 0); +} + +static int w53_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 16, h, 1); +} + +static int w97_16_c(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h){ + return w_c(v, pix1, pix2, line_size, 16, h, 0); +} + +static void get_pixels_c(DCTELEM *restrict block, const uint8_t *pixels, int line_size) +{ + int i; + + /* read the pixels */ + for(i=0;i<8;i++) { + block[0] = pixels[0]; + block[1] = pixels[1]; + block[2] = pixels[2]; + block[3] = pixels[3]; + block[4] = pixels[4]; + block[5] = pixels[5]; + block[6] = pixels[6]; + block[7] = pixels[7]; + pixels += line_size; + block += 8; + } +} + +static void diff_pixels_c(DCTELEM *restrict block, const uint8_t *s1, + const uint8_t *s2, int stride){ + int i; + + /* read the pixels */ + for(i=0;i<8;i++) { + block[0] = s1[0] - s2[0]; + block[1] = s1[1] - s2[1]; + block[2] = s1[2] - s2[2]; + block[3] = s1[3] - s2[3]; + block[4] = s1[4] - s2[4]; + block[5] = s1[5] - s2[5]; + block[6] = s1[6] - s2[6]; + block[7] = s1[7] - s2[7]; + s1 += stride; + s2 += stride; + block += 8; + } +} + + +static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<8;i++) { + pixels[0] = cm[block[0]]; + pixels[1] = cm[block[1]]; + pixels[2] = cm[block[2]]; + pixels[3] = cm[block[3]]; + pixels[4] = cm[block[4]]; + pixels[5] = cm[block[5]]; + pixels[6] = cm[block[6]]; + pixels[7] = cm[block[7]]; + + pixels += line_size; + block += 8; + } +} + +static void put_pixels_clamped4_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<4;i++) { + pixels[0] = cm[block[0]]; + pixels[1] = cm[block[1]]; + pixels[2] = cm[block[2]]; + pixels[3] = cm[block[3]]; + + pixels += line_size; + block += 8; + } +} + +static void put_pixels_clamped2_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<2;i++) { + pixels[0] = cm[block[0]]; + pixels[1] = cm[block[1]]; + + pixels += line_size; + block += 8; + } +} + +static void put_signed_pixels_clamped_c(const DCTELEM *block, + uint8_t *restrict pixels, + int line_size) +{ + int i, j; + + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + if (*block < -128) + *pixels = 0; + else if (*block > 127) + *pixels = 255; + else + *pixels = (uint8_t)(*block + 128); + block++; + pixels++; + } + pixels += (line_size - 8); + } +} + +static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<8;i++) { + pixels[0] = cm[pixels[0] + block[0]]; + pixels[1] = cm[pixels[1] + block[1]]; + pixels[2] = cm[pixels[2] + block[2]]; + pixels[3] = cm[pixels[3] + block[3]]; + pixels[4] = cm[pixels[4] + block[4]]; + pixels[5] = cm[pixels[5] + block[5]]; + pixels[6] = cm[pixels[6] + block[6]]; + pixels[7] = cm[pixels[7] + block[7]]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels_clamped4_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<4;i++) { + pixels[0] = cm[pixels[0] + block[0]]; + pixels[1] = cm[pixels[1] + block[1]]; + pixels[2] = cm[pixels[2] + block[2]]; + pixels[3] = cm[pixels[3] + block[3]]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels_clamped2_c(const DCTELEM *block, uint8_t *restrict pixels, + int line_size) +{ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + /* read the pixels */ + for(i=0;i<2;i++) { + pixels[0] = cm[pixels[0] + block[0]]; + pixels[1] = cm[pixels[1] + block[1]]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels8_c(uint8_t *restrict pixels, DCTELEM *block, int line_size) +{ + int i; + for(i=0;i<8;i++) { + pixels[0] += block[0]; + pixels[1] += block[1]; + pixels[2] += block[2]; + pixels[3] += block[3]; + pixels[4] += block[4]; + pixels[5] += block[5]; + pixels[6] += block[6]; + pixels[7] += block[7]; + pixels += line_size; + block += 8; + } +} + +static void add_pixels4_c(uint8_t *restrict pixels, DCTELEM *block, int line_size) +{ + int i; + for(i=0;i<4;i++) { + pixels[0] += block[0]; + pixels[1] += block[1]; + pixels[2] += block[2]; + pixels[3] += block[3]; + pixels += line_size; + block += 4; + } +} + +#if 0 + +#define PIXOP2(OPNAME, OP) \ +static void OPNAME ## _pixels(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _pixels_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _no_rnd_pixels_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _pixels_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + for(i=0; i>1));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + const uint64_t a= LD64(pixels );\ + const uint64_t b= LD64(pixels+1);\ + uint64_t l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0202020202020202ULL;\ + uint64_t h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + uint64_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD64(pixels );\ + b= LD64(pixels+1);\ + l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0202020202020202ULL;\ + h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static void OPNAME ## _no_rnd_pixels_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + const uint64_t a= LD64(pixels );\ + const uint64_t b= LD64(pixels+1);\ + uint64_t l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0101010101010101ULL;\ + uint64_t h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + uint64_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD64(pixels );\ + b= LD64(pixels+1);\ + l0= (a&0x0303030303030303ULL)\ + + (b&0x0303030303030303ULL)\ + + 0x0101010101010101ULL;\ + h0= ((a&0xFCFCFCFCFCFCFCFCULL)>>2)\ + + ((b&0xFCFCFCFCFCFCFCFCULL)>>2);\ + OP(*((uint64_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0F0F0F0F0FULL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +CALL_2X_PIXELS(OPNAME ## _pixels16_c , OPNAME ## _pixels_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_x2_c , OPNAME ## _pixels_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_y2_c , OPNAME ## _pixels_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_c, OPNAME ## _pixels_xy2_c, 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_x2_c , OPNAME ## _no_rnd_pixels_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_y2_c , OPNAME ## _no_rnd_pixels_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_c, OPNAME ## _no_rnd_pixels_xy2_c, 8) + +#define op_avg(a, b) a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEFEFEFEFEULL)>>1) ) +#else // 64 bit variant + +#define PIXOP2(OPNAME, OP) \ +static void OPNAME ## _pixels2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + int i;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + a= LD32(&src1[i*src_stride1+4]);\ + b= LD32(&src2[i*src_stride2+4]);\ + c= LD32(&src3[i*src_stride3+4]);\ + d= LD32(&src4[i*src_stride4+4]);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride+4]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + }\ +}\ +\ +static inline void OPNAME ## _pixels4_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels4_l2(block, pixels, pixels+1, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels4_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels4_l2(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels2_x2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels2_l2(block, pixels, pixels+1, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _pixels2_y2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + OPNAME ## _pixels2_l2(block, pixels, pixels+line_size, line_size, line_size, line_size, h);\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels8_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + int i;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + a= LD32(&src1[i*src_stride1+4]);\ + b= LD32(&src2[i*src_stride2+4]);\ + c= LD32(&src3[i*src_stride3+4]);\ + d= LD32(&src4[i*src_stride4+4]);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + l1= (c&0x03030303UL)\ + + (d&0x03030303UL);\ + h1= ((c&0xFCFCFCFCUL)>>2)\ + + ((d&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)&dst[i*dst_stride+4]), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + }\ +}\ +static inline void OPNAME ## _pixels16_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + OPNAME ## _pixels8_l4(dst , src1 , src2 , src3 , src4 , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ + OPNAME ## _pixels8_l4(dst+8, src1+8, src2+8, src3+8, src4+8, dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ +}\ +static inline void OPNAME ## _no_rnd_pixels16_l4(uint8_t *dst, const uint8_t *src1, uint8_t *src2, uint8_t *src3, uint8_t *src4,\ + int dst_stride, int src_stride1, int src_stride2,int src_stride3,int src_stride4, int h){\ + OPNAME ## _no_rnd_pixels8_l4(dst , src1 , src2 , src3 , src4 , dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ + OPNAME ## _no_rnd_pixels8_l4(dst+8, src1+8, src2+8, src3+8, src4+8, dst_stride, src_stride1, src_stride2, src_stride3, src_stride4, h);\ +}\ +\ +static inline void OPNAME ## _pixels2_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i, a0, b0, a1, b1;\ + a0= pixels[0];\ + b0= pixels[1] + 2;\ + a0 += b0;\ + b0 += pixels[2];\ +\ + pixels+=line_size;\ + for(i=0; i>2; /* FIXME non put */\ + block[1]= (b1+b0)>>2;\ +\ + pixels+=line_size;\ + block +=line_size;\ +\ + a0= pixels[0];\ + b0= pixels[1] + 2;\ + a0 += b0;\ + b0 += pixels[2];\ +\ + block[0]= (a1+a0)>>2;\ + block[1]= (b1+b0)>>2;\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static inline void OPNAME ## _pixels4_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int i;\ + const uint32_t a= LD32(pixels );\ + const uint32_t b= LD32(pixels+1);\ + uint32_t l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + uint32_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD32(pixels );\ + b= LD32(pixels+1);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ +}\ +\ +static inline void OPNAME ## _pixels8_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int j;\ + for(j=0; j<2; j++){\ + int i;\ + const uint32_t a= LD32(pixels );\ + const uint32_t b= LD32(pixels+1);\ + uint32_t l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + uint32_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD32(pixels );\ + b= LD32(pixels+1);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x02020202UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ + pixels+=4-line_size*(h+1);\ + block +=4-line_size*h;\ + }\ +}\ +\ +static inline void OPNAME ## _no_rnd_pixels8_xy2_c(uint8_t *block, const uint8_t *pixels, int line_size, int h)\ +{\ + int j;\ + for(j=0; j<2; j++){\ + int i;\ + const uint32_t a= LD32(pixels );\ + const uint32_t b= LD32(pixels+1);\ + uint32_t l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + uint32_t h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + uint32_t l1,h1;\ +\ + pixels+=line_size;\ + for(i=0; i>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + a= LD32(pixels );\ + b= LD32(pixels+1);\ + l0= (a&0x03030303UL)\ + + (b&0x03030303UL)\ + + 0x01010101UL;\ + h0= ((a&0xFCFCFCFCUL)>>2)\ + + ((b&0xFCFCFCFCUL)>>2);\ + OP(*((uint32_t*)block), h0+h1+(((l0+l1)>>2)&0x0F0F0F0FUL));\ + pixels+=line_size;\ + block +=line_size;\ + }\ + pixels+=4-line_size*(h+1);\ + block +=4-line_size*h;\ + }\ +}\ +\ +CALL_2X_PIXELS(OPNAME ## _pixels16_c , OPNAME ## _pixels8_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_x2_c , OPNAME ## _pixels8_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_y2_c , OPNAME ## _pixels8_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_c, OPNAME ## _pixels8_xy2_c, 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_c , OPNAME ## _pixels8_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_x2_c , OPNAME ## _no_rnd_pixels8_x2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_y2_c , OPNAME ## _no_rnd_pixels8_y2_c , 8)\ +CALL_2X_PIXELS(OPNAME ## _no_rnd_pixels16_xy2_c, OPNAME ## _no_rnd_pixels8_xy2_c, 8)\ + +#define op_avg(a, b) a = rnd_avg32(a, b) +#endif +#define op_put(a, b) a = b + +PIXOP2(avg, op_avg) +PIXOP2(put, op_put) +#undef op_avg +#undef op_put + +#define avg2(a,b) ((a+b+1)>>1) +#define avg4(a,b,c,d) ((a+b+c+d+2)>>2) + +static void put_no_rnd_pixels16_l2_c(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){ + put_no_rnd_pixels16_l2(dst, a, b, stride, stride, stride, h); +} + +static void put_no_rnd_pixels8_l2_c(uint8_t *dst, const uint8_t *a, const uint8_t *b, int stride, int h){ + put_no_rnd_pixels8_l2(dst, a, b, stride, stride, stride, h); +} + +static void gmc1_c(uint8_t *dst, uint8_t *src, int stride, int h, int x16, int y16, int rounder) +{ + const int A=(16-x16)*(16-y16); + const int B=( x16)*(16-y16); + const int C=(16-x16)*( y16); + const int D=( x16)*( y16); + int i; + + for(i=0; i>8; + dst[1]= (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + rounder)>>8; + dst[2]= (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + rounder)>>8; + dst[3]= (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + rounder)>>8; + dst[4]= (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + rounder)>>8; + dst[5]= (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + rounder)>>8; + dst[6]= (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + rounder)>>8; + dst[7]= (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + rounder)>>8; + dst+= stride; + src+= stride; + } +} + +void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height) +{ + int y, vx, vy; + const int s= 1<>16; + src_y= vy>>16; + frac_x= src_x&(s-1); + frac_y= src_y&(s-1); + src_x>>=shift; + src_y>>=shift; + + if((unsigned)src_x < width){ + if((unsigned)src_y < height){ + index= src_x + src_y*stride; + dst[y*stride + x]= ( ( src[index ]*(s-frac_x) + + src[index +1]* frac_x )*(s-frac_y) + + ( src[index+stride ]*(s-frac_x) + + src[index+stride+1]* frac_x )* frac_y + + r)>>(shift*2); + }else{ + index= src_x + clip(src_y, 0, height)*stride; + dst[y*stride + x]= ( ( src[index ]*(s-frac_x) + + src[index +1]* frac_x )*s + + r)>>(shift*2); + } + }else{ + if((unsigned)src_y < height){ + index= clip(src_x, 0, width) + src_y*stride; + dst[y*stride + x]= ( ( src[index ]*(s-frac_y) + + src[index+stride ]* frac_y )*s + + r)>>(shift*2); + }else{ + index= clip(src_x, 0, width) + clip(src_y, 0, height)*stride; + dst[y*stride + x]= src[index ]; + } + } + + vx+= dxx; + vy+= dyx; + } + ox += dxy; + oy += dyy; + } +} + +static inline void put_tpel_pixels_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + switch(width){ + case 2: put_pixels2_c (dst, src, stride, height); break; + case 4: put_pixels4_c (dst, src, stride, height); break; + case 8: put_pixels8_c (dst, src, stride, height); break; + case 16:put_pixels16_c(dst, src, stride, height); break; + } +} + +static inline void put_tpel_pixels_mc10_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (683*(2*src[j] + src[j+1] + 1)) >> 11; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc20_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (683*(src[j] + 2*src[j+1] + 1)) >> 11; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (683*(2*src[j] + src[j+stride] + 1)) >> 11; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc12_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc02_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (683*(src[j] + 2*src[j+stride] + 1)) >> 11; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc21_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15; + } + src += stride; + dst += stride; + } +} + +static inline void put_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc00_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + switch(width){ + case 2: avg_pixels2_c (dst, src, stride, height); break; + case 4: avg_pixels4_c (dst, src, stride, height); break; + case 8: avg_pixels8_c (dst, src, stride, height); break; + case 16:avg_pixels16_c(dst, src, stride, height); break; + } +} + +static inline void avg_tpel_pixels_mc10_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((683*(2*src[j] + src[j+1] + 1)) >> 11) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc20_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+1] + 1)) >> 11) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc01_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((683*(2*src[j] + src[j+stride] + 1)) >> 11) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc11_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((2731*(4*src[j] + 3*src[j+1] + 3*src[j+stride] + 2*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc12_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((2731*(3*src[j] + 2*src[j+1] + 4*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc02_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((683*(src[j] + 2*src[j+stride] + 1)) >> 11) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc21_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((2731*(3*src[j] + 4*src[j+1] + 2*src[j+stride] + 3*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + } + src += stride; + dst += stride; + } +} + +static inline void avg_tpel_pixels_mc22_c(uint8_t *dst, const uint8_t *src, int stride, int width, int height){ + int i,j; + for (i=0; i < height; i++) { + for (j=0; j < width; j++) { + dst[j] = (dst[j] + ((2731*(2*src[j] + 3*src[j+1] + 3*src[j+stride] + 4*src[j+stride+1] + 6)) >> 15) + 1) >> 1; + } + src += stride; + dst += stride; + } +} +#if 0 +#define TPEL_WIDTH(width)\ +static void put_tpel_pixels ## width ## _mc00_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc00_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc10_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc10_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc20_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc20_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc01_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc01_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc11_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc11_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc21_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc21_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc02_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc02_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc12_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc12_c(dst, src, stride, width, height);}\ +static void put_tpel_pixels ## width ## _mc22_c(uint8_t *dst, const uint8_t *src, int stride, int height){\ + void put_tpel_pixels_mc22_c(dst, src, stride, width, height);} +#endif + +#define H264_CHROMA_MC(OPNAME, OP)\ +static void OPNAME ## h264_chroma_mc2_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\ + const int A=(8-x)*(8-y);\ + const int B=( x)*(8-y);\ + const int C=(8-x)*( y);\ + const int D=( x)*( y);\ + int i;\ + \ + assert(x<8 && y<8 && x>=0 && y>=0);\ +\ + for(i=0; i=0 && y>=0);\ +\ + for(i=0; i=0 && y>=0);\ +\ + for(i=0; i>6)+1)>>1) +#define op_put(a, b) a = (((b) + 32)>>6) + +H264_CHROMA_MC(put_ , op_put) +H264_CHROMA_MC(avg_ , op_avg) +#undef op_avg +#undef op_put + +static inline void copy_block2(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h) +{ + int i; + for(i=0; i>5]+1)>>1) +#define op_avg_no_rnd(a, b) a = (((a)+cm[((b) + 15)>>5])>>1) +#define op_put(a, b) a = cm[((b) + 16)>>5] +#define op_put_no_rnd(a, b) a = cm[((b) + 15)>>5] + +QPEL_MC(0, put_ , _ , op_put) +QPEL_MC(1, put_no_rnd_, _no_rnd_, op_put_no_rnd) +QPEL_MC(0, avg_ , _ , op_avg) +//QPEL_MC(1, avg_no_rnd , _ , op_avg) +#undef op_avg +#undef op_avg_no_rnd +#undef op_put +#undef op_put_no_rnd + +#if 1 +#define H264_LOWPASS(OPNAME, OP, OP2) \ +static void OPNAME ## h264_qpel2_h_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + const int h=2;\ + uint8_t *cm = cropTbl + MAX_NEG_CROP;\ + int i;\ + for(i=0; i>5]+1)>>1) +//#define op_avg2(a, b) a = (((a)*w1+cm[((b) + 16)>>5]*w2 + o + 64)>>7) +#define op_put(a, b) a = cm[((b) + 16)>>5] +#define op2_avg(a, b) a = (((a)+cm[((b) + 512)>>10]+1)>>1) +#define op2_put(a, b) a = cm[((b) + 512)>>10] + +H264_LOWPASS(put_ , op_put, op2_put) +H264_LOWPASS(avg_ , op_avg, op2_avg) +H264_MC(put_, 2) +H264_MC(put_, 4) +H264_MC(put_, 8) +H264_MC(put_, 16) +H264_MC(avg_, 4) +H264_MC(avg_, 8) +H264_MC(avg_, 16) + +#undef op_avg +#undef op_put +#undef op2_avg +#undef op2_put +#endif + +#define op_scale1(x) block[x] = clip_uint8( (block[x]*weight + offset) >> log2_denom ) +#define op_scale2(x) dst[x] = clip_uint8( (src[x]*weights + dst[x]*weightd + offset) >> (log2_denom+1)) +#define H264_WEIGHT(W,H) \ +static void weight_h264_pixels ## W ## x ## H ## _c(uint8_t *block, int stride, int log2_denom, int weight, int offset){ \ + int y; \ + offset <<= log2_denom; \ + if(log2_denom) offset += 1<<(log2_denom-1); \ + for(y=0; y>4]; + dst[1]= cm[(9*(src[1] + src[2]) - (src[ 0] + src[3]) + 8)>>4]; + dst[2]= cm[(9*(src[2] + src[3]) - (src[ 1] + src[4]) + 8)>>4]; + dst[3]= cm[(9*(src[3] + src[4]) - (src[ 2] + src[5]) + 8)>>4]; + dst[4]= cm[(9*(src[4] + src[5]) - (src[ 3] + src[6]) + 8)>>4]; + dst[5]= cm[(9*(src[5] + src[6]) - (src[ 4] + src[7]) + 8)>>4]; + dst[6]= cm[(9*(src[6] + src[7]) - (src[ 5] + src[8]) + 8)>>4]; + dst[7]= cm[(9*(src[7] + src[8]) - (src[ 6] + src[9]) + 8)>>4]; + dst+=dstStride; + src+=srcStride; + } +} + +static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w){ + uint8_t *cm = cropTbl + MAX_NEG_CROP; + int i; + + for(i=0; i>4]; + dst[1*dstStride]= cm[(9*(src1 + src2) - (src0 + src3) + 8)>>4]; + dst[2*dstStride]= cm[(9*(src2 + src3) - (src1 + src4) + 8)>>4]; + dst[3*dstStride]= cm[(9*(src3 + src4) - (src2 + src5) + 8)>>4]; + dst[4*dstStride]= cm[(9*(src4 + src5) - (src3 + src6) + 8)>>4]; + dst[5*dstStride]= cm[(9*(src5 + src6) - (src4 + src7) + 8)>>4]; + dst[6*dstStride]= cm[(9*(src6 + src7) - (src5 + src8) + 8)>>4]; + dst[7*dstStride]= cm[(9*(src7 + src8) - (src6 + src9) + 8)>>4]; + src++; + dst++; + } +} + +static void put_mspel8_mc00_c (uint8_t *dst, uint8_t *src, int stride){ + put_pixels8_c(dst, src, stride, 8); +} + +static void put_mspel8_mc10_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t half[64]; + wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); + put_pixels8_l2(dst, src, half, stride, stride, 8, 8); +} + +static void put_mspel8_mc20_c(uint8_t *dst, uint8_t *src, int stride){ + wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8); +} + +static void put_mspel8_mc30_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t half[64]; + wmv2_mspel8_h_lowpass(half, src, 8, stride, 8); + put_pixels8_l2(dst, src+1, half, stride, stride, 8, 8); +} + +static void put_mspel8_mc02_c(uint8_t *dst, uint8_t *src, int stride){ + wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8); +} + +static void put_mspel8_mc12_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t halfH[88]; + uint8_t halfV[64]; + uint8_t halfHV[64]; + wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); + wmv2_mspel8_v_lowpass(halfV, src, 8, stride, 8); + wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8); + put_pixels8_l2(dst, halfV, halfHV, stride, 8, 8, 8); +} +static void put_mspel8_mc32_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t halfH[88]; + uint8_t halfV[64]; + uint8_t halfHV[64]; + wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); + wmv2_mspel8_v_lowpass(halfV, src+1, 8, stride, 8); + wmv2_mspel8_v_lowpass(halfHV, halfH+8, 8, 8, 8); + put_pixels8_l2(dst, halfV, halfHV, stride, 8, 8, 8); +} +static void put_mspel8_mc22_c(uint8_t *dst, uint8_t *src, int stride){ + uint8_t halfH[88]; + wmv2_mspel8_h_lowpass(halfH, src-stride, 8, stride, 11); + wmv2_mspel8_v_lowpass(dst, halfH+8, stride, 8, 8); +} + +static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale){ + int x; + const int strength= ff_h263_loop_filter_strength[qscale]; + + for(x=0; x<8; x++){ + int d1, d2, ad1; + int p0= src[x-2*stride]; + int p1= src[x-1*stride]; + int p2= src[x+0*stride]; + int p3= src[x+1*stride]; + int d = (p0 - p3 + 4*(p2 - p1)) / 8; + + if (d<-2*strength) d1= 0; + else if(d<- strength) d1=-2*strength - d; + else if(d< strength) d1= d; + else if(d< 2*strength) d1= 2*strength - d; + else d1= 0; + + p1 += d1; + p2 -= d1; + if(p1&256) p1= ~(p1>>31); + if(p2&256) p2= ~(p2>>31); + + src[x-1*stride] = p1; + src[x+0*stride] = p2; + + ad1= ABS(d1)>>1; + + d2= clip((p0-p3)/4, -ad1, ad1); + + src[x-2*stride] = p0 - d2; + src[x+ stride] = p3 + d2; + } +} + +static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){ + int y; + const int strength= ff_h263_loop_filter_strength[qscale]; + + for(y=0; y<8; y++){ + int d1, d2, ad1; + int p0= src[y*stride-2]; + int p1= src[y*stride-1]; + int p2= src[y*stride+0]; + int p3= src[y*stride+1]; + int d = (p0 - p3 + 4*(p2 - p1)) / 8; + + if (d<-2*strength) d1= 0; + else if(d<- strength) d1=-2*strength - d; + else if(d< strength) d1= d; + else if(d< 2*strength) d1= 2*strength - d; + else d1= 0; + + p1 += d1; + p2 -= d1; + if(p1&256) p1= ~(p1>>31); + if(p2&256) p2= ~(p2>>31); + + src[y*stride-1] = p1; + src[y*stride+0] = p2; + + ad1= ABS(d1)>>1; + + d2= clip((p0-p3)/4, -ad1, ad1); + + src[y*stride-2] = p0 - d2; + src[y*stride+1] = p3 + d2; + } +} + +static void h261_loop_filter_c(uint8_t *src, int stride){ + int x,y,xy,yz; + int temp[64]; + + for(x=0; x<8; x++){ + temp[x ] = 4*src[x ]; + temp[x + 7*8] = 4*src[x + 7*stride]; + } + for(y=1; y<7; y++){ + for(x=0; x<8; x++){ + xy = y * stride + x; + yz = y * 8 + x; + temp[yz] = src[xy - stride] + 2*src[xy] + src[xy + stride]; + } + } + + for(y=0; y<8; y++){ + src[ y*stride] = (temp[ y*8] + 2)>>2; + src[7+y*stride] = (temp[7+y*8] + 2)>>2; + for(x=1; x<7; x++){ + xy = y * stride + x; + yz = y * 8 + x; + src[xy] = (temp[yz-1] + 2*temp[yz] + temp[yz+1] + 8)>>4; + } + } +} + +static inline void h264_loop_filter_luma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) +{ + int i, d; + for( i = 0; i < 4; i++ ) { + if( tc0[i] < 0 ) { + pix += 4*ystride; + continue; + } + for( d = 0; d < 4; d++ ) { + const int p0 = pix[-1*xstride]; + const int p1 = pix[-2*xstride]; + const int p2 = pix[-3*xstride]; + const int q0 = pix[0]; + const int q1 = pix[1*xstride]; + const int q2 = pix[2*xstride]; + + if( ABS( p0 - q0 ) < alpha && + ABS( p1 - p0 ) < beta && + ABS( q1 - q0 ) < beta ) { + + int tc = tc0[i]; + int i_delta; + + if( ABS( p2 - p0 ) < beta ) { + pix[-2*xstride] = p1 + clip( (( p2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - p1, -tc0[i], tc0[i] ); + tc++; + } + if( ABS( q2 - q0 ) < beta ) { + pix[ xstride] = q1 + clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - q1, -tc0[i], tc0[i] ); + tc++; + } + + i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); + pix[-xstride] = clip_uint8( p0 + i_delta ); /* p0' */ + pix[0] = clip_uint8( q0 - i_delta ); /* q0' */ + } + pix += ystride; + } + } +} +static void h264_v_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_luma_c(pix, stride, 1, alpha, beta, tc0); +} +static void h264_h_loop_filter_luma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_luma_c(pix, 1, stride, alpha, beta, tc0); +} + +static inline void h264_loop_filter_chroma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0) +{ + int i, d; + for( i = 0; i < 4; i++ ) { + const int tc = tc0[i]; + if( tc <= 0 ) { + pix += 2*ystride; + continue; + } + for( d = 0; d < 2; d++ ) { + const int p0 = pix[-1*xstride]; + const int p1 = pix[-2*xstride]; + const int q0 = pix[0]; + const int q1 = pix[1*xstride]; + + if( ABS( p0 - q0 ) < alpha && + ABS( p1 - p0 ) < beta && + ABS( q1 - q0 ) < beta ) { + + int delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); + + pix[-xstride] = clip_uint8( p0 + delta ); /* p0' */ + pix[0] = clip_uint8( q0 - delta ); /* q0' */ + } + pix += ystride; + } + } +} +static void h264_v_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_chroma_c(pix, stride, 1, alpha, beta, tc0); +} +static void h264_h_loop_filter_chroma_c(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_chroma_c(pix, 1, stride, alpha, beta, tc0); +} + +static inline void h264_loop_filter_chroma_intra_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta) +{ + int d; + for( d = 0; d < 8; d++ ) { + const int p0 = pix[-1*xstride]; + const int p1 = pix[-2*xstride]; + const int q0 = pix[0]; + const int q1 = pix[1*xstride]; + + if( ABS( p0 - q0 ) < alpha && + ABS( p1 - p0 ) < beta && + ABS( q1 - q0 ) < beta ) { + + pix[-xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */ + pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */ + } + pix += ystride; + } +} +static void h264_v_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta) +{ + h264_loop_filter_chroma_intra_c(pix, stride, 1, alpha, beta); +} +static void h264_h_loop_filter_chroma_intra_c(uint8_t *pix, int stride, int alpha, int beta) +{ + h264_loop_filter_chroma_intra_c(pix, 1, stride, alpha, beta); +} + +static inline int pix_abs16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) +{ + int s, i; + + s = 0; + for(i=0;iavctx->nsse_weight; + else return score1 + ABS(score2)*8; +} + +static int nsse8_c(void *v, uint8_t *s1, uint8_t *s2, int stride, int h){ + MpegEncContext *c = v; + int score1=0; + int score2=0; + int x,y; + + for(y=0; yavctx->nsse_weight; + else return score1 + ABS(score2)*8; +} + +static int try_8x8basis_c(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale){ + int i; + unsigned int sum=0; + + for(i=0; i<8*8; i++){ + int b= rem[i] + ((basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT)); + int w= weight[i]; + b>>= RECON_SHIFT; + assert(-512>4; + } + return sum>>2; +} + +static void add_8x8basis_c(int16_t rem[64], int16_t basis[64], int scale){ + int i; + + for(i=0; i<8*8; i++){ + rem[i] += (basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT); + } +} + +/** + * permutes an 8x8 block. + * @param block the block which will be permuted according to the given permutation vector + * @param permutation the permutation vector + * @param last the last non zero coefficient in scantable order, used to speed the permutation up + * @param scantable the used scantable, this is only used to speed the permutation up, the block is not + * (inverse) permutated to scantable order! + */ +void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last) +{ + int i; + DCTELEM temp[64]; + + if(last<=0) return; + //if(permutation[1]==1) return; //FIXME its ok but not clean and might fail for some perms + + for(i=0; i<=last; i++){ + const int j= scantable[i]; + temp[j]= block[j]; + block[j]=0; + } + + for(i=0; i<=last; i++){ + const int j= scantable[i]; + const int perm_j= permutation[j]; + block[perm_j]= temp[j]; + } +} + +static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){ + return 0; +} + +void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){ + int i; + + memset(cmp, 0, sizeof(void*)*5); + + for(i=0; i<5; i++){ + switch(type&0xFF){ + case FF_CMP_SAD: + cmp[i]= c->sad[i]; + break; + case FF_CMP_SATD: + cmp[i]= c->hadamard8_diff[i]; + break; + case FF_CMP_SSE: + cmp[i]= c->sse[i]; + break; + case FF_CMP_DCT: + cmp[i]= c->dct_sad[i]; + break; + case FF_CMP_DCT264: + cmp[i]= c->dct264_sad[i]; + break; + case FF_CMP_DCTMAX: + cmp[i]= c->dct_max[i]; + break; + case FF_CMP_PSNR: + cmp[i]= c->quant_psnr[i]; + break; + case FF_CMP_BIT: + cmp[i]= c->bit[i]; + break; + case FF_CMP_RD: + cmp[i]= c->rd[i]; + break; + case FF_CMP_VSAD: + cmp[i]= c->vsad[i]; + break; + case FF_CMP_VSSE: + cmp[i]= c->vsse[i]; + break; + case FF_CMP_ZERO: + cmp[i]= zero_cmp; + break; + case FF_CMP_NSSE: + cmp[i]= c->nsse[i]; + break; + case FF_CMP_W53: + cmp[i]= c->w53[i]; + break; + case FF_CMP_W97: + cmp[i]= c->w97[i]; + break; + default: + av_log(NULL, AV_LOG_ERROR,"internal error in cmp function selection\n"); + } + } +} + +/** + * memset(blocks, 0, sizeof(DCTELEM)*6*64) + */ +static void clear_blocks_c(DCTELEM *blocks) +{ + memset(blocks, 0, sizeof(DCTELEM)*6*64); +} + +static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){ + int i; + for(i=0; i+7maxi){ + maxi=sum; + printf("MAX:%d\n", maxi); +} +#endif + return sum; +} + +static int hadamard8_intra8x8_c(/*MpegEncContext*/ void *s, uint8_t *src, uint8_t *dummy, int stride, int h){ + int i; + int temp[64]; + int sum=0; + + assert(h==8); + + for(i=0; i<8; i++){ + //FIXME try pointer walks + BUTTERFLY2(temp[8*i+0], temp[8*i+1], src[stride*i+0],src[stride*i+1]); + BUTTERFLY2(temp[8*i+2], temp[8*i+3], src[stride*i+2],src[stride*i+3]); + BUTTERFLY2(temp[8*i+4], temp[8*i+5], src[stride*i+4],src[stride*i+5]); + BUTTERFLY2(temp[8*i+6], temp[8*i+7], src[stride*i+6],src[stride*i+7]); + + BUTTERFLY1(temp[8*i+0], temp[8*i+2]); + BUTTERFLY1(temp[8*i+1], temp[8*i+3]); + BUTTERFLY1(temp[8*i+4], temp[8*i+6]); + BUTTERFLY1(temp[8*i+5], temp[8*i+7]); + + BUTTERFLY1(temp[8*i+0], temp[8*i+4]); + BUTTERFLY1(temp[8*i+1], temp[8*i+5]); + BUTTERFLY1(temp[8*i+2], temp[8*i+6]); + BUTTERFLY1(temp[8*i+3], temp[8*i+7]); + } + + for(i=0; i<8; i++){ + BUTTERFLY1(temp[8*0+i], temp[8*1+i]); + BUTTERFLY1(temp[8*2+i], temp[8*3+i]); + BUTTERFLY1(temp[8*4+i], temp[8*5+i]); + BUTTERFLY1(temp[8*6+i], temp[8*7+i]); + + BUTTERFLY1(temp[8*0+i], temp[8*2+i]); + BUTTERFLY1(temp[8*1+i], temp[8*3+i]); + BUTTERFLY1(temp[8*4+i], temp[8*6+i]); + BUTTERFLY1(temp[8*5+i], temp[8*7+i]); + + sum += + BUTTERFLYA(temp[8*0+i], temp[8*4+i]) + +BUTTERFLYA(temp[8*1+i], temp[8*5+i]) + +BUTTERFLYA(temp[8*2+i], temp[8*6+i]) + +BUTTERFLYA(temp[8*3+i], temp[8*7+i]); + } + + sum -= ABS(temp[8*0] + temp[8*4]); // -mean + + return sum; +} + +static int dct_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + DECLARE_ALIGNED_8(uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + int sum=0, i; + + assert(h==8); + + s->dsp.diff_pixels(temp, src1, src2, stride); + s->dsp.fdct(temp); + + for(i=0; i<64; i++) + sum+= ABS(temp[i]); + + return sum; +} + +#ifdef CONFIG_GPL +#define DCT8_1D {\ + const int s07 = SRC(0) + SRC(7);\ + const int s16 = SRC(1) + SRC(6);\ + const int s25 = SRC(2) + SRC(5);\ + const int s34 = SRC(3) + SRC(4);\ + const int a0 = s07 + s34;\ + const int a1 = s16 + s25;\ + const int a2 = s07 - s34;\ + const int a3 = s16 - s25;\ + const int d07 = SRC(0) - SRC(7);\ + const int d16 = SRC(1) - SRC(6);\ + const int d25 = SRC(2) - SRC(5);\ + const int d34 = SRC(3) - SRC(4);\ + const int a4 = d16 + d25 + (d07 + (d07>>1));\ + const int a5 = d07 - d34 - (d25 + (d25>>1));\ + const int a6 = d07 + d34 - (d16 + (d16>>1));\ + const int a7 = d16 - d25 + (d34 + (d34>>1));\ + DST(0, a0 + a1 ) ;\ + DST(1, a4 + (a7>>2)) ;\ + DST(2, a2 + (a3>>1)) ;\ + DST(3, a5 + (a6>>2)) ;\ + DST(4, a0 - a1 ) ;\ + DST(5, a6 - (a5>>2)) ;\ + DST(6, (a2>>1) - a3 ) ;\ + DST(7, (a4>>2) - a7 ) ;\ +} + +static int dct264_sad8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + int16_t dct[8][8]; + int i; + int sum=0; + + s->dsp.diff_pixels(dct, src1, src2, stride); + +#define SRC(x) dct[i][x] +#define DST(x,v) dct[i][x]= v + for( i = 0; i < 8; i++ ) + DCT8_1D +#undef SRC +#undef DST + +#define SRC(x) dct[x][i] +#define DST(x,v) sum += ABS(v) + for( i = 0; i < 8; i++ ) + DCT8_1D +#undef SRC +#undef DST + return sum; +} +#endif + +static int dct_max8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + DECLARE_ALIGNED_8(uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + int sum=0, i; + + assert(h==8); + + s->dsp.diff_pixels(temp, src1, src2, stride); + s->dsp.fdct(temp); + + for(i=0; i<64; i++) + sum= FFMAX(sum, ABS(temp[i])); + + return sum; +} + +void simple_idct(DCTELEM *block); //FIXME + +static int quant_psnr8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64*2/8]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + DCTELEM * const bak = ((DCTELEM*)aligned_temp)+64; + int sum=0, i; + + assert(h==8); + s->mb_intra=0; + + s->dsp.diff_pixels(temp, src1, src2, stride); + + memcpy(bak, temp, 64*sizeof(DCTELEM)); + + s->block_last_index[0/*FIXME*/]= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); + s->dct_unquantize_inter(s, temp, 0, s->qscale); + simple_idct(temp); //FIXME + + for(i=0; i<64; i++) + sum+= (temp[i]-bak[i])*(temp[i]-bak[i]); + + return sum; +} + +static int rd8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + const uint8_t *scantable= s->intra_scantable.permutated; + DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); + DECLARE_ALIGNED_8 (uint64_t, aligned_bak[stride]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + uint8_t * const bak= (uint8_t*)aligned_bak; + int i, last, run, bits, level, distoration, start_i; + const int esc_length= s->ac_esc_length; + uint8_t * length; + uint8_t * last_length; + + assert(h==8); + + for(i=0; i<8; i++){ + ((uint32_t*)(bak + i*stride))[0]= ((uint32_t*)(src2 + i*stride))[0]; + ((uint32_t*)(bak + i*stride))[1]= ((uint32_t*)(src2 + i*stride))[1]; + } + + s->dsp.diff_pixels(temp, src1, src2, stride); + + s->block_last_index[0/*FIXME*/]= last= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); + + bits=0; + + if (s->mb_intra) { + start_i = 1; + length = s->intra_ac_vlc_length; + last_length= s->intra_ac_vlc_last_length; + bits+= s->luma_dc_vlc_length[temp[0] + 256]; //FIXME chroma + } else { + start_i = 0; + length = s->inter_ac_vlc_length; + last_length= s->inter_ac_vlc_last_length; + } + + if(last>=start_i){ + run=0; + for(i=start_i; i=0){ + if(s->mb_intra) + s->dct_unquantize_intra(s, temp, 0, s->qscale); + else + s->dct_unquantize_inter(s, temp, 0, s->qscale); + } + + s->dsp.idct_add(bak, stride, temp); + + distoration= s->dsp.sse[1](NULL, bak, src1, stride, 8); + + return distoration + ((bits*s->qscale*s->qscale*109 + 64)>>7); +} + +static int bit8x8_c(/*MpegEncContext*/ void *c, uint8_t *src1, uint8_t *src2, int stride, int h){ + MpegEncContext * const s= (MpegEncContext *)c; + const uint8_t *scantable= s->intra_scantable.permutated; + DECLARE_ALIGNED_8 (uint64_t, aligned_temp[sizeof(DCTELEM)*64/8]); + DCTELEM * const temp= (DCTELEM*)aligned_temp; + int i, last, run, bits, level, start_i; + const int esc_length= s->ac_esc_length; + uint8_t * length; + uint8_t * last_length; + + assert(h==8); + + s->dsp.diff_pixels(temp, src1, src2, stride); + + s->block_last_index[0/*FIXME*/]= last= s->fast_dct_quantize(s, temp, 0/*FIXME*/, s->qscale, &i); + + bits=0; + + if (s->mb_intra) { + start_i = 1; + length = s->intra_ac_vlc_length; + last_length= s->intra_ac_vlc_last_length; + bits+= s->luma_dc_vlc_length[temp[0] + 256]; //FIXME chroma + } else { + start_i = 0; + length = s->inter_ac_vlc_length; + last_length= s->inter_ac_vlc_last_length; + } + + if(last>=start_i){ + run=0; + for(i=start_i; i>3]; +} +static void ff_jref_idct1_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + dest[0] = cm[dest[0] + ((block[0] + 4)>>3)]; +} + +static void just_return() { return; } + +/* init static data */ +void dsputil_static_init(void) +{ + int i; + + for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i; + for(i=0;idct_algo==FF_DCT_FASTINT) { + c->fdct = fdct_ifast; + c->fdct248 = fdct_ifast248; + } + else if(avctx->dct_algo==FF_DCT_FAAN) { + c->fdct = ff_faandct; + c->fdct248 = ff_faandct248; + } + else { + c->fdct = ff_jpeg_fdct_islow; //slow/accurate/default + c->fdct248 = ff_fdct248_islow; + } +#endif //CONFIG_ENCODERS + + if(avctx->lowres==1){ + if(avctx->idct_algo==FF_IDCT_INT || avctx->idct_algo==FF_IDCT_AUTO){ + c->idct_put= ff_jref_idct4_put; + c->idct_add= ff_jref_idct4_add; + }else{ + c->idct_put= ff_h264_lowres_idct_put_c; + c->idct_add= ff_h264_lowres_idct_add_c; + } + c->idct = j_rev_dct4; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->lowres==2){ + c->idct_put= ff_jref_idct2_put; + c->idct_add= ff_jref_idct2_add; + c->idct = j_rev_dct2; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else if(avctx->lowres==3){ + c->idct_put= ff_jref_idct1_put; + c->idct_add= ff_jref_idct1_add; + c->idct = j_rev_dct1; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else{ + if(avctx->idct_algo==FF_IDCT_INT){ + c->idct_put= ff_jref_idct_put; + c->idct_add= ff_jref_idct_add; + c->idct = j_rev_dct; + c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; + }else if(avctx->idct_algo==FF_IDCT_VP3){ + c->idct_put= ff_vp3_idct_put_c; + c->idct_add= ff_vp3_idct_add_c; + c->idct = ff_vp3_idct_c; + c->idct_permutation_type= FF_NO_IDCT_PERM; + }else{ //accurate/default + c->idct_put= simple_idct_put; + c->idct_add= simple_idct_add; + c->idct = simple_idct; + c->idct_permutation_type= FF_NO_IDCT_PERM; + } + } + + c->h264_idct_add= ff_h264_idct_add_c; + c->h264_idct8_add= ff_h264_idct8_add_c; + c->h264_idct_dc_add= ff_h264_idct_dc_add_c; + c->h264_idct8_dc_add= ff_h264_idct8_dc_add_c; + + c->get_pixels = get_pixels_c; + c->diff_pixels = diff_pixels_c; + c->put_pixels_clamped = put_pixels_clamped_c; + c->put_signed_pixels_clamped = put_signed_pixels_clamped_c; + c->add_pixels_clamped = add_pixels_clamped_c; + c->add_pixels8 = add_pixels8_c; + c->add_pixels4 = add_pixels4_c; + c->gmc1 = gmc1_c; + c->gmc = ff_gmc_c; + c->clear_blocks = clear_blocks_c; + c->pix_sum = pix_sum_c; + c->pix_norm1 = pix_norm1_c; + + /* TODO [0] 16 [1] 8 */ + c->pix_abs[0][0] = pix_abs16_c; + c->pix_abs[0][1] = pix_abs16_x2_c; + c->pix_abs[0][2] = pix_abs16_y2_c; + c->pix_abs[0][3] = pix_abs16_xy2_c; + c->pix_abs[1][0] = pix_abs8_c; + c->pix_abs[1][1] = pix_abs8_x2_c; + c->pix_abs[1][2] = pix_abs8_y2_c; + c->pix_abs[1][3] = pix_abs8_xy2_c; + +#define dspfunc(PFX, IDX, NUM) \ + c->PFX ## _pixels_tab[IDX][0] = PFX ## _pixels ## NUM ## _c; \ + c->PFX ## _pixels_tab[IDX][1] = PFX ## _pixels ## NUM ## _x2_c; \ + c->PFX ## _pixels_tab[IDX][2] = PFX ## _pixels ## NUM ## _y2_c; \ + c->PFX ## _pixels_tab[IDX][3] = PFX ## _pixels ## NUM ## _xy2_c + + dspfunc(put, 0, 16); + dspfunc(put_no_rnd, 0, 16); + dspfunc(put, 1, 8); + dspfunc(put_no_rnd, 1, 8); + dspfunc(put, 2, 4); + dspfunc(put, 3, 2); + + dspfunc(avg, 0, 16); + dspfunc(avg_no_rnd, 0, 16); + dspfunc(avg, 1, 8); + dspfunc(avg_no_rnd, 1, 8); + dspfunc(avg, 2, 4); + dspfunc(avg, 3, 2); +#undef dspfunc + + c->put_no_rnd_pixels_l2[0]= put_no_rnd_pixels16_l2_c; + c->put_no_rnd_pixels_l2[1]= put_no_rnd_pixels8_l2_c; + + c->put_tpel_pixels_tab[ 0] = put_tpel_pixels_mc00_c; + c->put_tpel_pixels_tab[ 1] = put_tpel_pixels_mc10_c; + c->put_tpel_pixels_tab[ 2] = put_tpel_pixels_mc20_c; + c->put_tpel_pixels_tab[ 4] = put_tpel_pixels_mc01_c; + c->put_tpel_pixels_tab[ 5] = put_tpel_pixels_mc11_c; + c->put_tpel_pixels_tab[ 6] = put_tpel_pixels_mc21_c; + c->put_tpel_pixels_tab[ 8] = put_tpel_pixels_mc02_c; + c->put_tpel_pixels_tab[ 9] = put_tpel_pixels_mc12_c; + c->put_tpel_pixels_tab[10] = put_tpel_pixels_mc22_c; + + c->avg_tpel_pixels_tab[ 0] = avg_tpel_pixels_mc00_c; + c->avg_tpel_pixels_tab[ 1] = avg_tpel_pixels_mc10_c; + c->avg_tpel_pixels_tab[ 2] = avg_tpel_pixels_mc20_c; + c->avg_tpel_pixels_tab[ 4] = avg_tpel_pixels_mc01_c; + c->avg_tpel_pixels_tab[ 5] = avg_tpel_pixels_mc11_c; + c->avg_tpel_pixels_tab[ 6] = avg_tpel_pixels_mc21_c; + c->avg_tpel_pixels_tab[ 8] = avg_tpel_pixels_mc02_c; + c->avg_tpel_pixels_tab[ 9] = avg_tpel_pixels_mc12_c; + c->avg_tpel_pixels_tab[10] = avg_tpel_pixels_mc22_c; + +#define dspfunc(PFX, IDX, NUM) \ + c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_c; \ + c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_c; \ + c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_c; \ + c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_c; \ + c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_c; \ + c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_c; \ + c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_c; \ + c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_c; \ + c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_c; \ + c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_c; \ + c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_c; \ + c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_c; \ + c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_c; \ + c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_c; \ + c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_c; \ + c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_c + + dspfunc(put_qpel, 0, 16); + dspfunc(put_no_rnd_qpel, 0, 16); + + dspfunc(avg_qpel, 0, 16); + /* dspfunc(avg_no_rnd_qpel, 0, 16); */ + + dspfunc(put_qpel, 1, 8); + dspfunc(put_no_rnd_qpel, 1, 8); + + dspfunc(avg_qpel, 1, 8); + /* dspfunc(avg_no_rnd_qpel, 1, 8); */ + + dspfunc(put_h264_qpel, 0, 16); + dspfunc(put_h264_qpel, 1, 8); + dspfunc(put_h264_qpel, 2, 4); + dspfunc(put_h264_qpel, 3, 2); + dspfunc(avg_h264_qpel, 0, 16); + dspfunc(avg_h264_qpel, 1, 8); + dspfunc(avg_h264_qpel, 2, 4); + +#undef dspfunc + c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_c; + c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_c; + c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_c; + c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_c; + c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_c; + c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_c; + + c->weight_h264_pixels_tab[0]= weight_h264_pixels16x16_c; + c->weight_h264_pixels_tab[1]= weight_h264_pixels16x8_c; + c->weight_h264_pixels_tab[2]= weight_h264_pixels8x16_c; + c->weight_h264_pixels_tab[3]= weight_h264_pixels8x8_c; + c->weight_h264_pixels_tab[4]= weight_h264_pixels8x4_c; + c->weight_h264_pixels_tab[5]= weight_h264_pixels4x8_c; + c->weight_h264_pixels_tab[6]= weight_h264_pixels4x4_c; + c->weight_h264_pixels_tab[7]= weight_h264_pixels4x2_c; + c->weight_h264_pixels_tab[8]= weight_h264_pixels2x4_c; + c->weight_h264_pixels_tab[9]= weight_h264_pixels2x2_c; + c->biweight_h264_pixels_tab[0]= biweight_h264_pixels16x16_c; + c->biweight_h264_pixels_tab[1]= biweight_h264_pixels16x8_c; + c->biweight_h264_pixels_tab[2]= biweight_h264_pixels8x16_c; + c->biweight_h264_pixels_tab[3]= biweight_h264_pixels8x8_c; + c->biweight_h264_pixels_tab[4]= biweight_h264_pixels8x4_c; + c->biweight_h264_pixels_tab[5]= biweight_h264_pixels4x8_c; + c->biweight_h264_pixels_tab[6]= biweight_h264_pixels4x4_c; + c->biweight_h264_pixels_tab[7]= biweight_h264_pixels4x2_c; + c->biweight_h264_pixels_tab[8]= biweight_h264_pixels2x4_c; + c->biweight_h264_pixels_tab[9]= biweight_h264_pixels2x2_c; + + c->put_mspel_pixels_tab[0]= put_mspel8_mc00_c; + c->put_mspel_pixels_tab[1]= put_mspel8_mc10_c; + c->put_mspel_pixels_tab[2]= put_mspel8_mc20_c; + c->put_mspel_pixels_tab[3]= put_mspel8_mc30_c; + c->put_mspel_pixels_tab[4]= put_mspel8_mc02_c; + c->put_mspel_pixels_tab[5]= put_mspel8_mc12_c; + c->put_mspel_pixels_tab[6]= put_mspel8_mc22_c; + c->put_mspel_pixels_tab[7]= put_mspel8_mc32_c; + +#define SET_CMP_FUNC(name) \ + c->name[0]= name ## 16_c;\ + c->name[1]= name ## 8x8_c; + + SET_CMP_FUNC(hadamard8_diff) + c->hadamard8_diff[4]= hadamard8_intra16_c; + SET_CMP_FUNC(dct_sad) + SET_CMP_FUNC(dct_max) +#ifdef CONFIG_GPL + SET_CMP_FUNC(dct264_sad) +#endif + c->sad[0]= pix_abs16_c; + c->sad[1]= pix_abs8_c; + c->sse[0]= sse16_c; + c->sse[1]= sse8_c; + c->sse[2]= sse4_c; + SET_CMP_FUNC(quant_psnr) + SET_CMP_FUNC(rd) + SET_CMP_FUNC(bit) + c->vsad[0]= vsad16_c; + c->vsad[4]= vsad_intra16_c; + c->vsse[0]= vsse16_c; + c->vsse[4]= vsse_intra16_c; + c->nsse[0]= nsse16_c; + c->nsse[1]= nsse8_c; + c->w53[0]= w53_16_c; + c->w53[1]= w53_8_c; + c->w97[0]= w97_16_c; + c->w97[1]= w97_8_c; + + c->add_bytes= add_bytes_c; + c->diff_bytes= diff_bytes_c; + c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; + c->bswap_buf= bswap_buf; + + c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_c; + c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_c; + c->h264_v_loop_filter_chroma= h264_v_loop_filter_chroma_c; + c->h264_h_loop_filter_chroma= h264_h_loop_filter_chroma_c; + c->h264_v_loop_filter_chroma_intra= h264_v_loop_filter_chroma_intra_c; + c->h264_h_loop_filter_chroma_intra= h264_h_loop_filter_chroma_intra_c; + + c->h263_h_loop_filter= h263_h_loop_filter_c; + c->h263_v_loop_filter= h263_v_loop_filter_c; + + c->h261_loop_filter= h261_loop_filter_c; + + c->try_8x8basis= try_8x8basis_c; + c->add_8x8basis= add_8x8basis_c; + +#ifdef CONFIG_SNOW_ENCODER + c->vertical_compose97i = ff_snow_vertical_compose97i; + c->horizontal_compose97i = ff_snow_horizontal_compose97i; + c->inner_add_yblock = ff_snow_inner_add_yblock; +#endif + + c->shrink[0]= ff_img_copy_plane; + c->shrink[1]= ff_shrink22; + c->shrink[2]= ff_shrink44; + c->shrink[3]= ff_shrink88; + + c->prefetch= just_return; + +#ifdef HAVE_MMX + dsputil_init_mmx(c, avctx); +#endif +#ifdef ARCH_ARMV4L + dsputil_init_armv4l(c, avctx); +#endif +#ifdef HAVE_MLIB + dsputil_init_mlib(c, avctx); +#endif +#ifdef ARCH_SPARC + dsputil_init_vis(c,avctx); +#endif +#ifdef ARCH_ALPHA + dsputil_init_alpha(c, avctx); +#endif +#ifdef ARCH_POWERPC + dsputil_init_ppc(c, avctx); +#endif +#ifdef HAVE_MMI + dsputil_init_mmi(c, avctx); +#endif +#ifdef ARCH_SH4 + dsputil_init_sh4(c,avctx); +#endif + + switch(c->idct_permutation_type){ + case FF_NO_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= i; + break; + case FF_LIBMPEG2_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2); + break; + case FF_SIMPLE_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= simple_mmx_permutation[i]; + break; + case FF_TRANSPOSE_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= ((i&7)<<3) | (i>>3); + break; + case FF_PARTTRANS_IDCT_PERM: + for(i=0; i<64; i++) + c->idct_permutation[i]= (i&0x24) | ((i&3)<<3) | ((i>>3)&3); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Internal error, IDCT permutation not set\n"); + } +} + diff --git a/mpeg4/src/libavcodec/dsputil.h b/mpeg4/src/libavcodec/dsputil.h new file mode 100644 index 00000000..44e6a9ef --- /dev/null +++ b/mpeg4/src/libavcodec/dsputil.h @@ -0,0 +1,638 @@ +/* + * DSP utils + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file dsputil.h + * DSP utils. + * note, many functions in here may use MMX which trashes the FPU state, it is + * absolutely necessary to call emms_c() between dsp & float/double code + */ + +#ifndef DSPUTIL_H +#define DSPUTIL_H + +#include "common.h" +#include "avcodec.h" + + +//#define DEBUG +/* dct code */ +typedef short DCTELEM; +typedef int DWTELEM; + +void fdct_ifast (DCTELEM *data); +void fdct_ifast248 (DCTELEM *data); +void ff_jpeg_fdct_islow (DCTELEM *data); +void ff_fdct248_islow (DCTELEM *data); + +void j_rev_dct (DCTELEM *data); +void j_rev_dct4 (DCTELEM *data); +void j_rev_dct2 (DCTELEM *data); +void j_rev_dct1 (DCTELEM *data); + +void ff_fdct_mmx(DCTELEM *block); +void ff_fdct_mmx2(DCTELEM *block); +void ff_fdct_sse2(DCTELEM *block); + +void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride); +void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block); +void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block); + +/* encoding scans */ +extern const uint8_t ff_alternate_horizontal_scan[64]; +extern const uint8_t ff_alternate_vertical_scan[64]; +extern const uint8_t ff_zigzag_direct[64]; +extern const uint8_t ff_zigzag248_direct[64]; + +/* pixel operations */ +#define MAX_NEG_CROP 1024 + +/* temporary */ +extern uint32_t squareTbl[512]; +extern uint8_t cropTbl[256 + 2 * MAX_NEG_CROP]; + +/* VP3 DSP functions */ +void ff_vp3_idct_c(DCTELEM *block/* align 16*/); +void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); +void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); + +/* 1/2^n downscaling functions from imgconvert.c */ +void ff_img_copy_plane(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); + +void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); + +/* minimum alignment rules ;) +if u notice errors in the align stuff, need more alignment for some asm code for some cpu +or need to use a function with less aligned data then send a mail to the ffmpeg-dev list, ... + +!warning these alignments might not match reallity, (missing attribute((align)) stuff somewhere possible) +i (michael) didnt check them, these are just the alignents which i think could be reached easily ... + +!future video codecs might need functions with less strict alignment +*/ + +/* +void get_pixels_c(DCTELEM *block, const uint8_t *pixels, int line_size); +void diff_pixels_c(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride); +void put_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); +void add_pixels_clamped_c(const DCTELEM *block, uint8_t *pixels, int line_size); +void clear_blocks_c(DCTELEM *blocks); +*/ + +/* add and put pixel (decoding) */ +// blocksizes for op_pixels_func are 8x4,8x8 16x8 16x16 +//h for op_pixels_func is limited to {width/2, width} but never larger than 16 and never smaller then 4 +typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int h); +typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h); +typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); +typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y); +typedef void (*h264_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int offset); +typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offset); + +#define DEF_OLD_QPEL(name)\ +void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ +void ff_put_no_rnd_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\ +void ff_avg_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride); + +DEF_OLD_QPEL(qpel16_mc11_old_c) +DEF_OLD_QPEL(qpel16_mc31_old_c) +DEF_OLD_QPEL(qpel16_mc12_old_c) +DEF_OLD_QPEL(qpel16_mc32_old_c) +DEF_OLD_QPEL(qpel16_mc13_old_c) +DEF_OLD_QPEL(qpel16_mc33_old_c) +DEF_OLD_QPEL(qpel8_mc11_old_c) +DEF_OLD_QPEL(qpel8_mc31_old_c) +DEF_OLD_QPEL(qpel8_mc12_old_c) +DEF_OLD_QPEL(qpel8_mc32_old_c) +DEF_OLD_QPEL(qpel8_mc13_old_c) +DEF_OLD_QPEL(qpel8_mc33_old_c) + +#define CALL_2X_PIXELS(a, b, n)\ +static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\ + b(block , pixels , line_size, h);\ + b(block+n, pixels+n, line_size, h);\ +} + +/* motion estimation */ +// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2 +// allthough currently h<4 is not used as functions with width <8 are not used and neither implemented +typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/; + + +// for snow slices +typedef struct slice_buffer_s slice_buffer; + +/** + * DSPContext. + */ +typedef struct DSPContext { + /* pixel ops : interface with DCT */ + void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size); + void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride); + void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size); + void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size); + void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size); + /** + * translational global motion compensation. + */ + void (*gmc1)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x16, int y16, int rounder); + /** + * global motion compensation. + */ + void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height); + void (*clear_blocks)(DCTELEM *blocks/*align 16*/); + int (*pix_sum)(uint8_t * pix, int line_size); + int (*pix_norm1)(uint8_t * pix, int line_size); +// 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4 + + me_cmp_func sad[5]; /* identical to pix_absAxA except additional void * */ + me_cmp_func sse[5]; + me_cmp_func hadamard8_diff[5]; + me_cmp_func dct_sad[5]; + me_cmp_func quant_psnr[5]; + me_cmp_func bit[5]; + me_cmp_func rd[5]; + me_cmp_func vsad[5]; + me_cmp_func vsse[5]; + me_cmp_func nsse[5]; + me_cmp_func w53[5]; + me_cmp_func w97[5]; + me_cmp_func dct_max[5]; + me_cmp_func dct264_sad[5]; + + me_cmp_func me_pre_cmp[5]; + me_cmp_func me_cmp[5]; + me_cmp_func me_sub_cmp[5]; + me_cmp_func mb_cmp[5]; + me_cmp_func ildct_cmp[5]; //only width 16 used + me_cmp_func frame_skip_cmp[5]; //only width 8 used + + /** + * Halfpel motion compensation with rounding (a+b+1)>>1. + * this is an array[4][4] of motion compensation funcions for 4 + * horizontal blocksizes (8,16) and the 4 halfpel positions
    + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func put_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with rounding (a+b+1)>>1. + * This is an array[4][4] of motion compensation functions for 4 + * horizontal blocksizes (8,16) and the 4 halfpel positions
    + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination into which the result is averaged (a+b+1)>>1 + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func avg_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with no rounding (a+b)>>1. + * this is an array[2][4] of motion compensation funcions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions
    + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func put_no_rnd_pixels_tab[4][4]; + + /** + * Halfpel motion compensation with no rounding (a+b)>>1. + * this is an array[2][4] of motion compensation funcions for 2 + * horizontal blocksizes (8,16) and the 4 halfpel positions
    + * *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ] + * @param block destination into which the result is averaged (a+b)>>1 + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + op_pixels_func avg_no_rnd_pixels_tab[4][4]; + + void (*put_no_rnd_pixels_l2[2])(uint8_t *block/*align width (8 or 16)*/, const uint8_t *a/*align 1*/, const uint8_t *b/*align 1*/, int line_size, int h); + + /** + * Thirdpel motion compensation with rounding (a+b+1)>>1. + * this is an array[12] of motion compensation funcions for the 9 thirdpel positions
    + * *pixels_tab[ xthirdpel + 4*ythirdpel ] + * @param block destination where the result is stored + * @param pixels source + * @param line_size number of bytes in a horizontal line of block + * @param h height + */ + tpel_mc_func put_tpel_pixels_tab[11]; //FIXME individual func ptr per width? + tpel_mc_func avg_tpel_pixels_tab[11]; //FIXME individual func ptr per width? + + qpel_mc_func put_qpel_pixels_tab[2][16]; + qpel_mc_func avg_qpel_pixels_tab[2][16]; + qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16]; + qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16]; + qpel_mc_func put_mspel_pixels_tab[8]; + + /** + * h264 Chram MC + */ + h264_chroma_mc_func put_h264_chroma_pixels_tab[3]; + h264_chroma_mc_func avg_h264_chroma_pixels_tab[3]; + + qpel_mc_func put_h264_qpel_pixels_tab[4][16]; + qpel_mc_func avg_h264_qpel_pixels_tab[4][16]; + + h264_weight_func weight_h264_pixels_tab[10]; + h264_biweight_func biweight_h264_pixels_tab[10]; + + me_cmp_func pix_abs[2][4]; + + /* huffyuv specific */ + void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w); + void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w); + /** + * subtract huffyuv's variant of median prediction + * note, this might read from src1[-1], src2[-1] + */ + void (*sub_hfyu_median_prediction)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top); + void (*bswap_buf)(uint32_t *dst, uint32_t *src, int w); + + void (*h264_v_loop_filter_luma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_h_loop_filter_luma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_v_loop_filter_chroma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_h_loop_filter_chroma)(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0); + void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix, int stride, int alpha, int beta); + void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix, int stride, int alpha, int beta); + + void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); + void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); + + void (*h261_loop_filter)(uint8_t *src, int stride); + + /* (I)DCT */ + void (*fdct)(DCTELEM *block/* align 16*/); + void (*fdct248)(DCTELEM *block/* align 16*/); + + /* IDCT really*/ + void (*idct)(DCTELEM *block/* align 16*/); + + /** + * block -> idct -> clip to unsigned 8 bit -> dest. + * (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...) + * @param line_size size in bytes of a horizotal line of dest + */ + void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); + + /** + * block -> idct -> add dest -> clip to unsigned 8 bit -> dest. + * @param line_size size in bytes of a horizotal line of dest + */ + void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/); + + /** + * idct input permutation. + * several optimized IDCTs need a permutated input (relative to the normal order of the reference + * IDCT) + * this permutation must be performed before the idct_put/add, note, normally this can be merged + * with the zigzag/alternate scan
    + * an example to avoid confusion: + * - (->decode coeffs -> zigzag reorder -> dequant -> reference idct ->...) + * - (x -> referece dct -> reference idct -> x) + * - (x -> referece dct -> simple_mmx_perm = idct_permutation -> simple_idct_mmx -> x) + * - (->decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant -> simple_idct_mmx ->...) + */ + uint8_t idct_permutation[64]; + int idct_permutation_type; +#define FF_NO_IDCT_PERM 1 +#define FF_LIBMPEG2_IDCT_PERM 2 +#define FF_SIMPLE_IDCT_PERM 3 +#define FF_TRANSPOSE_IDCT_PERM 4 +#define FF_PARTTRANS_IDCT_PERM 5 + + int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale); + void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale); +#define BASIS_SHIFT 16 +#define RECON_SHIFT 6 + + void (*h264_idct_add)(uint8_t *dst, DCTELEM *block, int stride); + void (*h264_idct8_add)(uint8_t *dst, DCTELEM *block, int stride); + void (*h264_idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride); + void (*h264_idct8_dc_add)(uint8_t *dst, DCTELEM *block, int stride); + + /* snow wavelet */ + void (*vertical_compose97i)(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width); + void (*horizontal_compose97i)(DWTELEM *b, int width); + void (*inner_add_yblock)(uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8); + + void (*prefetch)(void *mem, int stride, int h); + + void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height); +} DSPContext; + +void dsputil_static_init(void); +void dsputil_init(DSPContext* p, AVCodecContext *avctx); + +/** + * permute block according to permuatation. + * @param last last non zero element in scantable order + */ +void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scantable, int last); + +void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type); + +#define BYTE_VEC32(c) ((c)*0x01010101UL) + +static inline uint32_t rnd_avg32(uint32_t a, uint32_t b) +{ + return (a | b) - (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); +} + +static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b) +{ + return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1); +} + +static inline int get_penalty_factor(int lambda, int lambda2, int type){ + switch(type&0xFF){ + default: + case FF_CMP_SAD: + return lambda>>FF_LAMBDA_SHIFT; + case FF_CMP_DCT: + return (3*lambda)>>(FF_LAMBDA_SHIFT+1); + case FF_CMP_W53: + return (4*lambda)>>(FF_LAMBDA_SHIFT); + case FF_CMP_W97: + return (2*lambda)>>(FF_LAMBDA_SHIFT); + case FF_CMP_SATD: + case FF_CMP_DCT264: + return (2*lambda)>>FF_LAMBDA_SHIFT; + case FF_CMP_RD: + case FF_CMP_PSNR: + case FF_CMP_SSE: + case FF_CMP_NSSE: + return lambda2>>FF_LAMBDA_SHIFT; + case FF_CMP_BIT: + return 1; + } +} + +/** + * Empty mmx state. + * this must be called between any dsp function and float/double code. + * for example sin(); dsp->idct_put(); emms_c(); cos() + */ +#define emms_c() + +/* should be defined by architectures supporting + one or more MultiMedia extension */ +int mm_support(void); + +#ifdef __GNUC__ + #define DECLARE_ALIGNED_16(t,v) t v __attribute__ ((aligned (16))) +#else + #define DECLARE_ALIGNED_16(t,v) __declspec(align(16)) t v +#endif + +#if defined(HAVE_MMX) + +#undef emms_c + +#define MM_MMX 0x0001 /* standard MMX */ +#define MM_3DNOW 0x0004 /* AMD 3DNOW */ +#define MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */ +#define MM_SSE 0x0008 /* SSE functions */ +#define MM_SSE2 0x0010 /* PIV SSE2 functions */ +#define MM_3DNOWEXT 0x0020 /* AMD 3DNowExt */ + +extern int mm_flags; + +void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); +void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); +void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size); + +static inline void emms(void) +{ + __asm __volatile ("emms;":::"memory"); +} + + +#define emms_c() \ +{\ + if (mm_flags & MM_MMX)\ + emms();\ +} + +#ifdef __GNUC__ + #define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) +#else + #define DECLARE_ALIGNED_8(t,v) __declspec(align(8)) t v +#endif + +#define STRIDE_ALIGN 8 + +void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx); +void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx); + +#elif defined(ARCH_ARMV4L) + +/* This is to use 4 bytes read to the IDCT pointers for some 'zero' + line optimizations */ +#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (4))) +#define STRIDE_ALIGN 4 + +#define MM_IWMMXT 0x0100 /* XScale IWMMXT */ + +extern int mm_flags; + +void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx); + +#elif defined(HAVE_MLIB) + +/* SPARC/VIS IDCT needs 8-byte aligned DCT blocks */ +#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) +#define STRIDE_ALIGN 8 + +void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx); + +#elif defined(ARCH_SPARC) + +/* SPARC/VIS IDCT needs 8-byte aligned DCT blocks */ +#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) +#define STRIDE_ALIGN 8 +void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx); + +#elif defined(ARCH_ALPHA) + +#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) +#define STRIDE_ALIGN 8 + +void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx); + +#elif defined(ARCH_POWERPC) + +#define MM_ALTIVEC 0x0001 /* standard AltiVec */ + +extern int mm_flags; + +#if defined(HAVE_ALTIVEC) && !defined(CONFIG_DARWIN) +#define pixel altivec_pixel +#include +#undef pixel +#endif + +#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (16))) +#define STRIDE_ALIGN 16 + +void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx); + +#elif defined(HAVE_MMI) + +#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (16))) +#define STRIDE_ALIGN 16 + +void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx); + +#elif defined(ARCH_SH4) + +#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) +#define STRIDE_ALIGN 8 + +void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx); + +#else + +#define DECLARE_ALIGNED_8(t,v) t v __attribute__ ((aligned (8))) +#define STRIDE_ALIGN 8 + +#endif + +#ifdef __GNUC__ + +struct unaligned_64 { uint64_t l; } __attribute__((packed)); +struct unaligned_32 { uint32_t l; } __attribute__((packed)); +struct unaligned_16 { uint16_t l; } __attribute__((packed)); + +#define LD16(a) (((const struct unaligned_16 *) (a))->l) +#define LD32(a) (((const struct unaligned_32 *) (a))->l) +#define LD64(a) (((const struct unaligned_64 *) (a))->l) + +#define ST16(a, b) (((struct unaligned_16 *) (a))->l) = (b) +#define ST32(a, b) (((struct unaligned_32 *) (a))->l) = (b) + +#else /* __GNUC__ */ + +#define LD16(a) (*((uint16_t*)(a))) +#define LD32(a) (*((uint32_t*)(a))) +#define LD64(a) (*((uint64_t*)(a))) + +#define ST16(a, b) *((uint16_t*)(a)) = (b) +#define ST32(a, b) *((uint32_t*)(a)) = (b) + +#endif /* !__GNUC__ */ + +/* PSNR */ +void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3], + int orig_linesize[3], int coded_linesize, + AVCodecContext *avctx); + +/* FFT computation */ + +/* NOTE: soon integer code will be added, so you must use the + FFTSample type */ +typedef float FFTSample; + +typedef struct FFTComplex { + FFTSample re, im; +} FFTComplex; + +typedef struct FFTContext { + int nbits; + int inverse; + uint16_t *revtab; + FFTComplex *exptab; + FFTComplex *exptab1; /* only used by SSE code */ + void (*fft_calc)(struct FFTContext *s, FFTComplex *z); +} FFTContext; + +int ff_fft_init(FFTContext *s, int nbits, int inverse); +void ff_fft_permute(FFTContext *s, FFTComplex *z); +void ff_fft_calc_c(FFTContext *s, FFTComplex *z); +void ff_fft_calc_sse(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dn(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z); +void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z); + +static inline void ff_fft_calc(FFTContext *s, FFTComplex *z) +{ + s->fft_calc(s, z); +} +void ff_fft_end(FFTContext *s); + +/* MDCT computation */ + +typedef struct MDCTContext { + int n; /* size of MDCT (i.e. number of input data * 2) */ + int nbits; /* n = 2^nbits */ + /* pre/post rotation tables */ + FFTSample *tcos; + FFTSample *tsin; + FFTContext fft; +} MDCTContext; + +int ff_mdct_init(MDCTContext *s, int nbits, int inverse); +void ff_imdct_calc(MDCTContext *s, FFTSample *output, + const FFTSample *input, FFTSample *tmp); +void ff_mdct_calc(MDCTContext *s, FFTSample *out, + const FFTSample *input, FFTSample *tmp); +void ff_mdct_end(MDCTContext *s); + +#define WARPER8_16(name8, name16)\ +static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ + return name8(s, dst , src , stride, h)\ + +name8(s, dst+8 , src+8 , stride, h);\ +} + +#define WARPER8_16_SQ(name8, name16)\ +static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\ + int score=0;\ + score +=name8(s, dst , src , stride, 8);\ + score +=name8(s, dst+8 , src+8 , stride, 8);\ + if(h==16){\ + dst += 8*stride;\ + src += 8*stride;\ + score +=name8(s, dst , src , stride, 8);\ + score +=name8(s, dst+8 , src+8 , stride, 8);\ + }\ + return score;\ +} + +#endif diff --git a/mpeg4/src/libavcodec/dtsdec.c b/mpeg4/src/libavcodec/dtsdec.c new file mode 100644 index 00000000..dd326821 --- /dev/null +++ b/mpeg4/src/libavcodec/dtsdec.c @@ -0,0 +1,320 @@ +/* + * dtsdec.c : free DTS Coherent Acoustics stream decoder. + * Copyright (C) 2004 Benjamin Zores + * + * This file is part of libavcodec. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifdef HAVE_AV_CONFIG_H +#undef HAVE_AV_CONFIG_H +#endif + +#include "avcodec.h" +#include + +#include +#include + +#ifdef HAVE_MALLOC_H +#include +#endif + +#define BUFFER_SIZE 18726 +#define HEADER_SIZE 14 + +#ifdef LIBDTS_FIXED +#define CONVERT_LEVEL (1 << 26) +#define CONVERT_BIAS 0 +#else +#define CONVERT_LEVEL 1 +#define CONVERT_BIAS 384 +#endif + +static inline +int16_t convert (int32_t i) +{ +#ifdef LIBDTS_FIXED + i >>= 15; +#else + i -= 0x43c00000; +#endif + return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i); +} + +void +convert2s16_2 (sample_t * _f, int16_t * s16) +{ + int i; + int32_t * f = (int32_t *) _f; + + for (i = 0; i < 256; i++) + { + s16[2*i] = convert (f[i]); + s16[2*i+1] = convert (f[i+256]); + } +} + +void +convert2s16_4 (sample_t * _f, int16_t * s16) +{ + int i; + int32_t * f = (int32_t *) _f; + + for (i = 0; i < 256; i++) + { + s16[4*i] = convert (f[i]); + s16[4*i+1] = convert (f[i+256]); + s16[4*i+2] = convert (f[i+512]); + s16[4*i+3] = convert (f[i+768]); + } +} + +void +convert2s16_5 (sample_t * _f, int16_t * s16) +{ + int i; + int32_t * f = (int32_t *) _f; + + for (i = 0; i < 256; i++) + { + s16[5*i] = convert (f[i]); + s16[5*i+1] = convert (f[i+256]); + s16[5*i+2] = convert (f[i+512]); + s16[5*i+3] = convert (f[i+768]); + s16[5*i+4] = convert (f[i+1024]); + } +} + +static void +convert2s16_multi (sample_t * _f, int16_t * s16, int flags) +{ + int i; + int32_t * f = (int32_t *) _f; + + switch (flags) + { + case DTS_MONO: + for (i = 0; i < 256; i++) + { + s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; + s16[5*i+4] = convert (f[i]); + } + break; + case DTS_CHANNEL: + case DTS_STEREO: + case DTS_DOLBY: + convert2s16_2 (_f, s16); + break; + case DTS_3F: + for (i = 0; i < 256; i++) + { + s16[5*i] = convert (f[i]); + s16[5*i+1] = convert (f[i+512]); + s16[5*i+2] = s16[5*i+3] = 0; + s16[5*i+4] = convert (f[i+256]); + } + break; + case DTS_2F2R: + convert2s16_4 (_f, s16); + break; + case DTS_3F2R: + convert2s16_5 (_f, s16); + break; + case DTS_MONO | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; + s16[6*i+4] = convert (f[i+256]); + s16[6*i+5] = convert (f[i]); + } + break; + case DTS_CHANNEL | DTS_LFE: + case DTS_STEREO | DTS_LFE: + case DTS_DOLBY | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+512]); + s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; + s16[6*i+5] = convert (f[i]); + } + break; + case DTS_3F | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+768]); + s16[6*i+2] = s16[6*i+3] = 0; + s16[6*i+4] = convert (f[i+512]); + s16[6*i+5] = convert (f[i]); + } + break; + case DTS_2F2R | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+512]); + s16[6*i+2] = convert (f[i+768]); + s16[6*i+3] = convert (f[i+1024]); + s16[6*i+4] = 0; + s16[6*i+5] = convert (f[i]); + } + break; + case DTS_3F2R | DTS_LFE: + for (i = 0; i < 256; i++) + { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+768]); + s16[6*i+2] = convert (f[i+1024]); + s16[6*i+3] = convert (f[i+1280]); + s16[6*i+4] = convert (f[i+512]); + s16[6*i+5] = convert (f[i]); + } + break; + } +} + +static int +channels_multi (int flags) +{ + if (flags & DTS_LFE) + return 6; + else if (flags & 1) /* center channel */ + return 5; + else if ((flags & DTS_CHANNEL_MASK) == DTS_2F2R) + return 4; + else + return 2; +} + +static int +dts_decode_frame (AVCodecContext *avctx, void *data, int *data_size, + uint8_t *buff, int buff_size) +{ + uint8_t * start = buff; + uint8_t * end = buff + buff_size; + static uint8_t buf[BUFFER_SIZE]; + static uint8_t * bufptr = buf; + static uint8_t * bufpos = buf + HEADER_SIZE; + + static int sample_rate; + static int frame_length; + static int flags; + int bit_rate; + int len; + dts_state_t *state = avctx->priv_data; + + *data_size = 0; + + while (1) + { + len = end - start; + if (!len) + break; + if (len > bufpos - bufptr) + len = bufpos - bufptr; + memcpy (bufptr, start, len); + bufptr += len; + start += len; + if (bufptr != bufpos) + return start - buff; + if (bufpos != buf + HEADER_SIZE) + break; + + { + int length; + + length = dts_syncinfo (state, buf, &flags, &sample_rate, + &bit_rate, &frame_length); + if (!length) + { + av_log (NULL, AV_LOG_INFO, "skip\n"); + for (bufptr = buf; bufptr < buf + HEADER_SIZE-1; bufptr++) + bufptr[0] = bufptr[1]; + continue; + } + bufpos = buf + length; + } + } + + { + level_t level; + sample_t bias; + int i; + + flags = 2; /* ???????????? */ + level = CONVERT_LEVEL; + bias = CONVERT_BIAS; + + flags |= DTS_ADJUST_LEVEL; + if (dts_frame (state, buf, &flags, &level, bias)) + goto error; + avctx->sample_rate = sample_rate; + avctx->channels = channels_multi (flags); + avctx->bit_rate = bit_rate; + for (i = 0; i < dts_blocks_num (state); i++) + { + if (dts_block (state)) + goto error; + { + int chans; + chans = channels_multi (flags); + convert2s16_multi (dts_samples (state), data, + flags & (DTS_CHANNEL_MASK | DTS_LFE)); + + data += 256 * sizeof (int16_t) * chans; + *data_size += 256 * sizeof (int16_t) * chans; + } + } + bufptr = buf; + bufpos = buf + HEADER_SIZE; + return start-buff; + error: + av_log (NULL, AV_LOG_ERROR, "error\n"); + bufptr = buf; + bufpos = buf + HEADER_SIZE; + } + + return start-buff; +} + +static int +dts_decode_init (AVCodecContext *avctx) +{ + avctx->priv_data = dts_init (0); + if (avctx->priv_data == NULL) + return -1; + + return 0; +} + +static int +dts_decode_end (AVCodecContext *s) +{ + return 0; +} + +AVCodec dts_decoder = { + "dts", + CODEC_TYPE_AUDIO, + CODEC_ID_DTS, + sizeof (dts_state_t *), + dts_decode_init, + NULL, + dts_decode_end, + dts_decode_frame, +}; diff --git a/mpeg4/src/libavcodec/dv.c b/mpeg4/src/libavcodec/dv.c new file mode 100644 index 00000000..c39d70c5 --- /dev/null +++ b/mpeg4/src/libavcodec/dv.c @@ -0,0 +1,1147 @@ +/* + * DV decoder + * Copyright (c) 2002 Fabrice Bellard. + * Copyright (c) 2004 Roman Shaposhnik. + * + * DV encoder + * Copyright (c) 2003 Roman Shaposhnik. + * + * 50 Mbps (DVCPRO50) support + * Copyright (c) 2006 Daniel Maas + * + * Many thanks to Dan Dennedy for providing wealth + * of DV technical info. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file dv.c + * DV codec. + */ +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "simple_idct.h" +#include "dvdata.h" + +//#undef NDEBUG +//#include + +typedef struct DVVideoContext { + const DVprofile* sys; + AVFrame picture; + AVCodecContext *avctx; + uint8_t *buf; + + uint8_t dv_zigzag[2][64]; + uint8_t dv_idct_shift[2][2][22][64]; + + void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size); + void (*fdct[2])(DCTELEM *block); + void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block); +} DVVideoContext; + +/* MultiThreading - dv_anchor applies to entire DV codec, not just the avcontext */ +/* one element is needed for each video segment in a DV frame */ +/* at most there are 2 DIF channels * 12 DIF sequences * 27 video segments (PAL 50Mbps) */ +#define DV_ANCHOR_SIZE (2*12*27) + +static void* dv_anchor[DV_ANCHOR_SIZE]; + +#define TEX_VLC_BITS 9 + +#ifdef DV_CODEC_TINY_TARGET +#define DV_VLC_MAP_RUN_SIZE 15 +#define DV_VLC_MAP_LEV_SIZE 23 +#else +#define DV_VLC_MAP_RUN_SIZE 64 +#define DV_VLC_MAP_LEV_SIZE 512 //FIXME sign was removed so this should be /2 but needs check +#endif + +/* XXX: also include quantization */ +static RL_VLC_ELEM *dv_rl_vlc; +/* VLC encoding lookup table */ +static struct dv_vlc_pair { + uint32_t vlc; + uint8_t size; +} (*dv_vlc_map)[DV_VLC_MAP_LEV_SIZE] = NULL; + +static void dv_build_unquantize_tables(DVVideoContext *s, uint8_t* perm) +{ + int i, q, j; + + /* NOTE: max left shift is 6 */ + for(q = 0; q < 22; q++) { + /* 88DCT */ + for(i = 1; i < 64; i++) { + /* 88 table */ + j = perm[i]; + s->dv_idct_shift[0][0][q][j] = + dv_quant_shifts[q][dv_88_areas[i]] + 1; + s->dv_idct_shift[1][0][q][j] = s->dv_idct_shift[0][0][q][j] + 1; + } + + /* 248DCT */ + for(i = 1; i < 64; i++) { + /* 248 table */ + s->dv_idct_shift[0][1][q][i] = + dv_quant_shifts[q][dv_248_areas[i]] + 1; + s->dv_idct_shift[1][1][q][i] = s->dv_idct_shift[0][1][q][i] + 1; + } + } +} + +static int dvvideo_init(AVCodecContext *avctx) +{ + DVVideoContext *s = avctx->priv_data; + DSPContext dsp; + static int done=0; + int i, j; + + if (!done) { + VLC dv_vlc; + uint16_t new_dv_vlc_bits[NB_DV_VLC*2]; + uint8_t new_dv_vlc_len[NB_DV_VLC*2]; + uint8_t new_dv_vlc_run[NB_DV_VLC*2]; + int16_t new_dv_vlc_level[NB_DV_VLC*2]; + + done = 1; + + dv_vlc_map = av_mallocz_static(DV_VLC_MAP_LEV_SIZE*DV_VLC_MAP_RUN_SIZE*sizeof(struct dv_vlc_pair)); + if (!dv_vlc_map) + return -ENOMEM; + + /* dv_anchor lets each thread know its Id */ + for (i=0; i= DV_VLC_MAP_RUN_SIZE) + continue; +#ifdef DV_CODEC_TINY_TARGET + if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE) + continue; +#endif + + if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0) + continue; + + dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc = dv_vlc_bits[i] << + (!!dv_vlc_level[i]); + dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size = dv_vlc_len[i] + + (!!dv_vlc_level[i]); + } + for (i = 0; i < DV_VLC_MAP_RUN_SIZE; i++) { +#ifdef DV_CODEC_TINY_TARGET + for (j = 1; j < DV_VLC_MAP_LEV_SIZE; j++) { + if (dv_vlc_map[i][j].size == 0) { + dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc | + (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); + dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + + dv_vlc_map[0][j].size; + } + } +#else + for (j = 1; j < DV_VLC_MAP_LEV_SIZE/2; j++) { + if (dv_vlc_map[i][j].size == 0) { + dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc | + (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size)); + dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size + + dv_vlc_map[0][j].size; + } + dv_vlc_map[i][((uint16_t)(-j))&0x1ff].vlc = + dv_vlc_map[i][j].vlc | 1; + dv_vlc_map[i][((uint16_t)(-j))&0x1ff].size = + dv_vlc_map[i][j].size; + } +#endif + } + } + + /* Generic DSP setup */ + dsputil_init(&dsp, avctx); + s->get_pixels = dsp.get_pixels; + + /* 88DCT setup */ + s->fdct[0] = dsp.fdct; + s->idct_put[0] = dsp.idct_put; + for (i=0; i<64; i++) + s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]]; + + /* 248DCT setup */ + s->fdct[1] = dsp.fdct248; + s->idct_put[1] = simple_idct248_put; // FIXME: need to add it to DSP + if(avctx->lowres){ + for (i=0; i<64; i++){ + int j= ff_zigzag248_direct[i]; + s->dv_zigzag[1][i] = dsp.idct_permutation[(j&7) + (j&8)*4 + (j&48)/2]; + } + }else + memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64); + + /* XXX: do it only for constant case */ + dv_build_unquantize_tables(s, dsp.idct_permutation); + + avctx->coded_frame = &s->picture; + s->avctx= avctx; + + return 0; +} + +// #define VLC_DEBUG +// #define printf(...) av_log(NULL, AV_LOG_ERROR, __VA_ARGS__) + +typedef struct BlockInfo { + const uint8_t *shift_table; + const uint8_t *scan_table; + const int *iweight_table; + uint8_t pos; /* position in block */ + uint8_t dct_mode; + uint8_t partial_bit_count; + uint16_t partial_bit_buffer; + int shift_offset; +} BlockInfo; + +/* block size in bits */ +static const uint16_t block_sizes[6] = { + 112, 112, 112, 112, 80, 80 +}; +/* bit budget for AC only in 5 MBs */ +static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; +/* see dv_88_areas and dv_248_areas for details */ +static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; + +#ifndef ALT_BITSTREAM_READER +#warning only works with ALT_BITSTREAM_READER +static int re_index; //Hack to make it compile +#endif + +static inline int get_bits_left(GetBitContext *s) +{ + return s->size_in_bits - get_bits_count(s); +} + +static inline int get_bits_size(GetBitContext *s) +{ + return s->size_in_bits; +} + +static inline int put_bits_left(PutBitContext* s) +{ + return (s->buf_end - s->buf) * 8 - put_bits_count(s); +} + +/* decode ac coefs */ +static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) +{ + int last_index = get_bits_size(gb); + const uint8_t *scan_table = mb->scan_table; + const uint8_t *shift_table = mb->shift_table; + const int *iweight_table = mb->iweight_table; + int pos = mb->pos; + int partial_bit_count = mb->partial_bit_count; + int level, pos1, run, vlc_len, index; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + + /* if we must parse a partial vlc, we do it here */ + if (partial_bit_count > 0) { + re_cache = ((unsigned)re_cache >> partial_bit_count) | + (mb->partial_bit_buffer << (sizeof(re_cache)*8 - partial_bit_count)); + re_index -= partial_bit_count; + mb->partial_bit_count = 0; + } + + /* get the AC coefficients until last_index is reached */ + for(;;) { +#ifdef VLC_DEBUG + printf("%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16), re_index); +#endif + /* our own optimized GET_RL_VLC */ + index = NEG_USR32(re_cache, TEX_VLC_BITS); + vlc_len = dv_rl_vlc[index].len; + if (vlc_len < 0) { + index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level; + vlc_len = TEX_VLC_BITS - vlc_len; + } + level = dv_rl_vlc[index].level; + run = dv_rl_vlc[index].run; + + /* gotta check if we're still within gb boundaries */ + if (re_index + vlc_len > last_index) { + /* should be < 16 bits otherwise a codeword could have been parsed */ + mb->partial_bit_count = last_index - re_index; + mb->partial_bit_buffer = NEG_USR32(re_cache, mb->partial_bit_count); + re_index = last_index; + break; + } + re_index += vlc_len; + +#ifdef VLC_DEBUG + printf("run=%d level=%d\n", run, level); +#endif + pos += run; + if (pos >= 64) + break; + + pos1 = scan_table[pos]; + level <<= shift_table[pos1]; + + /* unweigh, round, and shift down */ + level = (level*iweight_table[pos] + (1 << (dv_iweight_bits-1))) >> dv_iweight_bits; + + block[pos1] = level; + + UPDATE_CACHE(re, gb); + } + CLOSE_READER(re, gb); + mb->pos = pos; +} + +static inline void bit_copy(PutBitContext *pb, GetBitContext *gb) +{ + int bits_left = get_bits_left(gb); + while (bits_left >= MIN_CACHE_BITS) { + put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS)); + bits_left -= MIN_CACHE_BITS; + } + if (bits_left > 0) { + put_bits(pb, bits_left, get_bits(gb, bits_left)); + } +} + +/* mb_x and mb_y are in units of 8 pixels */ +static inline void dv_decode_video_segment(DVVideoContext *s, + uint8_t *buf_ptr1, + const uint16_t *mb_pos_ptr) +{ + int quant, dc, dct_mode, class1, j; + int mb_index, mb_x, mb_y, v, last_index; + DCTELEM *block, *block1; + int c_offset; + uint8_t *y_ptr; + void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block); + uint8_t *buf_ptr; + PutBitContext pb, vs_pb; + GetBitContext gb; + BlockInfo mb_data[5 * 6], *mb, *mb1; + DECLARE_ALIGNED_8(DCTELEM, sblock[5*6][64]); + DECLARE_ALIGNED_8(uint8_t, mb_bit_buffer[80 + 4]); /* allow some slack */ + DECLARE_ALIGNED_8(uint8_t, vs_bit_buffer[5 * 80 + 4]); /* allow some slack */ + const int log2_blocksize= 3-s->avctx->lowres; + + assert((((int)mb_bit_buffer)&7)==0); + assert((((int)vs_bit_buffer)&7)==0); + + memset(sblock, 0, sizeof(sblock)); + + /* pass 1 : read DC and AC coefficients in blocks */ + buf_ptr = buf_ptr1; + block1 = &sblock[0][0]; + mb1 = mb_data; + init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80); + for(mb_index = 0; mb_index < 5; mb_index++, mb1 += 6, block1 += 6 * 64) { + /* skip header */ + quant = buf_ptr[3] & 0x0f; + buf_ptr += 4; + init_put_bits(&pb, mb_bit_buffer, 80); + mb = mb1; + block = block1; + for(j = 0;j < 6; j++) { + last_index = block_sizes[j]; + init_get_bits(&gb, buf_ptr, last_index); + + /* get the dc */ + dc = get_sbits(&gb, 9); + dct_mode = get_bits1(&gb); + mb->dct_mode = dct_mode; + mb->scan_table = s->dv_zigzag[dct_mode]; + mb->iweight_table = dct_mode ? dv_iweight_248 : dv_iweight_88; + class1 = get_bits(&gb, 2); + mb->shift_table = s->dv_idct_shift[class1 == 3][dct_mode] + [quant + dv_quant_offset[class1]]; + dc = dc << 2; + /* convert to unsigned because 128 is not added in the + standard IDCT */ + dc += 1024; + block[0] = dc; + buf_ptr += last_index >> 3; + mb->pos = 0; + mb->partial_bit_count = 0; + +#ifdef VLC_DEBUG + printf("MB block: %d, %d ", mb_index, j); +#endif + dv_decode_ac(&gb, mb, block); + + /* write the remaining bits in a new buffer only if the + block is finished */ + if (mb->pos >= 64) + bit_copy(&pb, &gb); + + block += 64; + mb++; + } + + /* pass 2 : we can do it just after */ +#ifdef VLC_DEBUG + printf("***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index); +#endif + block = block1; + mb = mb1; + init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb)); + flush_put_bits(&pb); + for(j = 0;j < 6; j++, block += 64, mb++) { + if (mb->pos < 64 && get_bits_left(&gb) > 0) { + dv_decode_ac(&gb, mb, block); + /* if still not finished, no need to parse other blocks */ + if (mb->pos < 64) + break; + } + } + /* all blocks are finished, so the extra bytes can be used at + the video segment level */ + if (j >= 6) + bit_copy(&vs_pb, &gb); + } + + /* we need a pass other the whole video segment */ +#ifdef VLC_DEBUG + printf("***pass 3 size=%d\n", put_bits_count(&vs_pb)); +#endif + block = &sblock[0][0]; + mb = mb_data; + init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb)); + flush_put_bits(&vs_pb); + for(mb_index = 0; mb_index < 5; mb_index++) { + for(j = 0;j < 6; j++) { + if (mb->pos < 64) { +#ifdef VLC_DEBUG + printf("start %d:%d\n", mb_index, j); +#endif + dv_decode_ac(&gb, mb, block); + } + if (mb->pos >= 64 && mb->pos < 127) + av_log(NULL, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos); + block += 64; + mb++; + } + } + + /* compute idct and place blocks */ + block = &sblock[0][0]; + mb = mb_data; + for(mb_index = 0; mb_index < 5; mb_index++) { + v = *mb_pos_ptr++; + mb_x = v & 0xff; + mb_y = v >> 8; + if (s->sys->pix_fmt == PIX_FMT_YUV422P) { + y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + (mb_x>>1))<picture.linesize[1] + (mb_x >> 2))<picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<sys->pix_fmt == PIX_FMT_YUV411P) + c_offset = ((mb_y * s->picture.linesize[1] + (mb_x >> 2))<> 1) * s->picture.linesize[1] + (mb_x >> 1))<idct_put[mb->dct_mode && log2_blocksize==3]; + if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */ + if (j == 0 || j == 2) { + /* Y0 Y1 */ + idct_put(y_ptr + ((j >> 1)<picture.linesize[0], block); + } else if(j > 3) { + /* Cr Cb */ + idct_put(s->picture.data[6 - j] + c_offset, + s->picture.linesize[6 - j], block); + } + /* note: j=1 and j=3 are "dummy" blocks in 4:2:2 */ + } else { /* 4:1:1 or 4:2:0 */ + if (j < 4) { + if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { + /* NOTE: at end of line, the macroblock is handled as 420 */ + idct_put(y_ptr + (j<picture.linesize[0], block); + } else { + idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<picture.linesize[0], block); + } + } else { + if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) { + uint64_t aligned_pixels[64/8]; + uint8_t *pixels= (uint8_t*)aligned_pixels; + uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1; + int x, y, linesize; + /* NOTE: at end of line, the macroblock is handled as 420 */ + idct_put(pixels, 8, block); + linesize = s->picture.linesize[6 - j]; + c_ptr = s->picture.data[6 - j] + c_offset; + ptr = pixels; + for(y = 0;y < (1<picture.data[6 - j] + c_offset, + s->picture.linesize[6 - j], block); + } + } + } + block += 64; + mb++; + } + } +} + +#ifdef DV_CODEC_TINY_TARGET +/* Converts run and level (where level != 0) pair into vlc, returning bit size */ +static always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc) +{ + int size; + if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { + *vlc = dv_vlc_map[run][level].vlc | sign; + size = dv_vlc_map[run][level].size; + } + else { + if (level < DV_VLC_MAP_LEV_SIZE) { + *vlc = dv_vlc_map[0][level].vlc | sign; + size = dv_vlc_map[0][level].size; + } else { + *vlc = 0xfe00 | (level << 1) | sign; + size = 16; + } + if (run) { + *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc : + (0x1f80 | (run - 1))) << size; + size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; + } + } + + return size; +} + +static always_inline int dv_rl2vlc_size(int run, int level) +{ + int size; + + if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) { + size = dv_vlc_map[run][level].size; + } + else { + size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16; + if (run) { + size += (run < 16) ? dv_vlc_map[run-1][0].size : 13; + } + } + return size; +} +#else +static always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc) +{ + *vlc = dv_vlc_map[run][l].vlc | sign; + return dv_vlc_map[run][l].size; +} + +static always_inline int dv_rl2vlc_size(int run, int l) +{ + return dv_vlc_map[run][l].size; +} +#endif + +typedef struct EncBlockInfo { + int area_q[4]; + int bit_size[4]; + int prev[5]; + int cur_ac; + int cno; + int dct_mode; + DCTELEM mb[64]; + uint8_t next[64]; + uint8_t sign[64]; + uint8_t partial_bit_count; + uint32_t partial_bit_buffer; /* we can't use uint16_t here */ +} EncBlockInfo; + +static always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi, PutBitContext* pb_pool, + PutBitContext* pb_end) +{ + int prev; + int bits_left; + PutBitContext* pb = pb_pool; + int size = bi->partial_bit_count; + uint32_t vlc = bi->partial_bit_buffer; + + bi->partial_bit_count = bi->partial_bit_buffer = 0; + for(;;){ + /* Find suitable storage space */ + for (; size > (bits_left = put_bits_left(pb)); pb++) { + if (bits_left) { + size -= bits_left; + put_bits(pb, bits_left, vlc >> size); + vlc = vlc & ((1<= pb_end) { + bi->partial_bit_count = size; + bi->partial_bit_buffer = vlc; + return pb; + } + } + + /* Store VLC */ + put_bits(pb, size, vlc); + + if(bi->cur_ac>=64) + break; + + /* Construct the next VLC */ + prev= bi->cur_ac; + bi->cur_ac = bi->next[prev]; + if(bi->cur_ac < 64){ + size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc); + } else { + size = 4; vlc = 6; /* End Of Block stamp */ + } + } + return pb; +} + +static always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi, + const uint8_t* zigzag_scan, const int *weight, int bias) +{ + int i, area; + /* We offer two different methods for class number assignment: the + method suggested in SMPTE 314M Table 22, and an improved + method. The SMPTE method is very conservative; it assigns class + 3 (i.e. severe quantization) to any block where the largest AC + component is greater than 36. ffmpeg's DV encoder tracks AC bit + consumption precisely, so there is no need to bias most blocks + towards strongly lossy compression. Instead, we assign class 2 + to most blocks, and use class 3 only when strictly necessary + (for blocks whose largest AC component exceeds 255). */ + +#if 0 /* SMPTE spec method */ + static const int classes[] = {12, 24, 36, 0xffff}; +#else /* improved ffmpeg method */ + static const int classes[] = {-1, -1, 255, 0xffff}; +#endif + int max=classes[0]; + int prev=0; + + bi->mb[0] = blk[0]; + + for (area = 0; area < 4; area++) { + bi->prev[area] = prev; + bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) + for (i=mb_area_start[area]; i 30U) { + bi->sign[i] = (level>>31)&1; + /* weigh it and and shift down into range, adding for rounding */ + /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT + AND the 2x doubling of the weights */ + level = (ABS(level) * weight[i] + (1<<(dv_weight_bits+3))) >> (dv_weight_bits+4); + bi->mb[i] = level; + if(level>max) max= level; + bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level); + bi->next[prev]= i; + prev= i; + } + } + } + bi->next[prev]= i; + for(bi->cno = 0; max > classes[bi->cno]; bi->cno++); + + bi->cno += bias; + + if (bi->cno >= 3) { + bi->cno = 3; + prev=0; + i= bi->next[prev]; + for (area = 0; area < 4; area++) { + bi->prev[area] = prev; + bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :) + for (; inext[i]) { + bi->mb[i] >>=1; + + if (bi->mb[i]) { + bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]); + bi->next[prev]= i; + prev= i; + } + } + } + bi->next[prev]= i; + } +} + +//FIXME replace this by dsputil +#define SC(x, y) ((s[x] - s[y]) ^ ((s[x] - s[y]) >> 7)) +static always_inline int dv_guess_dct_mode(DCTELEM *blk) { + DCTELEM *s; + int score88 = 0; + int score248 = 0; + int i; + + /* Compute 8-8 score (small values give a better chance for 8-8 DCT) */ + s = blk; + for(i=0; i<7; i++) { + score88 += SC(0, 8) + SC(1, 9) + SC(2, 10) + SC(3, 11) + + SC(4, 12) + SC(5,13) + SC(6, 14) + SC(7, 15); + s += 8; + } + /* Compute 2-4-8 score (small values give a better chance for 2-4-8 DCT) */ + s = blk; + for(i=0; i<6; i++) { + score248 += SC(0, 16) + SC(1,17) + SC(2, 18) + SC(3, 19) + + SC(4, 20) + SC(5,21) + SC(6, 22) + SC(7, 23); + s += 8; + } + + return (score88 - score248 > -10); +} + +static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos) +{ + int size[5]; + int i, j, k, a, prev, a2; + EncBlockInfo* b; + + size[0] = size[1] = size[2] = size[3] = size[4] = 1<<24; + do { + b = blks; + for (i=0; i<5; i++) { + if (!qnos[i]) + continue; + + qnos[i]--; + size[i] = 0; + for (j=0; j<6; j++, b++) { + for (a=0; a<4; a++) { + if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) { + b->bit_size[a] = 1; // 4 areas 4 bits for EOB :) + b->area_q[a]++; + prev= b->prev[a]; + assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]); + for (k= b->next[prev] ; knext[k]) { + b->mb[k] >>= 1; + if (b->mb[k]) { + b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]); + prev= k; + } else { + if(b->next[k] >= mb_area_start[a+1] && b->next[k]<64){ + for(a2=a+1; b->next[k] >= mb_area_start[a2+1]; a2++) + b->prev[a2] = prev; + assert(a2<4); + assert(b->mb[b->next[k]]); + b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]]) + -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]); + assert(b->prev[a2]==k && (a2+1 >= 4 || b->prev[a2+1]!=k)); + b->prev[a2] = prev; + } + b->next[prev] = b->next[k]; + } + } + b->prev[a+1]= prev; + } + size[i] += b->bit_size[a]; + } + } + if(vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4]) + return; + } + } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]); + + + for(a=2; a==2 || vs_total_ac_bits < size[0]; a+=a){ + b = blks; + size[0] = 5*6*4; //EOB + for (j=0; j<6*5; j++, b++) { + prev= b->prev[0]; + for (k= b->next[prev]; k<64; k= b->next[k]) { + if(b->mb[k] < a && b->mb[k] > -a){ + b->next[prev] = b->next[k]; + }else{ + size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]); + prev= k; + } + } + } + } +} + +static inline void dv_encode_video_segment(DVVideoContext *s, + uint8_t *dif, + const uint16_t *mb_pos_ptr) +{ + int mb_index, i, j, v; + int mb_x, mb_y, c_offset, linesize; + uint8_t* y_ptr; + uint8_t* data; + uint8_t* ptr; + int do_edge_wrap; + DECLARE_ALIGNED_8(DCTELEM, block[64]); + EncBlockInfo enc_blks[5*6]; + PutBitContext pbs[5*6]; + PutBitContext* pb; + EncBlockInfo* enc_blk; + int vs_bit_size = 0; + int qnos[5]; + + assert((((int)block) & 7) == 0); + + enc_blk = &enc_blks[0]; + pb = &pbs[0]; + for(mb_index = 0; mb_index < 5; mb_index++) { + v = *mb_pos_ptr++; + mb_x = v & 0xff; + mb_y = v >> 8; + if (s->sys->pix_fmt == PIX_FMT_YUV422P) { + y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 4); + } else { /* 4:1:1 */ + y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8); + } + if (s->sys->pix_fmt == PIX_FMT_YUV420P) { + c_offset = (((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8)); + } else { /* 4:2:2 or 4:1:1 */ + c_offset = ((mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8)); + } + do_edge_wrap = 0; + qnos[mb_index] = 15; /* No quantization */ + ptr = dif + mb_index*80 + 4; + for(j = 0;j < 6; j++) { + int dummy = 0; + if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */ + if (j == 0 || j == 2) { + /* Y0 Y1 */ + data = y_ptr + ((j>>1) * 8); + linesize = s->picture.linesize[0]; + } else if (j > 3) { + /* Cr Cb */ + data = s->picture.data[6 - j] + c_offset; + linesize = s->picture.linesize[6 - j]; + } else { + /* j=1 and j=3 are "dummy" blocks, used for AC data only */ + data = 0; + linesize = 0; + dummy = 1; + } + } else { /* 4:1:1 or 4:2:0 */ + if (j < 4) { /* Four Y blocks */ + /* NOTE: at end of line, the macroblock is handled as 420 */ + if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) { + data = y_ptr + (j * 8); + } else { + data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]); + } + linesize = s->picture.linesize[0]; + } else { /* Cr and Cb blocks */ + /* don't ask Fabrice why they inverted Cb and Cr ! */ + data = s->picture.data[6 - j] + c_offset; + linesize = s->picture.linesize[6 - j]; + if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) + do_edge_wrap = 1; + } + } + + /* Everything is set up -- now just copy data -> DCT block */ + if (do_edge_wrap) { /* Edge wrap copy: 4x16 -> 8x8 */ + uint8_t* d; + DCTELEM *b = block; + for (i=0;i<8;i++) { + d = data + 8 * linesize; + b[0] = data[0]; b[1] = data[1]; b[2] = data[2]; b[3] = data[3]; + b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3]; + data += linesize; + b += 8; + } + } else { /* Simple copy: 8x8 -> 8x8 */ + if (!dummy) + s->get_pixels(block, data, linesize); + } + + if(s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) + enc_blk->dct_mode = dv_guess_dct_mode(block); + else + enc_blk->dct_mode = 0; + enc_blk->area_q[0] = enc_blk->area_q[1] = enc_blk->area_q[2] = enc_blk->area_q[3] = 0; + enc_blk->partial_bit_count = 0; + enc_blk->partial_bit_buffer = 0; + enc_blk->cur_ac = 0; + + if (dummy) { + /* We rely on the fact that encoding all zeros leads to an immediate EOB, + which is precisely what the spec calls for in the "dummy" blocks. */ + memset(block, 0, sizeof(block)); + } else { + s->fdct[enc_blk->dct_mode](block); + } + + dv_set_class_number(block, enc_blk, + enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct, + enc_blk->dct_mode ? dv_weight_248 : dv_weight_88, + j/4); + + init_put_bits(pb, ptr, block_sizes[j]/8); + put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024 + 2) >> 2)); + put_bits(pb, 1, enc_blk->dct_mode); + put_bits(pb, 2, enc_blk->cno); + + vs_bit_size += enc_blk->bit_size[0] + enc_blk->bit_size[1] + + enc_blk->bit_size[2] + enc_blk->bit_size[3]; + ++enc_blk; + ++pb; + ptr += block_sizes[j]/8; + } + } + + if (vs_total_ac_bits < vs_bit_size) + dv_guess_qnos(&enc_blks[0], &qnos[0]); + + for (i=0; i<5; i++) { + dif[i*80 + 3] = qnos[i]; + } + + /* First pass over individual cells only */ + for (j=0; j<5*6; j++) + dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]); + + /* Second pass over each MB space */ + for (j=0; j<5*6; j+=6) { + pb= &pbs[j]; + for (i=0; i<6; i++) { + if (enc_blks[i+j].partial_bit_count) + pb=dv_encode_ac(&enc_blks[i+j], pb, &pbs[j+6]); + } + } + + /* Third and final pass over the whole vides segment space */ + pb= &pbs[0]; + for (j=0; j<5*6; j++) { + if (enc_blks[j].partial_bit_count) + pb=dv_encode_ac(&enc_blks[j], pb, &pbs[6*5]); + if (enc_blks[j].partial_bit_count) + av_log(NULL, AV_LOG_ERROR, "ac bitstream overflow\n"); + } + + for (j=0; j<5*6; j++) + flush_put_bits(&pbs[j]); +} + +static int dv_decode_mt(AVCodecContext *avctx, void* sl) +{ + DVVideoContext *s = avctx->priv_data; + int slice = (size_t)sl; + + /* which DIF channel is this? */ + int chan = slice / (s->sys->difseg_size * 27); + + /* slice within the DIF channel */ + int chan_slice = slice % (s->sys->difseg_size * 27); + + /* byte offset of this channel's data */ + int chan_offset = chan * s->sys->difseg_size * 150 * 80; + + dv_decode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset], + &s->sys->video_place[slice*5]); + return 0; +} + +static int dv_encode_mt(AVCodecContext *avctx, void* sl) +{ + DVVideoContext *s = avctx->priv_data; + int slice = (size_t)sl; + + /* which DIF channel is this? */ + int chan = slice / (s->sys->difseg_size * 27); + + /* slice within the DIF channel */ + int chan_slice = slice % (s->sys->difseg_size * 27); + + /* byte offset of this channel's data */ + int chan_offset = chan * s->sys->difseg_size * 150 * 80; + + dv_encode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset], + &s->sys->video_place[slice*5]); + return 0; +} + +/* NOTE: exactly one frame must be given (120000 bytes for NTSC, + 144000 bytes for PAL - or twice those for 50Mbps) */ +static int dvvideo_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + DVVideoContext *s = avctx->priv_data; + + s->sys = dv_frame_profile(buf); + if (!s->sys || buf_size < s->sys->frame_size) + return -1; /* NOTE: we only accept several full frames */ + + if(s->picture.data[0]) + avctx->release_buffer(avctx, &s->picture); + + s->picture.reference = 0; + s->picture.key_frame = 1; + s->picture.pict_type = FF_I_TYPE; + avctx->pix_fmt = s->sys->pix_fmt; + avcodec_set_dimensions(avctx, s->sys->width, s->sys->height); + if(avctx->get_buffer(avctx, &s->picture) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + s->picture.interlaced_frame = 1; + s->picture.top_field_first = 0; + + s->buf = buf; + avctx->execute(avctx, dv_decode_mt, (void**)&dv_anchor[0], NULL, + s->sys->n_difchan * s->sys->difseg_size * 27); + + emms_c(); + + /* return image */ + *data_size = sizeof(AVFrame); + *(AVFrame*)data= s->picture; + + return s->sys->frame_size; +} + +static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size, + void *data) +{ + DVVideoContext *s = c->priv_data; + + s->sys = dv_codec_profile(c); + if (!s->sys) + return -1; + if(buf_size < s->sys->frame_size) + return -1; + + c->pix_fmt = s->sys->pix_fmt; + s->picture = *((AVFrame *)data); + s->picture.key_frame = 1; + s->picture.pict_type = FF_I_TYPE; + + s->buf = buf; + c->execute(c, dv_encode_mt, (void**)&dv_anchor[0], NULL, + s->sys->n_difchan * s->sys->difseg_size * 27); + + emms_c(); + + /* Fill in just enough of the header for dv_frame_profile() to + return the correct result, so that the frame can be decoded + correctly. The rest of the metadata is filled in by the dvvideo + avformat. (this should probably change so that encode_frame() + fills in ALL of the metadata - e.g. for Quicktime-wrapped DV + streams) */ + + /* NTSC/PAL format */ + buf[3] = s->sys->dsf ? 0x80 : 0x00; + + /* 25Mbps or 50Mbps */ + buf[80*5 + 48 + 3] = (s->sys->pix_fmt == PIX_FMT_YUV422P) ? 0x4 : 0x0; + + return s->sys->frame_size; +} + +static int dvvideo_close(AVCodecContext *c) +{ + + return 0; +} + + +#ifdef CONFIG_DVVIDEO_ENCODER +AVCodec dvvideo_encoder = { + "dvvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_DVVIDEO, + sizeof(DVVideoContext), + dvvideo_init, + dvvideo_encode_frame, + dvvideo_close, + NULL, + CODEC_CAP_DR1, + NULL +}; +#endif // CONFIG_DVVIDEO_ENCODER + +AVCodec dvvideo_decoder = { + "dvvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_DVVIDEO, + sizeof(DVVideoContext), + dvvideo_init, + NULL, + dvvideo_close, + dvvideo_decode_frame, + CODEC_CAP_DR1, + NULL +}; diff --git a/mpeg4/src/libavcodec/dvbsub.c b/mpeg4/src/libavcodec/dvbsub.c new file mode 100644 index 00000000..17601990 --- /dev/null +++ b/mpeg4/src/libavcodec/dvbsub.c @@ -0,0 +1,443 @@ +/* + * DVB subtitle encoding for ffmpeg + * Copyright (c) 2005 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avcodec.h" + +typedef struct DVBSubtitleContext { + int hide_state; + int object_version; +} DVBSubtitleContext; + +#define PUTBITS2(val)\ +{\ + bitbuf |= (val) << bitcnt;\ + bitcnt -= 2;\ + if (bitcnt < 0) {\ + bitcnt = 6;\ + *q++ = bitbuf;\ + bitbuf = 0;\ + }\ +} + +static void dvb_encode_rle2(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h) +{ + uint8_t *q; + unsigned int bitbuf; + int bitcnt; + int x, y, len, x1, v, color; + + q = *pq; + + for(y = 0; y < h; y++) { + *q++ = 0x10; + bitbuf = 0; + bitcnt = 6; + + x = 0; + while (x < w) { + x1 = x; + color = bitmap[x1++]; + while (x1 < w && bitmap[x1] == color) + x1++; + len = x1 - x; + if (color == 0 && len == 2) { + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(1); + } else if (len >= 3 && len <= 10) { + v = len - 3; + PUTBITS2(0); + PUTBITS2((v >> 2) | 2); + PUTBITS2(v & 3); + PUTBITS2(color); + } else if (len >= 12 && len <= 27) { + v = len - 12; + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(2); + PUTBITS2(v >> 2); + PUTBITS2(v & 3); + PUTBITS2(color); + } else if (len >= 29) { + /* length = 29 ... 284 */ + if (len > 284) + len = 284; + v = len - 29; + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(3); + PUTBITS2((v >> 6)); + PUTBITS2((v >> 4) & 3); + PUTBITS2((v >> 2) & 3); + PUTBITS2(v & 3); + PUTBITS2(color); + } else { + PUTBITS2(color); + if (color == 0) { + PUTBITS2(1); + } + len = 1; + } + x += len; + } + /* end of line */ + PUTBITS2(0); + PUTBITS2(0); + PUTBITS2(0); + if (bitcnt != 6) { + *q++ = bitbuf; + } + *q++ = 0xf0; + bitmap += linesize; + } + *pq = q; +} + +#define PUTBITS4(val)\ +{\ + bitbuf |= (val) << bitcnt;\ + bitcnt -= 4;\ + if (bitcnt < 0) {\ + bitcnt = 4;\ + *q++ = bitbuf;\ + bitbuf = 0;\ + }\ +} + +/* some DVB decoders only implement 4 bits/pixel */ +static void dvb_encode_rle4(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h) +{ + uint8_t *q; + unsigned int bitbuf; + int bitcnt; + int x, y, len, x1, v, color; + + q = *pq; + + for(y = 0; y < h; y++) { + *q++ = 0x11; + bitbuf = 0; + bitcnt = 4; + + x = 0; + while (x < w) { + x1 = x; + color = bitmap[x1++]; + while (x1 < w && bitmap[x1] == color) + x1++; + len = x1 - x; + if (color == 0 && len == 2) { + PUTBITS4(0); + PUTBITS4(0xd); + } else if (color == 0 && (len >= 3 && len <= 9)) { + PUTBITS4(0); + PUTBITS4(len - 2); + } else if (len >= 4 && len <= 7) { + PUTBITS4(0); + PUTBITS4(8 + len - 4); + PUTBITS4(color); + } else if (len >= 9 && len <= 24) { + PUTBITS4(0); + PUTBITS4(0xe); + PUTBITS4(len - 9); + PUTBITS4(color); + } else if (len >= 25) { + if (len > 280) + len = 280; + v = len - 25; + PUTBITS4(0); + PUTBITS4(0xf); + PUTBITS4(v >> 4); + PUTBITS4(v & 0xf); + PUTBITS4(color); + } else { + PUTBITS4(color); + if (color == 0) { + PUTBITS4(0xc); + } + len = 1; + } + x += len; + } + /* end of line */ + PUTBITS4(0); + PUTBITS4(0); + if (bitcnt != 4) { + *q++ = bitbuf; + } + *q++ = 0xf0; + bitmap += linesize; + } + *pq = q; +} + +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<> SCALEBITS) + +#define RGB_TO_U_CCIR(r1, g1, b1, shift)\ +(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ + FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V_CCIR(r1, g1, b1, shift)\ +(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ + FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +static inline void putbe16(uint8_t **pq, uint16_t v) +{ + uint8_t *q; + q = *pq; + *q++ = v >> 8; + *q++ = v; + *pq = q; +} + +static int encode_dvb_subtitles(DVBSubtitleContext *s, + uint8_t *outbuf, AVSubtitle *h) +{ + uint8_t *q, *pseg_len; + int page_id, region_id, clut_id, object_id, i, bpp_index, page_state; + + + q = outbuf; + + page_id = 1; + + if (h->num_rects == 0 || h->rects == NULL) + return -1; + + *q++ = 0x00; /* subtitle_stream_id */ + + /* page composition segment */ + + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x10; /* segment_type */ + putbe16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = 30; /* page_timeout (seconds) */ + if (s->hide_state) + page_state = 0; /* normal case */ + else + page_state = 2; /* mode change */ + /* page_version = 0 + page_state */ + *q++ = s->object_version | (page_state << 2) | 3; + + for (region_id = 0; region_id < h->num_rects; region_id++) { + *q++ = region_id; + *q++ = 0xff; /* reserved */ + putbe16(&q, h->rects[region_id].x); /* left pos */ + putbe16(&q, h->rects[region_id].y); /* top pos */ + } + + putbe16(&pseg_len, q - pseg_len - 2); + + if (!s->hide_state) { + for (clut_id = 0; clut_id < h->num_rects; clut_id++) { + + /* CLUT segment */ + + if (h->rects[clut_id].nb_colors <= 4) { + /* 2 bpp, some decoders do not support it correctly */ + bpp_index = 0; + } else if (h->rects[clut_id].nb_colors <= 16) { + /* 4 bpp, standard encoding */ + bpp_index = 1; + } else { + return -1; + } + + *q++ = 0x0f; /* sync byte */ + *q++ = 0x12; /* CLUT definition segment */ + putbe16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = clut_id; + *q++ = (0 << 4) | 0xf; /* version = 0 */ + + for(i = 0; i < h->rects[clut_id].nb_colors; i++) { + *q++ = i; /* clut_entry_id */ + *q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */ + { + int a, r, g, b; + a = (h->rects[clut_id].rgba_palette[i] >> 24) & 0xff; + r = (h->rects[clut_id].rgba_palette[i] >> 16) & 0xff; + g = (h->rects[clut_id].rgba_palette[i] >> 8) & 0xff; + b = (h->rects[clut_id].rgba_palette[i] >> 0) & 0xff; + + *q++ = RGB_TO_Y_CCIR(r, g, b); + *q++ = RGB_TO_V_CCIR(r, g, b, 0); + *q++ = RGB_TO_U_CCIR(r, g, b, 0); + *q++ = 255 - a; + } + } + + putbe16(&pseg_len, q - pseg_len - 2); + } + } + + for (region_id = 0; region_id < h->num_rects; region_id++) { + + /* region composition segment */ + + if (h->rects[region_id].nb_colors <= 4) { + /* 2 bpp, some decoders do not support it correctly */ + bpp_index = 0; + } else if (h->rects[region_id].nb_colors <= 16) { + /* 4 bpp, standard encoding */ + bpp_index = 1; + } else { + return -1; + } + + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x11; /* segment_type */ + putbe16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + *q++ = region_id; + *q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */ + putbe16(&q, h->rects[region_id].w); /* region width */ + putbe16(&q, h->rects[region_id].h); /* region height */ + *q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03; + *q++ = region_id; /* clut_id == region_id */ + *q++ = 0; /* 8 bit fill colors */ + *q++ = 0x03; /* 4 bit and 2 bit fill colors */ + + if (!s->hide_state) { + putbe16(&q, region_id); /* object_id == region_id */ + *q++ = (0 << 6) | (0 << 4); + *q++ = 0; + *q++ = 0xf0; + *q++ = 0; + } + + putbe16(&pseg_len, q - pseg_len - 2); + } + + if (!s->hide_state) { + + for (object_id = 0; object_id < h->num_rects; object_id++) { + /* Object Data segment */ + + if (h->rects[object_id].nb_colors <= 4) { + /* 2 bpp, some decoders do not support it correctly */ + bpp_index = 0; + } else if (h->rects[object_id].nb_colors <= 16) { + /* 4 bpp, standard encoding */ + bpp_index = 1; + } else { + return -1; + } + + *q++ = 0x0f; /* sync byte */ + *q++ = 0x13; + putbe16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + + putbe16(&q, object_id); + *q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0, + onject_coding_method, + non_modifying_color_flag */ + { + uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr; + void (*dvb_encode_rle)(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h); + ptop_field_len = q; + q += 2; + pbottom_field_len = q; + q += 2; + + if (bpp_index == 0) + dvb_encode_rle = dvb_encode_rle2; + else + dvb_encode_rle = dvb_encode_rle4; + + top_ptr = q; + dvb_encode_rle(&q, h->rects[object_id].bitmap, h->rects[object_id].w * 2, + h->rects[object_id].w, h->rects[object_id].h >> 1); + bottom_ptr = q; + dvb_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w, + h->rects[object_id].w * 2, h->rects[object_id].w, + h->rects[object_id].h >> 1); + + putbe16(&ptop_field_len, bottom_ptr - top_ptr); + putbe16(&pbottom_field_len, q - bottom_ptr); + } + + putbe16(&pseg_len, q - pseg_len - 2); + } + } + + /* end of display set segment */ + + *q++ = 0x0f; /* sync_byte */ + *q++ = 0x80; /* segment_type */ + putbe16(&q, page_id); + pseg_len = q; + q += 2; /* segment length */ + + putbe16(&pseg_len, q - pseg_len - 2); + + *q++ = 0xff; /* end of PES data */ + + s->object_version = (s->object_version + 1) & 0xf; + s->hide_state = !s->hide_state; + return q - outbuf; +} + +static int dvbsub_init_decoder(AVCodecContext *avctx) +{ + return 0; +} + +static int dvbsub_close_decoder(AVCodecContext *avctx) +{ + return 0; +} + +static int dvbsub_encode(AVCodecContext *avctx, + unsigned char *buf, int buf_size, void *data) +{ + DVBSubtitleContext *s = avctx->priv_data; + AVSubtitle *sub = data; + int ret; + + ret = encode_dvb_subtitles(s, buf, sub); + return ret; +} + +AVCodec dvbsub_encoder = { + "dvbsub", + CODEC_TYPE_SUBTITLE, + CODEC_ID_DVB_SUBTITLE, + sizeof(DVBSubtitleContext), + dvbsub_init_decoder, + dvbsub_encode, + dvbsub_close_decoder, +}; diff --git a/mpeg4/src/libavcodec/dvbsubdec.c b/mpeg4/src/libavcodec/dvbsubdec.c new file mode 100644 index 00000000..525f7c23 --- /dev/null +++ b/mpeg4/src/libavcodec/dvbsubdec.c @@ -0,0 +1,1631 @@ +/* + * DVB subtitle decoding for ffmpeg + * Copyright (c) 2005 Ian Caulfield. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avcodec.h" +#include "dsputil.h" +#include "bitstream.h" + +//#define DEBUG +//#define DEBUG_PACKET_CONTENTS +//#define DEBUG_SAVE_IMAGES + +#define DVBSUB_PAGE_SEGMENT 0x10 +#define DVBSUB_REGION_SEGMENT 0x11 +#define DVBSUB_CLUT_SEGMENT 0x12 +#define DVBSUB_OBJECT_SEGMENT 0x13 +#define DVBSUB_DISPLAY_SEGMENT 0x80 + +static unsigned char *cm; + +#ifdef DEBUG_SAVE_IMAGES +#undef fprintf +#if 0 +static void png_save(const char *filename, uint8_t *bitmap, int w, int h, + uint32_t *rgba_palette) +{ + int x, y, v; + FILE *f; + char fname[40], fname2[40]; + char command[1024]; + + snprintf(fname, 40, "%s.ppm", filename); + + f = fopen(fname, "w"); + if (!f) { + perror(fname); + exit(1); + } + fprintf(f, "P6\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = rgba_palette[bitmap[y * w + x]]; + putc((v >> 16) & 0xff, f); + putc((v >> 8) & 0xff, f); + putc((v >> 0) & 0xff, f); + } + } + fclose(f); + + + snprintf(fname2, 40, "%s-a.pgm", filename); + + f = fopen(fname2, "w"); + if (!f) { + perror(fname2); + exit(1); + } + fprintf(f, "P5\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = rgba_palette[bitmap[y * w + x]]; + putc((v >> 24) & 0xff, f); + } + } + fclose(f); + + snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); + system(command); + + snprintf(command, 1024, "rm %s %s", fname, fname2); + system(command); +} +#endif + +static void png_save2(const char *filename, uint32_t *bitmap, int w, int h) +{ + int x, y, v; + FILE *f; + char fname[40], fname2[40]; + char command[1024]; + + snprintf(fname, 40, "%s.ppm", filename); + + f = fopen(fname, "w"); + if (!f) { + perror(fname); + exit(1); + } + fprintf(f, "P6\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = bitmap[y * w + x]; + putc((v >> 16) & 0xff, f); + putc((v >> 8) & 0xff, f); + putc((v >> 0) & 0xff, f); + } + } + fclose(f); + + + snprintf(fname2, 40, "%s-a.pgm", filename); + + f = fopen(fname2, "w"); + if (!f) { + perror(fname2); + exit(1); + } + fprintf(f, "P5\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = bitmap[y * w + x]; + putc((v >> 24) & 0xff, f); + } + } + fclose(f); + + snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename); + system(command); + + snprintf(command, 1024, "rm %s %s", fname, fname2); + system(command); +} +#endif + +#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +typedef struct DVBSubCLUT { + int id; + + uint32_t clut4[4]; + uint32_t clut16[16]; + uint32_t clut256[256]; + + struct DVBSubCLUT *next; +} DVBSubCLUT; + +static DVBSubCLUT default_clut; + +typedef struct DVBSubObjectDisplay { + int object_id; + int region_id; + + int x_pos; + int y_pos; + + int fgcolour; + int bgcolour; + + struct DVBSubObjectDisplay *region_list_next; + struct DVBSubObjectDisplay *object_list_next; +} DVBSubObjectDisplay; + +typedef struct DVBSubObject { + int id; + + int type; + + DVBSubObjectDisplay *display_list; + + struct DVBSubObject *next; +} DVBSubObject; + +typedef struct DVBSubRegionDisplay { + int region_id; + + int x_pos; + int y_pos; + + struct DVBSubRegionDisplay *next; +} DVBSubRegionDisplay; + +typedef struct DVBSubRegion { + int id; + + int width; + int height; + int depth; + + int clut; + int bgcolour; + + uint8_t *pbuf; + int buf_size; + + DVBSubObjectDisplay *display_list; + + struct DVBSubRegion *next; +} DVBSubRegion; + +typedef struct DVBSubContext { + int composition_id; + int ancillary_id; + + int time_out; + DVBSubRegion *region_list; + DVBSubCLUT *clut_list; + DVBSubObject *object_list; + + int display_list_size; + DVBSubRegionDisplay *display_list; +} DVBSubContext; + + +static DVBSubObject* get_object(DVBSubContext *ctx, int object_id) +{ + DVBSubObject *ptr = ctx->object_list; + + while (ptr != NULL && ptr->id != object_id) { + ptr = ptr->next; + } + + return ptr; +} + +static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id) +{ + DVBSubCLUT *ptr = ctx->clut_list; + + while (ptr != NULL && ptr->id != clut_id) { + ptr = ptr->next; + } + + return ptr; +} + +static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id) +{ + DVBSubRegion *ptr = ctx->region_list; + + while (ptr != NULL && ptr->id != region_id) { + ptr = ptr->next; + } + + return ptr; +} + +static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region) +{ + DVBSubObject *object, *obj2, **obj2_ptr; + DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr; + + while (region->display_list != NULL) { + display = region->display_list; + + object = get_object(ctx, display->object_id); + + if (object != NULL) { + obj_disp = object->display_list; + obj_disp_ptr = &object->display_list; + + while (obj_disp != NULL && obj_disp != display) { + obj_disp_ptr = &obj_disp->object_list_next; + obj_disp = obj_disp->object_list_next; + } + + if (obj_disp) { + *obj_disp_ptr = obj_disp->object_list_next; + + if (object->display_list == NULL) { + obj2 = ctx->object_list; + obj2_ptr = &ctx->object_list; + + while (obj2 != NULL && obj2 != object) { + obj2_ptr = &obj2->next; + obj2 = obj2->next; + } + + *obj2_ptr = obj2->next; + + av_free(obj2); + } + } + } + + region->display_list = display->region_list_next; + + av_free(display); + } + +} + +static void delete_state(DVBSubContext *ctx) +{ + DVBSubRegion *region; + DVBSubCLUT *clut; + + while (ctx->region_list != NULL) + { + region = ctx->region_list; + + ctx->region_list = region->next; + + delete_region_display_list(ctx, region); + if (region->pbuf != NULL) + av_free(region->pbuf); + + av_free(region); + } + + while (ctx->clut_list != NULL) + { + clut = ctx->clut_list; + + ctx->clut_list = clut->next; + + av_free(clut); + } + + /* Should already be null */ + if (ctx->object_list != NULL) + av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n"); +} + +static int dvbsub_init_decoder(AVCodecContext *avctx) +{ + int i, r, g, b, a = 0; + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + cm = cropTbl + MAX_NEG_CROP; + + memset(avctx->priv_data, 0, sizeof(DVBSubContext)); + + ctx->composition_id = avctx->sub_id & 0xffff; + ctx->ancillary_id = avctx->sub_id >> 16; + + default_clut.id = -1; + default_clut.next = NULL; + + default_clut.clut4[0] = RGBA( 0, 0, 0, 0); + default_clut.clut4[1] = RGBA(255, 255, 255, 255); + default_clut.clut4[2] = RGBA( 0, 0, 0, 255); + default_clut.clut4[3] = RGBA(127, 127, 127, 255); + + default_clut.clut16[0] = RGBA( 0, 0, 0, 0); + for (i = 1; i < 16; i++) { + if (i < 8) { + r = (i & 1) ? 255 : 0; + g = (i & 2) ? 255 : 0; + b = (i & 4) ? 255 : 0; + } else { + r = (i & 1) ? 127 : 0; + g = (i & 2) ? 127 : 0; + b = (i & 4) ? 127 : 0; + } + default_clut.clut16[i] = RGBA(r, g, b, 255); + } + + default_clut.clut256[0] = RGBA( 0, 0, 0, 0); + for (i = 1; i < 256; i++) { + if (i < 8) { + r = (i & 1) ? 255 : 0; + g = (i & 2) ? 255 : 0; + b = (i & 4) ? 255 : 0; + a = 63; + } else { + switch (i & 0x88) { + case 0x00: + r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0); + g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0); + b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0); + a = 255; + break; + case 0x08: + r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0); + g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0); + b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0); + a = 127; + break; + case 0x80: + r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0); + g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0); + b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0); + a = 255; + break; + case 0x88: + r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0); + g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0); + b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0); + a = 255; + break; + } + } + default_clut.clut256[i] = RGBA(r, g, b, a); + } + + return 0; +} + +static int dvbsub_close_decoder(AVCodecContext *avctx) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + DVBSubRegionDisplay *display; + + delete_state(ctx); + + while (ctx->display_list != NULL) + { + display = ctx->display_list; + ctx->display_list = display->next; + + av_free(display); + } + + return 0; +} + +static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len, + uint8_t **srcbuf, int buf_size, + int non_mod, uint8_t *map_table) +{ + GetBitContext gb; + + int bits; + int run_length; + int pixels_read = 0; + + init_get_bits(&gb, *srcbuf, buf_size << 8); + + while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) { + bits = get_bits(&gb, 2); + + if (bits != 0) { + if (non_mod != 1 || bits != 1) { + if (map_table != NULL) + *destbuf++ = map_table[bits]; + else + *destbuf++ = bits; + } + pixels_read++; + } else { + bits = get_bits(&gb, 1); + if (bits == 1) { + run_length = get_bits(&gb, 3) + 3; + bits = get_bits(&gb, 2); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table != NULL) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else { + bits = get_bits(&gb, 1); + if (bits == 0) { + bits = get_bits(&gb, 2); + if (bits == 2) { + run_length = get_bits(&gb, 4) + 12; + bits = get_bits(&gb, 2); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table != NULL) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else if (bits == 3) { + run_length = get_bits(&gb, 8) + 29; + bits = get_bits(&gb, 2); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table != NULL) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else if (bits == 1) { + pixels_read += 2; + if (map_table != NULL) + bits = map_table[0]; + else + bits = 0; + if (pixels_read <= dbuf_len) { + *destbuf++ = bits; + *destbuf++ = bits; + } + } else { + (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + return pixels_read; + } + } else { + if (map_table != NULL) + bits = map_table[0]; + else + bits = 0; + *destbuf++ = bits; + pixels_read++; + } + } + } + } + + if (get_bits(&gb, 6) != 0) + av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); + + (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + + return pixels_read; +} + +static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len, + uint8_t **srcbuf, int buf_size, + int non_mod, uint8_t *map_table) +{ + GetBitContext gb; + + int bits; + int run_length; + int pixels_read = 0; + + init_get_bits(&gb, *srcbuf, buf_size << 8); + + while (get_bits_count(&gb) < (buf_size << 8) && pixels_read < dbuf_len) { + bits = get_bits(&gb, 4); + + if (bits != 0) { + if (non_mod != 1 || bits != 1) { + if (map_table != NULL) + *destbuf++ = map_table[bits]; + else + *destbuf++ = bits; + } + pixels_read++; + } else { + bits = get_bits(&gb, 1); + if (bits == 0) { + run_length = get_bits(&gb, 3); + + if (run_length == 0) { + (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + return pixels_read; + } + + run_length += 2; + + if (map_table != NULL) + bits = map_table[0]; + else + bits = 0; + + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } else { + bits = get_bits(&gb, 1); + if (bits == 0) { + run_length = get_bits(&gb, 2) + 4; + bits = get_bits(&gb, 4); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table != NULL) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else { + bits = get_bits(&gb, 2); + if (bits == 2) { + run_length = get_bits(&gb, 4) + 9; + bits = get_bits(&gb, 4); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table != NULL) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else if (bits == 3) { + run_length = get_bits(&gb, 8) + 25; + bits = get_bits(&gb, 4); + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + else { + if (map_table != NULL) + bits = map_table[bits]; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } else if (bits == 1) { + pixels_read += 2; + if (map_table != NULL) + bits = map_table[0]; + else + bits = 0; + if (pixels_read <= dbuf_len) { + *destbuf++ = bits; + *destbuf++ = bits; + } + } else { + if (map_table != NULL) + bits = map_table[0]; + else + bits = 0; + *destbuf++ = bits; + pixels_read ++; + } + } + } + } + } + + if (get_bits(&gb, 8) != 0) + av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); + + (*srcbuf) += (get_bits_count(&gb) + 7) >> 3; + + return pixels_read; +} + +static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len, + uint8_t **srcbuf, int buf_size, + int non_mod, uint8_t *map_table) +{ + uint8_t *sbuf_end = (*srcbuf) + buf_size; + int bits; + int run_length; + int pixels_read = 0; + + while (*srcbuf < sbuf_end && pixels_read < dbuf_len) { + bits = *(*srcbuf)++; + + if (bits != 0) { + if (non_mod != 1 || bits != 1) { + if (map_table != NULL) + *destbuf++ = map_table[bits]; + else + *destbuf++ = bits; + } + pixels_read++; + } else { + bits = *(*srcbuf)++; + run_length = bits & 0x7f; + if ((bits & 0x80) == 0) { + if (run_length == 0) { + return pixels_read; + } + + if (map_table != NULL) + bits = map_table[0]; + else + bits = 0; + while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } else { + bits = *(*srcbuf)++; + + if (non_mod == 1 && bits == 1) + pixels_read += run_length; + if (map_table != NULL) + bits = map_table[bits]; + else while (run_length-- > 0 && pixels_read < dbuf_len) { + *destbuf++ = bits; + pixels_read++; + } + } + } + } + + if (*(*srcbuf)++ != 0) + av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n"); + + return pixels_read; +} + + + +static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display, + uint8_t *buf, int buf_size, int top_bottom, int non_mod) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + DVBSubRegion *region = get_region(ctx, display->region_id); + uint8_t *buf_end = buf + buf_size; + uint8_t *pbuf; + int x_pos, y_pos; + int i; + + uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf}; + uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff}; + uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + uint8_t *map_table; + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "DVB pixel block size %d, %s field:\n", buf_size, + top_bottom ? "bottom" : "top"); +#endif + +#ifdef DEBUG_PACKET_CONTENTS + for (i = 0; i < buf_size; i++) + { + if (i % 16 == 0) + av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i); + + av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); + if (i % 16 == 15) + av_log(avctx, AV_LOG_INFO, "\n"); + } + + if (i % 16 != 0) + av_log(avctx, AV_LOG_INFO, "\n"); + +#endif + + if (region == 0) + return; + + pbuf = region->pbuf; + + x_pos = display->x_pos; + y_pos = display->y_pos; + + if ((y_pos & 1) != top_bottom) + y_pos++; + + while (buf < buf_end) { + if (x_pos > region->width || y_pos > region->height) { + av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n"); + return; + } + + switch (*buf++) { + case 0x10: + if (region->depth == 8) + map_table = map2to8; + else if (region->depth == 4) + map_table = map2to4; + else + map_table = NULL; + + x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos, + region->width - x_pos, &buf, buf_size, + non_mod, map_table); + break; + case 0x11: + if (region->depth < 4) { + av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth); + return; + } + + if (region->depth == 8) + map_table = map4to8; + else + map_table = NULL; + + x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos, + region->width - x_pos, &buf, buf_size, + non_mod, map_table); + break; + case 0x12: + if (region->depth < 8) { + av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth); + return; + } + + x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos, + region->width - x_pos, &buf, buf_size, + non_mod, NULL); + break; + + case 0x20: + map2to4[0] = (*buf) >> 4; + map2to4[1] = (*buf++) & 0xf; + map2to4[2] = (*buf) >> 4; + map2to4[3] = (*buf++) & 0xf; + break; + case 0x21: + for (i = 0; i < 4; i++) + map2to8[i] = *buf++; + break; + case 0x22: + for (i = 0; i < 16; i++) + map4to8[i] = *buf++; + break; + + case 0xf0: + x_pos = display->x_pos; + y_pos += 2; + break; + default: + av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1)); + } + } + +} + +static void dvbsub_parse_object_segment(AVCodecContext *avctx, + uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + uint8_t *buf_end = buf + buf_size; + uint8_t *block; + int object_id; + DVBSubObject *object; + DVBSubObjectDisplay *display; + int top_field_len, bottom_field_len; + + int coding_method, non_modifying_colour; + + object_id = BE_16(buf); + buf += 2; + + object = get_object(ctx, object_id); + + if (!object) + return; + + coding_method = ((*buf) >> 2) & 3; + non_modifying_colour = ((*buf++) >> 1) & 1; + + if (coding_method == 0) { + top_field_len = BE_16(buf); + buf += 2; + bottom_field_len = BE_16(buf); + buf += 2; + + if (buf + top_field_len + bottom_field_len > buf_end) { + av_log(avctx, AV_LOG_ERROR, "Field data size too large\n"); + return; + } + + for (display = object->display_list; display != 0; display = display->object_list_next) { + block = buf; + + dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0, + non_modifying_colour); + + if (bottom_field_len > 0) + block = buf + top_field_len; + else + bottom_field_len = top_field_len; + + dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1, + non_modifying_colour); + } + +/* } else if (coding_method == 1) {*/ + + } else { + av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method); + } + +} + +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<> SCALEBITS];\ + g = cm[(y + g_add) >> SCALEBITS];\ + b = cm[(y + b_add) >> SCALEBITS];\ +} + + +static void dvbsub_parse_clut_segment(AVCodecContext *avctx, + uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + uint8_t *buf_end = buf + buf_size; + int clut_id; + DVBSubCLUT *clut; + int entry_id, depth , full_range; + int y, cr, cb, alpha; + int r, g, b, r_add, g_add, b_add; + +#ifdef DEBUG_PACKET_CONTENTS + int i; + + av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n"); + + for (i=0; i < buf_size; i++) + { + av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); + if (i % 16 == 15) + av_log(avctx, AV_LOG_INFO, "\n"); + } + + if (i % 16 != 0) + av_log(avctx, AV_LOG_INFO, "\n"); + +#endif + + clut_id = *buf++; + buf += 1; + + clut = get_clut(ctx, clut_id); + + if (clut == NULL) { + clut = av_malloc(sizeof(DVBSubCLUT)); + + memcpy(clut, &default_clut, sizeof(DVBSubCLUT)); + + clut->id = clut_id; + + clut->next = ctx->clut_list; + ctx->clut_list = clut; + } + + while (buf + 4 < buf_end) + { + entry_id = *buf++; + + depth = (*buf) & 0xe0; + + if (depth == 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf); + return; + } + + full_range = (*buf++) & 1; + + if (full_range) { + y = *buf++; + cr = *buf++; + cb = *buf++; + alpha = *buf++; + } else { + y = buf[0] & 0xfc; + cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4; + cb = (buf[1] << 2) & 0xf0; + alpha = (buf[1] << 6) & 0xc0; + + buf += 2; + } + + if (y == 0) + alpha = 0xff; + + YUV_TO_RGB1_CCIR(cb, cr); + YUV_TO_RGB2_CCIR(r, g, b, y); + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha); +#endif + + if (depth & 0x80) + clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha); + if (depth & 0x40) + clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha); + if (depth & 0x20) + clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha); + } +} + + +static void dvbsub_parse_region_segment(AVCodecContext *avctx, + uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + uint8_t *buf_end = buf + buf_size; + int region_id, object_id; + DVBSubRegion *region; + DVBSubObject *object; + DVBSubObjectDisplay *display; + int fill; + + if (buf_size < 10) + return; + + region_id = *buf++; + + region = get_region(ctx, region_id); + + if (region == NULL) + { + region = av_mallocz(sizeof(DVBSubRegion)); + + region->id = region_id; + + region->next = ctx->region_list; + ctx->region_list = region; + } + + fill = ((*buf++) >> 3) & 1; + + region->width = BE_16(buf); + buf += 2; + region->height = BE_16(buf); + buf += 2; + + if (region->width * region->height != region->buf_size) { + if (region->pbuf != 0) + av_free(region->pbuf); + + region->buf_size = region->width * region->height; + + region->pbuf = av_malloc(region->buf_size); + + fill = 1; + } + + region->depth = 1 << (((*buf++) >> 2) & 7); + region->clut = *buf++; + + if (region->depth == 8) + region->bgcolour = *buf++; + else { + buf += 1; + + if (region->depth == 4) + region->bgcolour = (((*buf++) >> 4) & 15); + else + region->bgcolour = (((*buf++) >> 2) & 3); + } + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Region %d, (%dx%d)\n", region_id, region->width, region->height); +#endif + + if (fill) { + memset(region->pbuf, region->bgcolour, region->buf_size); +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Fill region (%d)\n", region->bgcolour); +#endif + } + + delete_region_display_list(ctx, region); + + while (buf + 5 < buf_end) { + object_id = BE_16(buf); + buf += 2; + + object = get_object(ctx, object_id); + + if (object == NULL) { + object = av_mallocz(sizeof(DVBSubObject)); + + object->id = object_id; + object->next = ctx->object_list; + ctx->object_list = object; + } + + object->type = (*buf) >> 6; + + display = av_mallocz(sizeof(DVBSubObjectDisplay)); + + display->object_id = object_id; + display->region_id = region_id; + + display->x_pos = BE_16(buf) & 0xfff; + buf += 2; + display->y_pos = BE_16(buf) & 0xfff; + buf += 2; + + if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) { + display->fgcolour = *buf++; + display->bgcolour = *buf++; + } + + display->region_list_next = region->display_list; + region->display_list = display; + + display->object_list_next = object->display_list; + object->display_list = display; + } +} + +static void dvbsub_parse_page_segment(AVCodecContext *avctx, + uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + DVBSubRegionDisplay *display; + DVBSubRegionDisplay *tmp_display_list, **tmp_ptr; + + uint8_t *buf_end = buf + buf_size; + int region_id; + int page_state; + + if (buf_size < 1) + return; + + ctx->time_out = *buf++; + page_state = ((*buf++) >> 2) & 3; + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Page time out %ds, state %d\n", ctx->time_out, page_state); +#endif + + if (page_state == 2) + { + delete_state(ctx); + } + + tmp_display_list = ctx->display_list; + ctx->display_list = NULL; + ctx->display_list_size = 0; + + while (buf + 5 < buf_end) { + region_id = *buf++; + buf += 1; + + display = tmp_display_list; + tmp_ptr = &tmp_display_list; + + while (display != NULL && display->region_id != region_id) { + tmp_ptr = &display->next; + display = display->next; + } + + if (display == NULL) + display = av_mallocz(sizeof(DVBSubRegionDisplay)); + + display->region_id = region_id; + + display->x_pos = BE_16(buf); + buf += 2; + display->y_pos = BE_16(buf); + buf += 2; + + *tmp_ptr = display->next; + + display->next = ctx->display_list; + ctx->display_list = display; + ctx->display_list_size++; + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos); +#endif + } + + while (tmp_display_list != 0) { + display = tmp_display_list; + + tmp_display_list = display->next; + + av_free(display); + } + +} + + +#ifdef DEBUG_SAVE_IMAGES +static void save_display_set(DVBSubContext *ctx) +{ + DVBSubRegion *region; + DVBSubRegionDisplay *display; + DVBSubCLUT *clut; + uint32_t *clut_table; + int x_pos, y_pos, width, height; + int x, y, y_off, x_off; + uint32_t *pbuf; + char filename[32]; + static int fileno_index = 0; + + x_pos = -1; + y_pos = -1; + width = 0; + height = 0; + + for (display = ctx->display_list; display != NULL; display = display->next) { + region = get_region(ctx, display->region_id); + + if (x_pos == -1) { + x_pos = display->x_pos; + y_pos = display->y_pos; + width = region->width; + height = region->height; + } else { + if (display->x_pos < x_pos) { + width += (x_pos - display->x_pos); + x_pos = display->x_pos; + } + + if (display->y_pos < y_pos) { + height += (y_pos - display->y_pos); + y_pos = display->y_pos; + } + + if (display->x_pos + region->width > x_pos + width) { + width = display->x_pos + region->width - x_pos; + } + + if (display->y_pos + region->height > y_pos + height) { + height = display->y_pos + region->height - y_pos; + } + } + } + + if (x_pos >= 0) { + + pbuf = av_malloc(width * height * 4); + + for (display = ctx->display_list; display != NULL; display = display->next) { + region = get_region(ctx, display->region_id); + + x_off = display->x_pos - x_pos; + y_off = display->y_pos - y_pos; + + clut = get_clut(ctx, region->clut); + + if (clut == 0) + clut = &default_clut; + + switch (region->depth) { + case 2: + clut_table = clut->clut4; + break; + case 8: + clut_table = clut->clut256; + break; + case 4: + default: + clut_table = clut->clut16; + break; + } + + for (y = 0; y < region->height; y++) { + for (x = 0; x < region->width; x++) { + pbuf[((y + y_off) * width) + x_off + x] = + clut_table[region->pbuf[y * region->width + x]]; + } + } + + } + + snprintf(filename, 32, "dvbs.%d", fileno_index); + + png_save2(filename, pbuf, width, height); + + av_free(pbuf); + } + + fileno_index++; +} +#endif + +static int dvbsub_display_end_segment(AVCodecContext *avctx, uint8_t *buf, + int buf_size, AVSubtitle *sub) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + + DVBSubRegion *region; + DVBSubRegionDisplay *display; + AVSubtitleRect *rect; + DVBSubCLUT *clut; + uint32_t *clut_table; + int i; + + sub->rects = NULL; + sub->start_display_time = 0; + sub->end_display_time = ctx->time_out * 1000; + sub->format = 0; + + sub->num_rects = ctx->display_list_size; + + if (sub->num_rects > 0) + sub->rects = av_mallocz(sizeof(AVSubtitleRect) * sub->num_rects); + + i = 0; + + for (display = ctx->display_list; display != NULL; display = display->next) { + region = get_region(ctx, display->region_id); + rect = &sub->rects[i]; + + if (region == NULL) + continue; + + rect->x = display->x_pos; + rect->y = display->y_pos; + rect->w = region->width; + rect->h = region->height; + rect->nb_colors = 16; + rect->linesize = region->width; + + clut = get_clut(ctx, region->clut); + + if (clut == NULL) + clut = &default_clut; + + switch (region->depth) { + case 2: + clut_table = clut->clut4; + break; + case 8: + clut_table = clut->clut256; + break; + case 4: + default: + clut_table = clut->clut16; + break; + } + + rect->rgba_palette = av_malloc((1 << region->depth) * sizeof(uint32_t)); + memcpy(rect->rgba_palette, clut_table, (1 << region->depth) * sizeof(uint32_t)); + + rect->bitmap = av_malloc(region->buf_size); + memcpy(rect->bitmap, region->pbuf, region->buf_size); + + i++; + } + + sub->num_rects = i; + +#ifdef DEBUG_SAVE_IMAGES + save_display_set(ctx); +#endif + + return 1; +} + +static int dvbsub_decode(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + DVBSubContext *ctx = (DVBSubContext*) avctx->priv_data; + AVSubtitle *sub = (AVSubtitle*) data; + uint8_t *p, *p_end; + int segment_type; + int page_id; + int segment_length; + +#ifdef DEBUG_PACKET_CONTENTS + int i; + + av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n"); + + for (i=0; i < buf_size; i++) + { + av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); + if (i % 16 == 15) + av_log(avctx, AV_LOG_INFO, "\n"); + } + + if (i % 16 != 0) + av_log(avctx, AV_LOG_INFO, "\n"); + +#endif + + if (buf_size <= 2) + return -1; + + p = buf; + p_end = buf + buf_size; + + while (p < p_end && *p == 0x0f) + { + p += 1; + segment_type = *p++; + page_id = BE_16(p); + p += 2; + segment_length = BE_16(p); + p += 2; + + if (page_id == ctx->composition_id || page_id == ctx->ancillary_id) { + switch (segment_type) { + case DVBSUB_PAGE_SEGMENT: + dvbsub_parse_page_segment(avctx, p, segment_length); + break; + case DVBSUB_REGION_SEGMENT: + dvbsub_parse_region_segment(avctx, p, segment_length); + break; + case DVBSUB_CLUT_SEGMENT: + dvbsub_parse_clut_segment(avctx, p, segment_length); + break; + case DVBSUB_OBJECT_SEGMENT: + dvbsub_parse_object_segment(avctx, p, segment_length); + break; + case DVBSUB_DISPLAY_SEGMENT: + *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub); + break; + default: +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Subtitling segment type 0x%x, page id %d, length %d\n", + segment_type, page_id, segment_length); +#endif + break; + } + } + + p += segment_length; + } + + if (p != p_end) + { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n"); +#endif + return -1; + } + + return buf_size; +} + + +AVCodec dvbsub_decoder = { + "dvbsub", + CODEC_TYPE_SUBTITLE, + CODEC_ID_DVB_SUBTITLE, + sizeof(DVBSubContext), + dvbsub_init_decoder, + NULL, + dvbsub_close_decoder, + dvbsub_decode, +}; + +/* Parser (mostly) copied from dvdsub.c */ + +#define PARSE_BUF_SIZE (65536) + + +/* parser definition */ +typedef struct DVBSubParseContext { + uint8_t *packet_buf; + int packet_start; + int packet_index; + int in_packet; +} DVBSubParseContext; + +static int dvbsub_parse_init(AVCodecParserContext *s) +{ + DVBSubParseContext *pc = s->priv_data; + pc->packet_buf = av_malloc(PARSE_BUF_SIZE); + + return 0; +} + +static int dvbsub_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + DVBSubParseContext *pc = s->priv_data; + uint8_t *p, *p_end; + int len, buf_pos = 0; + +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "DVB parse packet pts=%Lx, lpts=%Lx, cpts=%Lx:\n", + s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]); +#endif + +#ifdef DEBUG_PACKET_CONTENTS + int i; + + for (i=0; i < buf_size; i++) + { + av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]); + if (i % 16 == 15) + av_log(avctx, AV_LOG_INFO, "\n"); + } + + if (i % 16 != 0) + av_log(avctx, AV_LOG_INFO, "\n"); + +#endif + + *poutbuf = NULL; + *poutbuf_size = 0; + + s->fetch_timestamp = 1; + + if (s->last_pts != s->pts && s->last_pts != AV_NOPTS_VALUE) /* Start of a new packet */ + { + if (pc->packet_index != pc->packet_start) + { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Discarding %d bytes\n", + pc->packet_index - pc->packet_start); +#endif + } + + pc->packet_start = 0; + pc->packet_index = 0; + + if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Bad packet header\n"); +#endif + return -1; + } + + buf_pos = 2; + + pc->in_packet = 1; + } else { + if (pc->packet_start != 0) + { + if (pc->packet_index != pc->packet_start) + { + memmove(pc->packet_buf, pc->packet_buf + pc->packet_start, + pc->packet_index - pc->packet_start); + + pc->packet_index -= pc->packet_start; + pc->packet_start = 0; + } else { + pc->packet_start = 0; + pc->packet_index = 0; + } + } + } + + if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE) + return -1; + +/* if not currently in a packet, discard data */ + if (pc->in_packet == 0) + return buf_size; + + memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos); + pc->packet_index += buf_size - buf_pos; + + p = pc->packet_buf; + p_end = pc->packet_buf + pc->packet_index; + + while (p < p_end) + { + if (*p == 0x0f) + { + if (p + 6 <= p_end) + { + len = BE_16(p + 4); + + if (p + len + 6 <= p_end) + { + *poutbuf_size += len + 6; + + p += len + 6; + } else + break; + } else + break; + } else if (*p == 0xff) { + if (p + 1 < p_end) + { +#ifdef DEBUG + av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n"); +#endif + } + pc->packet_index = p - pc->packet_buf; + pc->in_packet = 0; + break; + } else { + av_log(avctx, AV_LOG_ERROR, "Junk in packet\n"); + + pc->packet_index = p - pc->packet_buf; + pc->in_packet = 0; + break; + } + } + + if (*poutbuf_size > 0) + { + *poutbuf = pc->packet_buf; + pc->packet_start = *poutbuf_size; + } + + if (s->last_pts == AV_NOPTS_VALUE) + s->last_pts = s->pts; + + return buf_size; +} + +static void dvbsub_parse_close(AVCodecParserContext *s) +{ + DVBSubParseContext *pc = s->priv_data; + av_freep(&pc->packet_buf); +} + +AVCodecParser dvbsub_parser = { + { CODEC_ID_DVB_SUBTITLE }, + sizeof(DVBSubParseContext), + dvbsub_parse_init, + dvbsub_parse, + dvbsub_parse_close, +}; diff --git a/mpeg4/src/libavcodec/dvdata.h b/mpeg4/src/libavcodec/dvdata.h new file mode 100644 index 00000000..a3d42d66 --- /dev/null +++ b/mpeg4/src/libavcodec/dvdata.h @@ -0,0 +1,2665 @@ +/* + * Constants for DV codec + * Copyright (c) 2002 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file dvdata.h + * Constants for DV codec. + */ + +/* + * DVprofile is used to express the differences between various + * DV flavors. For now it's primarily used for differentiating + * 525/60 and 625/50, but the plans are to use it for various + * DV specs as well (e.g. SMPTE314M vs. IEC 61834). + */ +typedef struct DVprofile { + int dsf; /* value of the dsf in the DV header */ + int frame_size; /* total size of one frame in bytes */ + int difseg_size; /* number of DIF segments per DIF channel */ + int n_difchan; /* number of DIF channels per frame */ + int frame_rate; + int frame_rate_base; + int ltc_divisor; /* FPS from the LTS standpoint */ + int height; /* picture height in pixels */ + int width; /* picture width in pixels */ + AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */ + const uint16_t *video_place; /* positions of all DV macro blocks */ + enum PixelFormat pix_fmt; /* picture pixel format */ + + int audio_stride; /* size of audio_shuffle table */ + int audio_min_samples[3];/* min ammount of audio samples */ + /* for 48Khz, 44.1Khz and 32Khz */ + int audio_samples_dist[5];/* how many samples are supposed to be */ + /* in each frame in a 5 frames window */ + const uint16_t (*audio_shuffle)[9]; /* PCM shuffling table */ +} DVprofile; + +#define NB_DV_VLC 409 + +/* + * There's a catch about the following three tables: the mapping they establish + * between (run, level) and vlc is not 1-1. So you have to watch out for that + * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82. + */ +static const uint16_t dv_vlc_bits[409] = { + 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016, + 0x0017, 0x0030, 0x0031, 0x0032, 0x0033, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00e0, 0x00e1, 0x00e2, + 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, + 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x01e0, 0x01e1, 0x01e2, + 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea, + 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x03e0, 0x03e1, 0x03e2, + 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x07ce, 0x07cf, 0x07d0, 0x07d1, + 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x0fac, 0x0fad, 0x0fae, 0x0faf, + 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, + 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, + 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, + 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, + 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, + 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, + 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, + 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, + 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7, + 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf, + 0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07, + 0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f, + 0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17, + 0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f, + 0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27, + 0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f, + 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37, + 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f, + 0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47, + 0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f, + 0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57, + 0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f, + 0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67, + 0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f, + 0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77, + 0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f, + 0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87, + 0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f, + 0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97, + 0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f, + 0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7, + 0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf, + 0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7, + 0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf, + 0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7, + 0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf, + 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7, + 0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf, + 0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7, + 0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef, + 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, + 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff, + 0x0006, +}; + +static const uint8_t dv_vlc_len[409] = { + 2, 3, 4, 4, 4, 5, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 10, 10, 10, + 10, 10, 10, 10, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, + 4, +}; + +static const uint8_t dv_vlc_run[409] = { + 0, 0, 1, 0, 0, 2, 1, 0, + 0, 3, 4, 0, 0, 5, 6, 2, + 1, 1, 0, 0, 0, 7, 8, 9, + 10, 3, 4, 2, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 11, 12, 13, + 14, 5, 6, 3, 4, 2, 2, 1, + 0, 0, 0, 0, 0, 5, 3, 3, + 2, 1, 1, 1, 0, 1, 6, 4, + 3, 1, 1, 1, 2, 3, 4, 5, + 7, 8, 9, 10, 7, 8, 4, 3, + 2, 2, 2, 2, 2, 1, 1, 1, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +127, +}; + +static const uint8_t dv_vlc_level[409] = { + 1, 2, 1, 3, 4, 1, 2, 5, + 6, 1, 1, 7, 8, 1, 1, 2, + 3, 4, 9, 10, 11, 1, 1, 1, + 1, 2, 2, 3, 5, 6, 7, 12, + 13, 14, 15, 16, 17, 1, 1, 1, + 1, 2, 2, 3, 3, 4, 5, 8, + 18, 19, 20, 21, 22, 3, 4, 5, + 6, 9, 10, 11, 0, 0, 3, 4, + 6, 12, 13, 14, 0, 0, 0, 0, + 2, 2, 2, 2, 3, 3, 5, 7, + 7, 8, 9, 10, 11, 15, 16, 17, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + 0, +}; + +/* unquant tables (not used directly) */ +static const uint8_t dv_88_areas[64] = { + 0,0,0,1,1,1,2,2, + 0,0,1,1,1,2,2,2, + 0,1,1,1,2,2,2,3, + 1,1,1,2,2,2,3,3, + 1,1,2,2,2,3,3,3, + 1,2,2,2,3,3,3,3, + 2,2,2,3,3,3,3,3, + 2,2,3,3,3,3,3,3, +}; + +static const uint8_t dv_248_areas[64] = { + 0,0,1,1,1,2,2,3, + 0,0,1,1,2,2,2,3, + 0,1,1,2,2,2,3,3, + 0,1,1,2,2,2,3,3, + 1,1,2,2,2,3,3,3, + 1,1,2,2,2,3,3,3, + 1,2,2,2,3,3,3,3, + 1,2,2,3,3,3,3,3, +}; + +static const uint8_t dv_quant_shifts[22][4] = { + { 3,3,4,4 }, + { 3,3,4,4 }, + { 2,3,3,4 }, + { 2,3,3,4 }, + { 2,2,3,3 }, + { 2,2,3,3 }, + { 1,2,2,3 }, + { 1,2,2,3 }, + { 1,1,2,2 }, + { 1,1,2,2 }, + { 0,1,1,2 }, + { 0,1,1,2 }, + { 0,0,1,1 }, + { 0,0,1,1 }, + { 0,0,0,1 }, + { 0,0,0,0 }, + { 0,0,0,0 }, + { 0,0,0,0 }, + { 0,0,0,0 }, + { 0,0,0,0 }, + { 0,0,0,0 }, + { 0,0,0,0 }, +}; + +static const uint8_t dv_quant_offset[4] = { 6, 3, 0, 1 }; + +/* NOTE: I prefer hardcoding the positionning of dv blocks, it is + simpler :-) */ + +static const uint16_t dv_place_420[1620] = { + 0x0c24, 0x2412, 0x3036, 0x0000, 0x1848, + 0x0e24, 0x2612, 0x3236, 0x0200, 0x1a48, + 0x1024, 0x2812, 0x3436, 0x0400, 0x1c48, + 0x1026, 0x2814, 0x3438, 0x0402, 0x1c4a, + 0x0e26, 0x2614, 0x3238, 0x0202, 0x1a4a, + 0x0c26, 0x2414, 0x3038, 0x0002, 0x184a, + 0x0c28, 0x2416, 0x303a, 0x0004, 0x184c, + 0x0e28, 0x2616, 0x323a, 0x0204, 0x1a4c, + 0x1028, 0x2816, 0x343a, 0x0404, 0x1c4c, + 0x102a, 0x2818, 0x343c, 0x0406, 0x1c4e, + 0x0e2a, 0x2618, 0x323c, 0x0206, 0x1a4e, + 0x0c2a, 0x2418, 0x303c, 0x0006, 0x184e, + 0x0c2c, 0x241a, 0x303e, 0x0008, 0x1850, + 0x0e2c, 0x261a, 0x323e, 0x0208, 0x1a50, + 0x102c, 0x281a, 0x343e, 0x0408, 0x1c50, + 0x102e, 0x281c, 0x3440, 0x040a, 0x1c52, + 0x0e2e, 0x261c, 0x3240, 0x020a, 0x1a52, + 0x0c2e, 0x241c, 0x3040, 0x000a, 0x1852, + 0x0c30, 0x241e, 0x3042, 0x000c, 0x1854, + 0x0e30, 0x261e, 0x3242, 0x020c, 0x1a54, + 0x1030, 0x281e, 0x3442, 0x040c, 0x1c54, + 0x1032, 0x2820, 0x3444, 0x040e, 0x1c56, + 0x0e32, 0x2620, 0x3244, 0x020e, 0x1a56, + 0x0c32, 0x2420, 0x3044, 0x000e, 0x1856, + 0x0c34, 0x2422, 0x3046, 0x0010, 0x1858, + 0x0e34, 0x2622, 0x3246, 0x0210, 0x1a58, + 0x1034, 0x2822, 0x3446, 0x0410, 0x1c58, + 0x1224, 0x2a12, 0x3636, 0x0600, 0x1e48, + 0x1424, 0x2c12, 0x3836, 0x0800, 0x2048, + 0x1624, 0x2e12, 0x3a36, 0x0a00, 0x2248, + 0x1626, 0x2e14, 0x3a38, 0x0a02, 0x224a, + 0x1426, 0x2c14, 0x3838, 0x0802, 0x204a, + 0x1226, 0x2a14, 0x3638, 0x0602, 0x1e4a, + 0x1228, 0x2a16, 0x363a, 0x0604, 0x1e4c, + 0x1428, 0x2c16, 0x383a, 0x0804, 0x204c, + 0x1628, 0x2e16, 0x3a3a, 0x0a04, 0x224c, + 0x162a, 0x2e18, 0x3a3c, 0x0a06, 0x224e, + 0x142a, 0x2c18, 0x383c, 0x0806, 0x204e, + 0x122a, 0x2a18, 0x363c, 0x0606, 0x1e4e, + 0x122c, 0x2a1a, 0x363e, 0x0608, 0x1e50, + 0x142c, 0x2c1a, 0x383e, 0x0808, 0x2050, + 0x162c, 0x2e1a, 0x3a3e, 0x0a08, 0x2250, + 0x162e, 0x2e1c, 0x3a40, 0x0a0a, 0x2252, + 0x142e, 0x2c1c, 0x3840, 0x080a, 0x2052, + 0x122e, 0x2a1c, 0x3640, 0x060a, 0x1e52, + 0x1230, 0x2a1e, 0x3642, 0x060c, 0x1e54, + 0x1430, 0x2c1e, 0x3842, 0x080c, 0x2054, + 0x1630, 0x2e1e, 0x3a42, 0x0a0c, 0x2254, + 0x1632, 0x2e20, 0x3a44, 0x0a0e, 0x2256, + 0x1432, 0x2c20, 0x3844, 0x080e, 0x2056, + 0x1232, 0x2a20, 0x3644, 0x060e, 0x1e56, + 0x1234, 0x2a22, 0x3646, 0x0610, 0x1e58, + 0x1434, 0x2c22, 0x3846, 0x0810, 0x2058, + 0x1634, 0x2e22, 0x3a46, 0x0a10, 0x2258, + 0x1824, 0x3012, 0x3c36, 0x0c00, 0x2448, + 0x1a24, 0x3212, 0x3e36, 0x0e00, 0x2648, + 0x1c24, 0x3412, 0x4036, 0x1000, 0x2848, + 0x1c26, 0x3414, 0x4038, 0x1002, 0x284a, + 0x1a26, 0x3214, 0x3e38, 0x0e02, 0x264a, + 0x1826, 0x3014, 0x3c38, 0x0c02, 0x244a, + 0x1828, 0x3016, 0x3c3a, 0x0c04, 0x244c, + 0x1a28, 0x3216, 0x3e3a, 0x0e04, 0x264c, + 0x1c28, 0x3416, 0x403a, 0x1004, 0x284c, + 0x1c2a, 0x3418, 0x403c, 0x1006, 0x284e, + 0x1a2a, 0x3218, 0x3e3c, 0x0e06, 0x264e, + 0x182a, 0x3018, 0x3c3c, 0x0c06, 0x244e, + 0x182c, 0x301a, 0x3c3e, 0x0c08, 0x2450, + 0x1a2c, 0x321a, 0x3e3e, 0x0e08, 0x2650, + 0x1c2c, 0x341a, 0x403e, 0x1008, 0x2850, + 0x1c2e, 0x341c, 0x4040, 0x100a, 0x2852, + 0x1a2e, 0x321c, 0x3e40, 0x0e0a, 0x2652, + 0x182e, 0x301c, 0x3c40, 0x0c0a, 0x2452, + 0x1830, 0x301e, 0x3c42, 0x0c0c, 0x2454, + 0x1a30, 0x321e, 0x3e42, 0x0e0c, 0x2654, + 0x1c30, 0x341e, 0x4042, 0x100c, 0x2854, + 0x1c32, 0x3420, 0x4044, 0x100e, 0x2856, + 0x1a32, 0x3220, 0x3e44, 0x0e0e, 0x2656, + 0x1832, 0x3020, 0x3c44, 0x0c0e, 0x2456, + 0x1834, 0x3022, 0x3c46, 0x0c10, 0x2458, + 0x1a34, 0x3222, 0x3e46, 0x0e10, 0x2658, + 0x1c34, 0x3422, 0x4046, 0x1010, 0x2858, + 0x1e24, 0x3612, 0x4236, 0x1200, 0x2a48, + 0x2024, 0x3812, 0x4436, 0x1400, 0x2c48, + 0x2224, 0x3a12, 0x4636, 0x1600, 0x2e48, + 0x2226, 0x3a14, 0x4638, 0x1602, 0x2e4a, + 0x2026, 0x3814, 0x4438, 0x1402, 0x2c4a, + 0x1e26, 0x3614, 0x4238, 0x1202, 0x2a4a, + 0x1e28, 0x3616, 0x423a, 0x1204, 0x2a4c, + 0x2028, 0x3816, 0x443a, 0x1404, 0x2c4c, + 0x2228, 0x3a16, 0x463a, 0x1604, 0x2e4c, + 0x222a, 0x3a18, 0x463c, 0x1606, 0x2e4e, + 0x202a, 0x3818, 0x443c, 0x1406, 0x2c4e, + 0x1e2a, 0x3618, 0x423c, 0x1206, 0x2a4e, + 0x1e2c, 0x361a, 0x423e, 0x1208, 0x2a50, + 0x202c, 0x381a, 0x443e, 0x1408, 0x2c50, + 0x222c, 0x3a1a, 0x463e, 0x1608, 0x2e50, + 0x222e, 0x3a1c, 0x4640, 0x160a, 0x2e52, + 0x202e, 0x381c, 0x4440, 0x140a, 0x2c52, + 0x1e2e, 0x361c, 0x4240, 0x120a, 0x2a52, + 0x1e30, 0x361e, 0x4242, 0x120c, 0x2a54, + 0x2030, 0x381e, 0x4442, 0x140c, 0x2c54, + 0x2230, 0x3a1e, 0x4642, 0x160c, 0x2e54, + 0x2232, 0x3a20, 0x4644, 0x160e, 0x2e56, + 0x2032, 0x3820, 0x4444, 0x140e, 0x2c56, + 0x1e32, 0x3620, 0x4244, 0x120e, 0x2a56, + 0x1e34, 0x3622, 0x4246, 0x1210, 0x2a58, + 0x2034, 0x3822, 0x4446, 0x1410, 0x2c58, + 0x2234, 0x3a22, 0x4646, 0x1610, 0x2e58, + 0x2424, 0x3c12, 0x0036, 0x1800, 0x3048, + 0x2624, 0x3e12, 0x0236, 0x1a00, 0x3248, + 0x2824, 0x4012, 0x0436, 0x1c00, 0x3448, + 0x2826, 0x4014, 0x0438, 0x1c02, 0x344a, + 0x2626, 0x3e14, 0x0238, 0x1a02, 0x324a, + 0x2426, 0x3c14, 0x0038, 0x1802, 0x304a, + 0x2428, 0x3c16, 0x003a, 0x1804, 0x304c, + 0x2628, 0x3e16, 0x023a, 0x1a04, 0x324c, + 0x2828, 0x4016, 0x043a, 0x1c04, 0x344c, + 0x282a, 0x4018, 0x043c, 0x1c06, 0x344e, + 0x262a, 0x3e18, 0x023c, 0x1a06, 0x324e, + 0x242a, 0x3c18, 0x003c, 0x1806, 0x304e, + 0x242c, 0x3c1a, 0x003e, 0x1808, 0x3050, + 0x262c, 0x3e1a, 0x023e, 0x1a08, 0x3250, + 0x282c, 0x401a, 0x043e, 0x1c08, 0x3450, + 0x282e, 0x401c, 0x0440, 0x1c0a, 0x3452, + 0x262e, 0x3e1c, 0x0240, 0x1a0a, 0x3252, + 0x242e, 0x3c1c, 0x0040, 0x180a, 0x3052, + 0x2430, 0x3c1e, 0x0042, 0x180c, 0x3054, + 0x2630, 0x3e1e, 0x0242, 0x1a0c, 0x3254, + 0x2830, 0x401e, 0x0442, 0x1c0c, 0x3454, + 0x2832, 0x4020, 0x0444, 0x1c0e, 0x3456, + 0x2632, 0x3e20, 0x0244, 0x1a0e, 0x3256, + 0x2432, 0x3c20, 0x0044, 0x180e, 0x3056, + 0x2434, 0x3c22, 0x0046, 0x1810, 0x3058, + 0x2634, 0x3e22, 0x0246, 0x1a10, 0x3258, + 0x2834, 0x4022, 0x0446, 0x1c10, 0x3458, + 0x2a24, 0x4212, 0x0636, 0x1e00, 0x3648, + 0x2c24, 0x4412, 0x0836, 0x2000, 0x3848, + 0x2e24, 0x4612, 0x0a36, 0x2200, 0x3a48, + 0x2e26, 0x4614, 0x0a38, 0x2202, 0x3a4a, + 0x2c26, 0x4414, 0x0838, 0x2002, 0x384a, + 0x2a26, 0x4214, 0x0638, 0x1e02, 0x364a, + 0x2a28, 0x4216, 0x063a, 0x1e04, 0x364c, + 0x2c28, 0x4416, 0x083a, 0x2004, 0x384c, + 0x2e28, 0x4616, 0x0a3a, 0x2204, 0x3a4c, + 0x2e2a, 0x4618, 0x0a3c, 0x2206, 0x3a4e, + 0x2c2a, 0x4418, 0x083c, 0x2006, 0x384e, + 0x2a2a, 0x4218, 0x063c, 0x1e06, 0x364e, + 0x2a2c, 0x421a, 0x063e, 0x1e08, 0x3650, + 0x2c2c, 0x441a, 0x083e, 0x2008, 0x3850, + 0x2e2c, 0x461a, 0x0a3e, 0x2208, 0x3a50, + 0x2e2e, 0x461c, 0x0a40, 0x220a, 0x3a52, + 0x2c2e, 0x441c, 0x0840, 0x200a, 0x3852, + 0x2a2e, 0x421c, 0x0640, 0x1e0a, 0x3652, + 0x2a30, 0x421e, 0x0642, 0x1e0c, 0x3654, + 0x2c30, 0x441e, 0x0842, 0x200c, 0x3854, + 0x2e30, 0x461e, 0x0a42, 0x220c, 0x3a54, + 0x2e32, 0x4620, 0x0a44, 0x220e, 0x3a56, + 0x2c32, 0x4420, 0x0844, 0x200e, 0x3856, + 0x2a32, 0x4220, 0x0644, 0x1e0e, 0x3656, + 0x2a34, 0x4222, 0x0646, 0x1e10, 0x3658, + 0x2c34, 0x4422, 0x0846, 0x2010, 0x3858, + 0x2e34, 0x4622, 0x0a46, 0x2210, 0x3a58, + 0x3024, 0x0012, 0x0c36, 0x2400, 0x3c48, + 0x3224, 0x0212, 0x0e36, 0x2600, 0x3e48, + 0x3424, 0x0412, 0x1036, 0x2800, 0x4048, + 0x3426, 0x0414, 0x1038, 0x2802, 0x404a, + 0x3226, 0x0214, 0x0e38, 0x2602, 0x3e4a, + 0x3026, 0x0014, 0x0c38, 0x2402, 0x3c4a, + 0x3028, 0x0016, 0x0c3a, 0x2404, 0x3c4c, + 0x3228, 0x0216, 0x0e3a, 0x2604, 0x3e4c, + 0x3428, 0x0416, 0x103a, 0x2804, 0x404c, + 0x342a, 0x0418, 0x103c, 0x2806, 0x404e, + 0x322a, 0x0218, 0x0e3c, 0x2606, 0x3e4e, + 0x302a, 0x0018, 0x0c3c, 0x2406, 0x3c4e, + 0x302c, 0x001a, 0x0c3e, 0x2408, 0x3c50, + 0x322c, 0x021a, 0x0e3e, 0x2608, 0x3e50, + 0x342c, 0x041a, 0x103e, 0x2808, 0x4050, + 0x342e, 0x041c, 0x1040, 0x280a, 0x4052, + 0x322e, 0x021c, 0x0e40, 0x260a, 0x3e52, + 0x302e, 0x001c, 0x0c40, 0x240a, 0x3c52, + 0x3030, 0x001e, 0x0c42, 0x240c, 0x3c54, + 0x3230, 0x021e, 0x0e42, 0x260c, 0x3e54, + 0x3430, 0x041e, 0x1042, 0x280c, 0x4054, + 0x3432, 0x0420, 0x1044, 0x280e, 0x4056, + 0x3232, 0x0220, 0x0e44, 0x260e, 0x3e56, + 0x3032, 0x0020, 0x0c44, 0x240e, 0x3c56, + 0x3034, 0x0022, 0x0c46, 0x2410, 0x3c58, + 0x3234, 0x0222, 0x0e46, 0x2610, 0x3e58, + 0x3434, 0x0422, 0x1046, 0x2810, 0x4058, + 0x3624, 0x0612, 0x1236, 0x2a00, 0x4248, + 0x3824, 0x0812, 0x1436, 0x2c00, 0x4448, + 0x3a24, 0x0a12, 0x1636, 0x2e00, 0x4648, + 0x3a26, 0x0a14, 0x1638, 0x2e02, 0x464a, + 0x3826, 0x0814, 0x1438, 0x2c02, 0x444a, + 0x3626, 0x0614, 0x1238, 0x2a02, 0x424a, + 0x3628, 0x0616, 0x123a, 0x2a04, 0x424c, + 0x3828, 0x0816, 0x143a, 0x2c04, 0x444c, + 0x3a28, 0x0a16, 0x163a, 0x2e04, 0x464c, + 0x3a2a, 0x0a18, 0x163c, 0x2e06, 0x464e, + 0x382a, 0x0818, 0x143c, 0x2c06, 0x444e, + 0x362a, 0x0618, 0x123c, 0x2a06, 0x424e, + 0x362c, 0x061a, 0x123e, 0x2a08, 0x4250, + 0x382c, 0x081a, 0x143e, 0x2c08, 0x4450, + 0x3a2c, 0x0a1a, 0x163e, 0x2e08, 0x4650, + 0x3a2e, 0x0a1c, 0x1640, 0x2e0a, 0x4652, + 0x382e, 0x081c, 0x1440, 0x2c0a, 0x4452, + 0x362e, 0x061c, 0x1240, 0x2a0a, 0x4252, + 0x3630, 0x061e, 0x1242, 0x2a0c, 0x4254, + 0x3830, 0x081e, 0x1442, 0x2c0c, 0x4454, + 0x3a30, 0x0a1e, 0x1642, 0x2e0c, 0x4654, + 0x3a32, 0x0a20, 0x1644, 0x2e0e, 0x4656, + 0x3832, 0x0820, 0x1444, 0x2c0e, 0x4456, + 0x3632, 0x0620, 0x1244, 0x2a0e, 0x4256, + 0x3634, 0x0622, 0x1246, 0x2a10, 0x4258, + 0x3834, 0x0822, 0x1446, 0x2c10, 0x4458, + 0x3a34, 0x0a22, 0x1646, 0x2e10, 0x4658, + 0x3c24, 0x0c12, 0x1836, 0x3000, 0x0048, + 0x3e24, 0x0e12, 0x1a36, 0x3200, 0x0248, + 0x4024, 0x1012, 0x1c36, 0x3400, 0x0448, + 0x4026, 0x1014, 0x1c38, 0x3402, 0x044a, + 0x3e26, 0x0e14, 0x1a38, 0x3202, 0x024a, + 0x3c26, 0x0c14, 0x1838, 0x3002, 0x004a, + 0x3c28, 0x0c16, 0x183a, 0x3004, 0x004c, + 0x3e28, 0x0e16, 0x1a3a, 0x3204, 0x024c, + 0x4028, 0x1016, 0x1c3a, 0x3404, 0x044c, + 0x402a, 0x1018, 0x1c3c, 0x3406, 0x044e, + 0x3e2a, 0x0e18, 0x1a3c, 0x3206, 0x024e, + 0x3c2a, 0x0c18, 0x183c, 0x3006, 0x004e, + 0x3c2c, 0x0c1a, 0x183e, 0x3008, 0x0050, + 0x3e2c, 0x0e1a, 0x1a3e, 0x3208, 0x0250, + 0x402c, 0x101a, 0x1c3e, 0x3408, 0x0450, + 0x402e, 0x101c, 0x1c40, 0x340a, 0x0452, + 0x3e2e, 0x0e1c, 0x1a40, 0x320a, 0x0252, + 0x3c2e, 0x0c1c, 0x1840, 0x300a, 0x0052, + 0x3c30, 0x0c1e, 0x1842, 0x300c, 0x0054, + 0x3e30, 0x0e1e, 0x1a42, 0x320c, 0x0254, + 0x4030, 0x101e, 0x1c42, 0x340c, 0x0454, + 0x4032, 0x1020, 0x1c44, 0x340e, 0x0456, + 0x3e32, 0x0e20, 0x1a44, 0x320e, 0x0256, + 0x3c32, 0x0c20, 0x1844, 0x300e, 0x0056, + 0x3c34, 0x0c22, 0x1846, 0x3010, 0x0058, + 0x3e34, 0x0e22, 0x1a46, 0x3210, 0x0258, + 0x4034, 0x1022, 0x1c46, 0x3410, 0x0458, + 0x4224, 0x1212, 0x1e36, 0x3600, 0x0648, + 0x4424, 0x1412, 0x2036, 0x3800, 0x0848, + 0x4624, 0x1612, 0x2236, 0x3a00, 0x0a48, + 0x4626, 0x1614, 0x2238, 0x3a02, 0x0a4a, + 0x4426, 0x1414, 0x2038, 0x3802, 0x084a, + 0x4226, 0x1214, 0x1e38, 0x3602, 0x064a, + 0x4228, 0x1216, 0x1e3a, 0x3604, 0x064c, + 0x4428, 0x1416, 0x203a, 0x3804, 0x084c, + 0x4628, 0x1616, 0x223a, 0x3a04, 0x0a4c, + 0x462a, 0x1618, 0x223c, 0x3a06, 0x0a4e, + 0x442a, 0x1418, 0x203c, 0x3806, 0x084e, + 0x422a, 0x1218, 0x1e3c, 0x3606, 0x064e, + 0x422c, 0x121a, 0x1e3e, 0x3608, 0x0650, + 0x442c, 0x141a, 0x203e, 0x3808, 0x0850, + 0x462c, 0x161a, 0x223e, 0x3a08, 0x0a50, + 0x462e, 0x161c, 0x2240, 0x3a0a, 0x0a52, + 0x442e, 0x141c, 0x2040, 0x380a, 0x0852, + 0x422e, 0x121c, 0x1e40, 0x360a, 0x0652, + 0x4230, 0x121e, 0x1e42, 0x360c, 0x0654, + 0x4430, 0x141e, 0x2042, 0x380c, 0x0854, + 0x4630, 0x161e, 0x2242, 0x3a0c, 0x0a54, + 0x4632, 0x1620, 0x2244, 0x3a0e, 0x0a56, + 0x4432, 0x1420, 0x2044, 0x380e, 0x0856, + 0x4232, 0x1220, 0x1e44, 0x360e, 0x0656, + 0x4234, 0x1222, 0x1e46, 0x3610, 0x0658, + 0x4434, 0x1422, 0x2046, 0x3810, 0x0858, + 0x4634, 0x1622, 0x2246, 0x3a10, 0x0a58, + 0x0024, 0x1812, 0x2436, 0x3c00, 0x0c48, + 0x0224, 0x1a12, 0x2636, 0x3e00, 0x0e48, + 0x0424, 0x1c12, 0x2836, 0x4000, 0x1048, + 0x0426, 0x1c14, 0x2838, 0x4002, 0x104a, + 0x0226, 0x1a14, 0x2638, 0x3e02, 0x0e4a, + 0x0026, 0x1814, 0x2438, 0x3c02, 0x0c4a, + 0x0028, 0x1816, 0x243a, 0x3c04, 0x0c4c, + 0x0228, 0x1a16, 0x263a, 0x3e04, 0x0e4c, + 0x0428, 0x1c16, 0x283a, 0x4004, 0x104c, + 0x042a, 0x1c18, 0x283c, 0x4006, 0x104e, + 0x022a, 0x1a18, 0x263c, 0x3e06, 0x0e4e, + 0x002a, 0x1818, 0x243c, 0x3c06, 0x0c4e, + 0x002c, 0x181a, 0x243e, 0x3c08, 0x0c50, + 0x022c, 0x1a1a, 0x263e, 0x3e08, 0x0e50, + 0x042c, 0x1c1a, 0x283e, 0x4008, 0x1050, + 0x042e, 0x1c1c, 0x2840, 0x400a, 0x1052, + 0x022e, 0x1a1c, 0x2640, 0x3e0a, 0x0e52, + 0x002e, 0x181c, 0x2440, 0x3c0a, 0x0c52, + 0x0030, 0x181e, 0x2442, 0x3c0c, 0x0c54, + 0x0230, 0x1a1e, 0x2642, 0x3e0c, 0x0e54, + 0x0430, 0x1c1e, 0x2842, 0x400c, 0x1054, + 0x0432, 0x1c20, 0x2844, 0x400e, 0x1056, + 0x0232, 0x1a20, 0x2644, 0x3e0e, 0x0e56, + 0x0032, 0x1820, 0x2444, 0x3c0e, 0x0c56, + 0x0034, 0x1822, 0x2446, 0x3c10, 0x0c58, + 0x0234, 0x1a22, 0x2646, 0x3e10, 0x0e58, + 0x0434, 0x1c22, 0x2846, 0x4010, 0x1058, + 0x0624, 0x1e12, 0x2a36, 0x4200, 0x1248, + 0x0824, 0x2012, 0x2c36, 0x4400, 0x1448, + 0x0a24, 0x2212, 0x2e36, 0x4600, 0x1648, + 0x0a26, 0x2214, 0x2e38, 0x4602, 0x164a, + 0x0826, 0x2014, 0x2c38, 0x4402, 0x144a, + 0x0626, 0x1e14, 0x2a38, 0x4202, 0x124a, + 0x0628, 0x1e16, 0x2a3a, 0x4204, 0x124c, + 0x0828, 0x2016, 0x2c3a, 0x4404, 0x144c, + 0x0a28, 0x2216, 0x2e3a, 0x4604, 0x164c, + 0x0a2a, 0x2218, 0x2e3c, 0x4606, 0x164e, + 0x082a, 0x2018, 0x2c3c, 0x4406, 0x144e, + 0x062a, 0x1e18, 0x2a3c, 0x4206, 0x124e, + 0x062c, 0x1e1a, 0x2a3e, 0x4208, 0x1250, + 0x082c, 0x201a, 0x2c3e, 0x4408, 0x1450, + 0x0a2c, 0x221a, 0x2e3e, 0x4608, 0x1650, + 0x0a2e, 0x221c, 0x2e40, 0x460a, 0x1652, + 0x082e, 0x201c, 0x2c40, 0x440a, 0x1452, + 0x062e, 0x1e1c, 0x2a40, 0x420a, 0x1252, + 0x0630, 0x1e1e, 0x2a42, 0x420c, 0x1254, + 0x0830, 0x201e, 0x2c42, 0x440c, 0x1454, + 0x0a30, 0x221e, 0x2e42, 0x460c, 0x1654, + 0x0a32, 0x2220, 0x2e44, 0x460e, 0x1656, + 0x0832, 0x2020, 0x2c44, 0x440e, 0x1456, + 0x0632, 0x1e20, 0x2a44, 0x420e, 0x1256, + 0x0634, 0x1e22, 0x2a46, 0x4210, 0x1258, + 0x0834, 0x2022, 0x2c46, 0x4410, 0x1458, + 0x0a34, 0x2222, 0x2e46, 0x4610, 0x1658, +}; + +static const uint16_t dv_place_411P[1620] = { + 0x0c24, 0x2710, 0x3334, 0x0000, 0x1848, + 0x0d24, 0x2810, 0x3434, 0x0100, 0x1948, + 0x0e24, 0x2910, 0x3534, 0x0200, 0x1a48, + 0x0f24, 0x2914, 0x3538, 0x0300, 0x1b48, + 0x1024, 0x2814, 0x3438, 0x0400, 0x1c48, + 0x1124, 0x2714, 0x3338, 0x0500, 0x1d48, + 0x1128, 0x2614, 0x3238, 0x0504, 0x1d4c, + 0x1028, 0x2514, 0x3138, 0x0404, 0x1c4c, + 0x0f28, 0x2414, 0x3038, 0x0304, 0x1b4c, + 0x0e28, 0x2418, 0x303c, 0x0204, 0x1a4c, + 0x0d28, 0x2518, 0x313c, 0x0104, 0x194c, + 0x0c28, 0x2618, 0x323c, 0x0004, 0x184c, + 0x0c2c, 0x2718, 0x333c, 0x0008, 0x1850, + 0x0d2c, 0x2818, 0x343c, 0x0108, 0x1950, + 0x0e2c, 0x2918, 0x353c, 0x0208, 0x1a50, + 0x0f2c, 0x291c, 0x3540, 0x0308, 0x1b50, + 0x102c, 0x281c, 0x3440, 0x0408, 0x1c50, + 0x112c, 0x271c, 0x3340, 0x0508, 0x1d50, + 0x1130, 0x261c, 0x3240, 0x050c, 0x1d54, + 0x1030, 0x251c, 0x3140, 0x040c, 0x1c54, + 0x0f30, 0x241c, 0x3040, 0x030c, 0x1b54, + 0x0e30, 0x2420, 0x3044, 0x020c, 0x1a54, + 0x0d30, 0x2520, 0x3144, 0x010c, 0x1954, + 0x0c30, 0x2620, 0x3244, 0x000c, 0x1854, + 0x0c34, 0x2720, 0x3344, 0x0010, 0x1858, + 0x0d34, 0x2820, 0x3444, 0x0110, 0x1a58, + 0x0e34, 0x2920, 0x3544, 0x0210, 0x1c58, + 0x1224, 0x2d10, 0x3934, 0x0600, 0x1e48, + 0x1324, 0x2e10, 0x3a34, 0x0700, 0x1f48, + 0x1424, 0x2f10, 0x3b34, 0x0800, 0x2048, + 0x1524, 0x2f14, 0x3b38, 0x0900, 0x2148, + 0x1624, 0x2e14, 0x3a38, 0x0a00, 0x2248, + 0x1724, 0x2d14, 0x3938, 0x0b00, 0x2348, + 0x1728, 0x2c14, 0x3838, 0x0b04, 0x234c, + 0x1628, 0x2b14, 0x3738, 0x0a04, 0x224c, + 0x1528, 0x2a14, 0x3638, 0x0904, 0x214c, + 0x1428, 0x2a18, 0x363c, 0x0804, 0x204c, + 0x1328, 0x2b18, 0x373c, 0x0704, 0x1f4c, + 0x1228, 0x2c18, 0x383c, 0x0604, 0x1e4c, + 0x122c, 0x2d18, 0x393c, 0x0608, 0x1e50, + 0x132c, 0x2e18, 0x3a3c, 0x0708, 0x1f50, + 0x142c, 0x2f18, 0x3b3c, 0x0808, 0x2050, + 0x152c, 0x2f1c, 0x3b40, 0x0908, 0x2150, + 0x162c, 0x2e1c, 0x3a40, 0x0a08, 0x2250, + 0x172c, 0x2d1c, 0x3940, 0x0b08, 0x2350, + 0x1730, 0x2c1c, 0x3840, 0x0b0c, 0x2354, + 0x1630, 0x2b1c, 0x3740, 0x0a0c, 0x2254, + 0x1530, 0x2a1c, 0x3640, 0x090c, 0x2154, + 0x1430, 0x2a20, 0x3644, 0x080c, 0x2054, + 0x1330, 0x2b20, 0x3744, 0x070c, 0x1f54, + 0x1230, 0x2c20, 0x3844, 0x060c, 0x1e54, + 0x1234, 0x2d20, 0x3944, 0x0610, 0x1e58, + 0x1334, 0x2e20, 0x3a44, 0x0710, 0x2058, + 0x1434, 0x2f20, 0x3b44, 0x0810, 0x2258, + 0x1824, 0x3310, 0x3f34, 0x0c00, 0x2448, + 0x1924, 0x3410, 0x4034, 0x0d00, 0x2548, + 0x1a24, 0x3510, 0x4134, 0x0e00, 0x2648, + 0x1b24, 0x3514, 0x4138, 0x0f00, 0x2748, + 0x1c24, 0x3414, 0x4038, 0x1000, 0x2848, + 0x1d24, 0x3314, 0x3f38, 0x1100, 0x2948, + 0x1d28, 0x3214, 0x3e38, 0x1104, 0x294c, + 0x1c28, 0x3114, 0x3d38, 0x1004, 0x284c, + 0x1b28, 0x3014, 0x3c38, 0x0f04, 0x274c, + 0x1a28, 0x3018, 0x3c3c, 0x0e04, 0x264c, + 0x1928, 0x3118, 0x3d3c, 0x0d04, 0x254c, + 0x1828, 0x3218, 0x3e3c, 0x0c04, 0x244c, + 0x182c, 0x3318, 0x3f3c, 0x0c08, 0x2450, + 0x192c, 0x3418, 0x403c, 0x0d08, 0x2550, + 0x1a2c, 0x3518, 0x413c, 0x0e08, 0x2650, + 0x1b2c, 0x351c, 0x4140, 0x0f08, 0x2750, + 0x1c2c, 0x341c, 0x4040, 0x1008, 0x2850, + 0x1d2c, 0x331c, 0x3f40, 0x1108, 0x2950, + 0x1d30, 0x321c, 0x3e40, 0x110c, 0x2954, + 0x1c30, 0x311c, 0x3d40, 0x100c, 0x2854, + 0x1b30, 0x301c, 0x3c40, 0x0f0c, 0x2754, + 0x1a30, 0x3020, 0x3c44, 0x0e0c, 0x2654, + 0x1930, 0x3120, 0x3d44, 0x0d0c, 0x2554, + 0x1830, 0x3220, 0x3e44, 0x0c0c, 0x2454, + 0x1834, 0x3320, 0x3f44, 0x0c10, 0x2458, + 0x1934, 0x3420, 0x4044, 0x0d10, 0x2658, + 0x1a34, 0x3520, 0x4144, 0x0e10, 0x2858, + 0x1e24, 0x3910, 0x4534, 0x1200, 0x2a48, + 0x1f24, 0x3a10, 0x4634, 0x1300, 0x2b48, + 0x2024, 0x3b10, 0x4734, 0x1400, 0x2c48, + 0x2124, 0x3b14, 0x4738, 0x1500, 0x2d48, + 0x2224, 0x3a14, 0x4638, 0x1600, 0x2e48, + 0x2324, 0x3914, 0x4538, 0x1700, 0x2f48, + 0x2328, 0x3814, 0x4438, 0x1704, 0x2f4c, + 0x2228, 0x3714, 0x4338, 0x1604, 0x2e4c, + 0x2128, 0x3614, 0x4238, 0x1504, 0x2d4c, + 0x2028, 0x3618, 0x423c, 0x1404, 0x2c4c, + 0x1f28, 0x3718, 0x433c, 0x1304, 0x2b4c, + 0x1e28, 0x3818, 0x443c, 0x1204, 0x2a4c, + 0x1e2c, 0x3918, 0x453c, 0x1208, 0x2a50, + 0x1f2c, 0x3a18, 0x463c, 0x1308, 0x2b50, + 0x202c, 0x3b18, 0x473c, 0x1408, 0x2c50, + 0x212c, 0x3b1c, 0x4740, 0x1508, 0x2d50, + 0x222c, 0x3a1c, 0x4640, 0x1608, 0x2e50, + 0x232c, 0x391c, 0x4540, 0x1708, 0x2f50, + 0x2330, 0x381c, 0x4440, 0x170c, 0x2f54, + 0x2230, 0x371c, 0x4340, 0x160c, 0x2e54, + 0x2130, 0x361c, 0x4240, 0x150c, 0x2d54, + 0x2030, 0x3620, 0x4244, 0x140c, 0x2c54, + 0x1f30, 0x3720, 0x4344, 0x130c, 0x2b54, + 0x1e30, 0x3820, 0x4444, 0x120c, 0x2a54, + 0x1e34, 0x3920, 0x4544, 0x1210, 0x2a58, + 0x1f34, 0x3a20, 0x4644, 0x1310, 0x2c58, + 0x2034, 0x3b20, 0x4744, 0x1410, 0x2e58, + 0x2424, 0x3f10, 0x0334, 0x1800, 0x3048, + 0x2524, 0x4010, 0x0434, 0x1900, 0x3148, + 0x2624, 0x4110, 0x0534, 0x1a00, 0x3248, + 0x2724, 0x4114, 0x0538, 0x1b00, 0x3348, + 0x2824, 0x4014, 0x0438, 0x1c00, 0x3448, + 0x2924, 0x3f14, 0x0338, 0x1d00, 0x3548, + 0x2928, 0x3e14, 0x0238, 0x1d04, 0x354c, + 0x2828, 0x3d14, 0x0138, 0x1c04, 0x344c, + 0x2728, 0x3c14, 0x0038, 0x1b04, 0x334c, + 0x2628, 0x3c18, 0x003c, 0x1a04, 0x324c, + 0x2528, 0x3d18, 0x013c, 0x1904, 0x314c, + 0x2428, 0x3e18, 0x023c, 0x1804, 0x304c, + 0x242c, 0x3f18, 0x033c, 0x1808, 0x3050, + 0x252c, 0x4018, 0x043c, 0x1908, 0x3150, + 0x262c, 0x4118, 0x053c, 0x1a08, 0x3250, + 0x272c, 0x411c, 0x0540, 0x1b08, 0x3350, + 0x282c, 0x401c, 0x0440, 0x1c08, 0x3450, + 0x292c, 0x3f1c, 0x0340, 0x1d08, 0x3550, + 0x2930, 0x3e1c, 0x0240, 0x1d0c, 0x3554, + 0x2830, 0x3d1c, 0x0140, 0x1c0c, 0x3454, + 0x2730, 0x3c1c, 0x0040, 0x1b0c, 0x3354, + 0x2630, 0x3c20, 0x0044, 0x1a0c, 0x3254, + 0x2530, 0x3d20, 0x0144, 0x190c, 0x3154, + 0x2430, 0x3e20, 0x0244, 0x180c, 0x3054, + 0x2434, 0x3f20, 0x0344, 0x1810, 0x3058, + 0x2534, 0x4020, 0x0444, 0x1910, 0x3258, + 0x2634, 0x4120, 0x0544, 0x1a10, 0x3458, + 0x2a24, 0x4510, 0x0934, 0x1e00, 0x3648, + 0x2b24, 0x4610, 0x0a34, 0x1f00, 0x3748, + 0x2c24, 0x4710, 0x0b34, 0x2000, 0x3848, + 0x2d24, 0x4714, 0x0b38, 0x2100, 0x3948, + 0x2e24, 0x4614, 0x0a38, 0x2200, 0x3a48, + 0x2f24, 0x4514, 0x0938, 0x2300, 0x3b48, + 0x2f28, 0x4414, 0x0838, 0x2304, 0x3b4c, + 0x2e28, 0x4314, 0x0738, 0x2204, 0x3a4c, + 0x2d28, 0x4214, 0x0638, 0x2104, 0x394c, + 0x2c28, 0x4218, 0x063c, 0x2004, 0x384c, + 0x2b28, 0x4318, 0x073c, 0x1f04, 0x374c, + 0x2a28, 0x4418, 0x083c, 0x1e04, 0x364c, + 0x2a2c, 0x4518, 0x093c, 0x1e08, 0x3650, + 0x2b2c, 0x4618, 0x0a3c, 0x1f08, 0x3750, + 0x2c2c, 0x4718, 0x0b3c, 0x2008, 0x3850, + 0x2d2c, 0x471c, 0x0b40, 0x2108, 0x3950, + 0x2e2c, 0x461c, 0x0a40, 0x2208, 0x3a50, + 0x2f2c, 0x451c, 0x0940, 0x2308, 0x3b50, + 0x2f30, 0x441c, 0x0840, 0x230c, 0x3b54, + 0x2e30, 0x431c, 0x0740, 0x220c, 0x3a54, + 0x2d30, 0x421c, 0x0640, 0x210c, 0x3954, + 0x2c30, 0x4220, 0x0644, 0x200c, 0x3854, + 0x2b30, 0x4320, 0x0744, 0x1f0c, 0x3754, + 0x2a30, 0x4420, 0x0844, 0x1e0c, 0x3654, + 0x2a34, 0x4520, 0x0944, 0x1e10, 0x3658, + 0x2b34, 0x4620, 0x0a44, 0x1f10, 0x3858, + 0x2c34, 0x4720, 0x0b44, 0x2010, 0x3a58, + 0x3024, 0x0310, 0x0f34, 0x2400, 0x3c48, + 0x3124, 0x0410, 0x1034, 0x2500, 0x3d48, + 0x3224, 0x0510, 0x1134, 0x2600, 0x3e48, + 0x3324, 0x0514, 0x1138, 0x2700, 0x3f48, + 0x3424, 0x0414, 0x1038, 0x2800, 0x4048, + 0x3524, 0x0314, 0x0f38, 0x2900, 0x4148, + 0x3528, 0x0214, 0x0e38, 0x2904, 0x414c, + 0x3428, 0x0114, 0x0d38, 0x2804, 0x404c, + 0x3328, 0x0014, 0x0c38, 0x2704, 0x3f4c, + 0x3228, 0x0018, 0x0c3c, 0x2604, 0x3e4c, + 0x3128, 0x0118, 0x0d3c, 0x2504, 0x3d4c, + 0x3028, 0x0218, 0x0e3c, 0x2404, 0x3c4c, + 0x302c, 0x0318, 0x0f3c, 0x2408, 0x3c50, + 0x312c, 0x0418, 0x103c, 0x2508, 0x3d50, + 0x322c, 0x0518, 0x113c, 0x2608, 0x3e50, + 0x332c, 0x051c, 0x1140, 0x2708, 0x3f50, + 0x342c, 0x041c, 0x1040, 0x2808, 0x4050, + 0x352c, 0x031c, 0x0f40, 0x2908, 0x4150, + 0x3530, 0x021c, 0x0e40, 0x290c, 0x4154, + 0x3430, 0x011c, 0x0d40, 0x280c, 0x4054, + 0x3330, 0x001c, 0x0c40, 0x270c, 0x3f54, + 0x3230, 0x0020, 0x0c44, 0x260c, 0x3e54, + 0x3130, 0x0120, 0x0d44, 0x250c, 0x3d54, + 0x3030, 0x0220, 0x0e44, 0x240c, 0x3c54, + 0x3034, 0x0320, 0x0f44, 0x2410, 0x3c58, + 0x3134, 0x0420, 0x1044, 0x2510, 0x3e58, + 0x3234, 0x0520, 0x1144, 0x2610, 0x4058, + 0x3624, 0x0910, 0x1534, 0x2a00, 0x4248, + 0x3724, 0x0a10, 0x1634, 0x2b00, 0x4348, + 0x3824, 0x0b10, 0x1734, 0x2c00, 0x4448, + 0x3924, 0x0b14, 0x1738, 0x2d00, 0x4548, + 0x3a24, 0x0a14, 0x1638, 0x2e00, 0x4648, + 0x3b24, 0x0914, 0x1538, 0x2f00, 0x4748, + 0x3b28, 0x0814, 0x1438, 0x2f04, 0x474c, + 0x3a28, 0x0714, 0x1338, 0x2e04, 0x464c, + 0x3928, 0x0614, 0x1238, 0x2d04, 0x454c, + 0x3828, 0x0618, 0x123c, 0x2c04, 0x444c, + 0x3728, 0x0718, 0x133c, 0x2b04, 0x434c, + 0x3628, 0x0818, 0x143c, 0x2a04, 0x424c, + 0x362c, 0x0918, 0x153c, 0x2a08, 0x4250, + 0x372c, 0x0a18, 0x163c, 0x2b08, 0x4350, + 0x382c, 0x0b18, 0x173c, 0x2c08, 0x4450, + 0x392c, 0x0b1c, 0x1740, 0x2d08, 0x4550, + 0x3a2c, 0x0a1c, 0x1640, 0x2e08, 0x4650, + 0x3b2c, 0x091c, 0x1540, 0x2f08, 0x4750, + 0x3b30, 0x081c, 0x1440, 0x2f0c, 0x4754, + 0x3a30, 0x071c, 0x1340, 0x2e0c, 0x4654, + 0x3930, 0x061c, 0x1240, 0x2d0c, 0x4554, + 0x3830, 0x0620, 0x1244, 0x2c0c, 0x4454, + 0x3730, 0x0720, 0x1344, 0x2b0c, 0x4354, + 0x3630, 0x0820, 0x1444, 0x2a0c, 0x4254, + 0x3634, 0x0920, 0x1544, 0x2a10, 0x4258, + 0x3734, 0x0a20, 0x1644, 0x2b10, 0x4458, + 0x3834, 0x0b20, 0x1744, 0x2c10, 0x4658, + 0x3c24, 0x0f10, 0x1b34, 0x3000, 0x0048, + 0x3d24, 0x1010, 0x1c34, 0x3100, 0x0148, + 0x3e24, 0x1110, 0x1d34, 0x3200, 0x0248, + 0x3f24, 0x1114, 0x1d38, 0x3300, 0x0348, + 0x4024, 0x1014, 0x1c38, 0x3400, 0x0448, + 0x4124, 0x0f14, 0x1b38, 0x3500, 0x0548, + 0x4128, 0x0e14, 0x1a38, 0x3504, 0x054c, + 0x4028, 0x0d14, 0x1938, 0x3404, 0x044c, + 0x3f28, 0x0c14, 0x1838, 0x3304, 0x034c, + 0x3e28, 0x0c18, 0x183c, 0x3204, 0x024c, + 0x3d28, 0x0d18, 0x193c, 0x3104, 0x014c, + 0x3c28, 0x0e18, 0x1a3c, 0x3004, 0x004c, + 0x3c2c, 0x0f18, 0x1b3c, 0x3008, 0x0050, + 0x3d2c, 0x1018, 0x1c3c, 0x3108, 0x0150, + 0x3e2c, 0x1118, 0x1d3c, 0x3208, 0x0250, + 0x3f2c, 0x111c, 0x1d40, 0x3308, 0x0350, + 0x402c, 0x101c, 0x1c40, 0x3408, 0x0450, + 0x412c, 0x0f1c, 0x1b40, 0x3508, 0x0550, + 0x4130, 0x0e1c, 0x1a40, 0x350c, 0x0554, + 0x4030, 0x0d1c, 0x1940, 0x340c, 0x0454, + 0x3f30, 0x0c1c, 0x1840, 0x330c, 0x0354, + 0x3e30, 0x0c20, 0x1844, 0x320c, 0x0254, + 0x3d30, 0x0d20, 0x1944, 0x310c, 0x0154, + 0x3c30, 0x0e20, 0x1a44, 0x300c, 0x0054, + 0x3c34, 0x0f20, 0x1b44, 0x3010, 0x0058, + 0x3d34, 0x1020, 0x1c44, 0x3110, 0x0258, + 0x3e34, 0x1120, 0x1d44, 0x3210, 0x0458, + 0x4224, 0x1510, 0x2134, 0x3600, 0x0648, + 0x4324, 0x1610, 0x2234, 0x3700, 0x0748, + 0x4424, 0x1710, 0x2334, 0x3800, 0x0848, + 0x4524, 0x1714, 0x2338, 0x3900, 0x0948, + 0x4624, 0x1614, 0x2238, 0x3a00, 0x0a48, + 0x4724, 0x1514, 0x2138, 0x3b00, 0x0b48, + 0x4728, 0x1414, 0x2038, 0x3b04, 0x0b4c, + 0x4628, 0x1314, 0x1f38, 0x3a04, 0x0a4c, + 0x4528, 0x1214, 0x1e38, 0x3904, 0x094c, + 0x4428, 0x1218, 0x1e3c, 0x3804, 0x084c, + 0x4328, 0x1318, 0x1f3c, 0x3704, 0x074c, + 0x4228, 0x1418, 0x203c, 0x3604, 0x064c, + 0x422c, 0x1518, 0x213c, 0x3608, 0x0650, + 0x432c, 0x1618, 0x223c, 0x3708, 0x0750, + 0x442c, 0x1718, 0x233c, 0x3808, 0x0850, + 0x452c, 0x171c, 0x2340, 0x3908, 0x0950, + 0x462c, 0x161c, 0x2240, 0x3a08, 0x0a50, + 0x472c, 0x151c, 0x2140, 0x3b08, 0x0b50, + 0x4730, 0x141c, 0x2040, 0x3b0c, 0x0b54, + 0x4630, 0x131c, 0x1f40, 0x3a0c, 0x0a54, + 0x4530, 0x121c, 0x1e40, 0x390c, 0x0954, + 0x4430, 0x1220, 0x1e44, 0x380c, 0x0854, + 0x4330, 0x1320, 0x1f44, 0x370c, 0x0754, + 0x4230, 0x1420, 0x2044, 0x360c, 0x0654, + 0x4234, 0x1520, 0x2144, 0x3610, 0x0658, + 0x4334, 0x1620, 0x2244, 0x3710, 0x0858, + 0x4434, 0x1720, 0x2344, 0x3810, 0x0a58, + 0x0024, 0x1b10, 0x2734, 0x3c00, 0x0c48, + 0x0124, 0x1c10, 0x2834, 0x3d00, 0x0d48, + 0x0224, 0x1d10, 0x2934, 0x3e00, 0x0e48, + 0x0324, 0x1d14, 0x2938, 0x3f00, 0x0f48, + 0x0424, 0x1c14, 0x2838, 0x4000, 0x1048, + 0x0524, 0x1b14, 0x2738, 0x4100, 0x1148, + 0x0528, 0x1a14, 0x2638, 0x4104, 0x114c, + 0x0428, 0x1914, 0x2538, 0x4004, 0x104c, + 0x0328, 0x1814, 0x2438, 0x3f04, 0x0f4c, + 0x0228, 0x1818, 0x243c, 0x3e04, 0x0e4c, + 0x0128, 0x1918, 0x253c, 0x3d04, 0x0d4c, + 0x0028, 0x1a18, 0x263c, 0x3c04, 0x0c4c, + 0x002c, 0x1b18, 0x273c, 0x3c08, 0x0c50, + 0x012c, 0x1c18, 0x283c, 0x3d08, 0x0d50, + 0x022c, 0x1d18, 0x293c, 0x3e08, 0x0e50, + 0x032c, 0x1d1c, 0x2940, 0x3f08, 0x0f50, + 0x042c, 0x1c1c, 0x2840, 0x4008, 0x1050, + 0x052c, 0x1b1c, 0x2740, 0x4108, 0x1150, + 0x0530, 0x1a1c, 0x2640, 0x410c, 0x1154, + 0x0430, 0x191c, 0x2540, 0x400c, 0x1054, + 0x0330, 0x181c, 0x2440, 0x3f0c, 0x0f54, + 0x0230, 0x1820, 0x2444, 0x3e0c, 0x0e54, + 0x0130, 0x1920, 0x2544, 0x3d0c, 0x0d54, + 0x0030, 0x1a20, 0x2644, 0x3c0c, 0x0c54, + 0x0034, 0x1b20, 0x2744, 0x3c10, 0x0c58, + 0x0134, 0x1c20, 0x2844, 0x3d10, 0x0e58, + 0x0234, 0x1d20, 0x2944, 0x3e10, 0x1058, + 0x0624, 0x2110, 0x2d34, 0x4200, 0x1248, + 0x0724, 0x2210, 0x2e34, 0x4300, 0x1348, + 0x0824, 0x2310, 0x2f34, 0x4400, 0x1448, + 0x0924, 0x2314, 0x2f38, 0x4500, 0x1548, + 0x0a24, 0x2214, 0x2e38, 0x4600, 0x1648, + 0x0b24, 0x2114, 0x2d38, 0x4700, 0x1748, + 0x0b28, 0x2014, 0x2c38, 0x4704, 0x174c, + 0x0a28, 0x1f14, 0x2b38, 0x4604, 0x164c, + 0x0928, 0x1e14, 0x2a38, 0x4504, 0x154c, + 0x0828, 0x1e18, 0x2a3c, 0x4404, 0x144c, + 0x0728, 0x1f18, 0x2b3c, 0x4304, 0x134c, + 0x0628, 0x2018, 0x2c3c, 0x4204, 0x124c, + 0x062c, 0x2118, 0x2d3c, 0x4208, 0x1250, + 0x072c, 0x2218, 0x2e3c, 0x4308, 0x1350, + 0x082c, 0x2318, 0x2f3c, 0x4408, 0x1450, + 0x092c, 0x231c, 0x2f40, 0x4508, 0x1550, + 0x0a2c, 0x221c, 0x2e40, 0x4608, 0x1650, + 0x0b2c, 0x211c, 0x2d40, 0x4708, 0x1750, + 0x0b30, 0x201c, 0x2c40, 0x470c, 0x1754, + 0x0a30, 0x1f1c, 0x2b40, 0x460c, 0x1654, + 0x0930, 0x1e1c, 0x2a40, 0x450c, 0x1554, + 0x0830, 0x1e20, 0x2a44, 0x440c, 0x1454, + 0x0730, 0x1f20, 0x2b44, 0x430c, 0x1354, + 0x0630, 0x2020, 0x2c44, 0x420c, 0x1254, + 0x0634, 0x2120, 0x2d44, 0x4210, 0x1258, + 0x0734, 0x2220, 0x2e44, 0x4310, 0x1458, + 0x0834, 0x2320, 0x2f44, 0x4410, 0x1658, +}; + +static const uint16_t dv_place_411[1350] = { + 0x0c24, 0x2710, 0x3334, 0x0000, 0x1848, + 0x0d24, 0x2810, 0x3434, 0x0100, 0x1948, + 0x0e24, 0x2910, 0x3534, 0x0200, 0x1a48, + 0x0f24, 0x2914, 0x3538, 0x0300, 0x1b48, + 0x1024, 0x2814, 0x3438, 0x0400, 0x1c48, + 0x1124, 0x2714, 0x3338, 0x0500, 0x1d48, + 0x1128, 0x2614, 0x3238, 0x0504, 0x1d4c, + 0x1028, 0x2514, 0x3138, 0x0404, 0x1c4c, + 0x0f28, 0x2414, 0x3038, 0x0304, 0x1b4c, + 0x0e28, 0x2418, 0x303c, 0x0204, 0x1a4c, + 0x0d28, 0x2518, 0x313c, 0x0104, 0x194c, + 0x0c28, 0x2618, 0x323c, 0x0004, 0x184c, + 0x0c2c, 0x2718, 0x333c, 0x0008, 0x1850, + 0x0d2c, 0x2818, 0x343c, 0x0108, 0x1950, + 0x0e2c, 0x2918, 0x353c, 0x0208, 0x1a50, + 0x0f2c, 0x291c, 0x3540, 0x0308, 0x1b50, + 0x102c, 0x281c, 0x3440, 0x0408, 0x1c50, + 0x112c, 0x271c, 0x3340, 0x0508, 0x1d50, + 0x1130, 0x261c, 0x3240, 0x050c, 0x1d54, + 0x1030, 0x251c, 0x3140, 0x040c, 0x1c54, + 0x0f30, 0x241c, 0x3040, 0x030c, 0x1b54, + 0x0e30, 0x2420, 0x3044, 0x020c, 0x1a54, + 0x0d30, 0x2520, 0x3144, 0x010c, 0x1954, + 0x0c30, 0x2620, 0x3244, 0x000c, 0x1854, + 0x0c34, 0x2720, 0x3344, 0x0010, 0x1858, + 0x0d34, 0x2820, 0x3444, 0x0110, 0x1a58, + 0x0e34, 0x2920, 0x3544, 0x0210, 0x1c58, + 0x1224, 0x2d10, 0x3934, 0x0600, 0x1e48, + 0x1324, 0x2e10, 0x3a34, 0x0700, 0x1f48, + 0x1424, 0x2f10, 0x3b34, 0x0800, 0x2048, + 0x1524, 0x2f14, 0x3b38, 0x0900, 0x2148, + 0x1624, 0x2e14, 0x3a38, 0x0a00, 0x2248, + 0x1724, 0x2d14, 0x3938, 0x0b00, 0x2348, + 0x1728, 0x2c14, 0x3838, 0x0b04, 0x234c, + 0x1628, 0x2b14, 0x3738, 0x0a04, 0x224c, + 0x1528, 0x2a14, 0x3638, 0x0904, 0x214c, + 0x1428, 0x2a18, 0x363c, 0x0804, 0x204c, + 0x1328, 0x2b18, 0x373c, 0x0704, 0x1f4c, + 0x1228, 0x2c18, 0x383c, 0x0604, 0x1e4c, + 0x122c, 0x2d18, 0x393c, 0x0608, 0x1e50, + 0x132c, 0x2e18, 0x3a3c, 0x0708, 0x1f50, + 0x142c, 0x2f18, 0x3b3c, 0x0808, 0x2050, + 0x152c, 0x2f1c, 0x3b40, 0x0908, 0x2150, + 0x162c, 0x2e1c, 0x3a40, 0x0a08, 0x2250, + 0x172c, 0x2d1c, 0x3940, 0x0b08, 0x2350, + 0x1730, 0x2c1c, 0x3840, 0x0b0c, 0x2354, + 0x1630, 0x2b1c, 0x3740, 0x0a0c, 0x2254, + 0x1530, 0x2a1c, 0x3640, 0x090c, 0x2154, + 0x1430, 0x2a20, 0x3644, 0x080c, 0x2054, + 0x1330, 0x2b20, 0x3744, 0x070c, 0x1f54, + 0x1230, 0x2c20, 0x3844, 0x060c, 0x1e54, + 0x1234, 0x2d20, 0x3944, 0x0610, 0x1e58, + 0x1334, 0x2e20, 0x3a44, 0x0710, 0x2058, + 0x1434, 0x2f20, 0x3b44, 0x0810, 0x2258, + 0x1824, 0x3310, 0x0334, 0x0c00, 0x2448, + 0x1924, 0x3410, 0x0434, 0x0d00, 0x2548, + 0x1a24, 0x3510, 0x0534, 0x0e00, 0x2648, + 0x1b24, 0x3514, 0x0538, 0x0f00, 0x2748, + 0x1c24, 0x3414, 0x0438, 0x1000, 0x2848, + 0x1d24, 0x3314, 0x0338, 0x1100, 0x2948, + 0x1d28, 0x3214, 0x0238, 0x1104, 0x294c, + 0x1c28, 0x3114, 0x0138, 0x1004, 0x284c, + 0x1b28, 0x3014, 0x0038, 0x0f04, 0x274c, + 0x1a28, 0x3018, 0x003c, 0x0e04, 0x264c, + 0x1928, 0x3118, 0x013c, 0x0d04, 0x254c, + 0x1828, 0x3218, 0x023c, 0x0c04, 0x244c, + 0x182c, 0x3318, 0x033c, 0x0c08, 0x2450, + 0x192c, 0x3418, 0x043c, 0x0d08, 0x2550, + 0x1a2c, 0x3518, 0x053c, 0x0e08, 0x2650, + 0x1b2c, 0x351c, 0x0540, 0x0f08, 0x2750, + 0x1c2c, 0x341c, 0x0440, 0x1008, 0x2850, + 0x1d2c, 0x331c, 0x0340, 0x1108, 0x2950, + 0x1d30, 0x321c, 0x0240, 0x110c, 0x2954, + 0x1c30, 0x311c, 0x0140, 0x100c, 0x2854, + 0x1b30, 0x301c, 0x0040, 0x0f0c, 0x2754, + 0x1a30, 0x3020, 0x0044, 0x0e0c, 0x2654, + 0x1930, 0x3120, 0x0144, 0x0d0c, 0x2554, + 0x1830, 0x3220, 0x0244, 0x0c0c, 0x2454, + 0x1834, 0x3320, 0x0344, 0x0c10, 0x2458, + 0x1934, 0x3420, 0x0444, 0x0d10, 0x2658, + 0x1a34, 0x3520, 0x0544, 0x0e10, 0x2858, + 0x1e24, 0x3910, 0x0934, 0x1200, 0x2a48, + 0x1f24, 0x3a10, 0x0a34, 0x1300, 0x2b48, + 0x2024, 0x3b10, 0x0b34, 0x1400, 0x2c48, + 0x2124, 0x3b14, 0x0b38, 0x1500, 0x2d48, + 0x2224, 0x3a14, 0x0a38, 0x1600, 0x2e48, + 0x2324, 0x3914, 0x0938, 0x1700, 0x2f48, + 0x2328, 0x3814, 0x0838, 0x1704, 0x2f4c, + 0x2228, 0x3714, 0x0738, 0x1604, 0x2e4c, + 0x2128, 0x3614, 0x0638, 0x1504, 0x2d4c, + 0x2028, 0x3618, 0x063c, 0x1404, 0x2c4c, + 0x1f28, 0x3718, 0x073c, 0x1304, 0x2b4c, + 0x1e28, 0x3818, 0x083c, 0x1204, 0x2a4c, + 0x1e2c, 0x3918, 0x093c, 0x1208, 0x2a50, + 0x1f2c, 0x3a18, 0x0a3c, 0x1308, 0x2b50, + 0x202c, 0x3b18, 0x0b3c, 0x1408, 0x2c50, + 0x212c, 0x3b1c, 0x0b40, 0x1508, 0x2d50, + 0x222c, 0x3a1c, 0x0a40, 0x1608, 0x2e50, + 0x232c, 0x391c, 0x0940, 0x1708, 0x2f50, + 0x2330, 0x381c, 0x0840, 0x170c, 0x2f54, + 0x2230, 0x371c, 0x0740, 0x160c, 0x2e54, + 0x2130, 0x361c, 0x0640, 0x150c, 0x2d54, + 0x2030, 0x3620, 0x0644, 0x140c, 0x2c54, + 0x1f30, 0x3720, 0x0744, 0x130c, 0x2b54, + 0x1e30, 0x3820, 0x0844, 0x120c, 0x2a54, + 0x1e34, 0x3920, 0x0944, 0x1210, 0x2a58, + 0x1f34, 0x3a20, 0x0a44, 0x1310, 0x2c58, + 0x2034, 0x3b20, 0x0b44, 0x1410, 0x2e58, + 0x2424, 0x0310, 0x0f34, 0x1800, 0x3048, + 0x2524, 0x0410, 0x1034, 0x1900, 0x3148, + 0x2624, 0x0510, 0x1134, 0x1a00, 0x3248, + 0x2724, 0x0514, 0x1138, 0x1b00, 0x3348, + 0x2824, 0x0414, 0x1038, 0x1c00, 0x3448, + 0x2924, 0x0314, 0x0f38, 0x1d00, 0x3548, + 0x2928, 0x0214, 0x0e38, 0x1d04, 0x354c, + 0x2828, 0x0114, 0x0d38, 0x1c04, 0x344c, + 0x2728, 0x0014, 0x0c38, 0x1b04, 0x334c, + 0x2628, 0x0018, 0x0c3c, 0x1a04, 0x324c, + 0x2528, 0x0118, 0x0d3c, 0x1904, 0x314c, + 0x2428, 0x0218, 0x0e3c, 0x1804, 0x304c, + 0x242c, 0x0318, 0x0f3c, 0x1808, 0x3050, + 0x252c, 0x0418, 0x103c, 0x1908, 0x3150, + 0x262c, 0x0518, 0x113c, 0x1a08, 0x3250, + 0x272c, 0x051c, 0x1140, 0x1b08, 0x3350, + 0x282c, 0x041c, 0x1040, 0x1c08, 0x3450, + 0x292c, 0x031c, 0x0f40, 0x1d08, 0x3550, + 0x2930, 0x021c, 0x0e40, 0x1d0c, 0x3554, + 0x2830, 0x011c, 0x0d40, 0x1c0c, 0x3454, + 0x2730, 0x001c, 0x0c40, 0x1b0c, 0x3354, + 0x2630, 0x0020, 0x0c44, 0x1a0c, 0x3254, + 0x2530, 0x0120, 0x0d44, 0x190c, 0x3154, + 0x2430, 0x0220, 0x0e44, 0x180c, 0x3054, + 0x2434, 0x0320, 0x0f44, 0x1810, 0x3058, + 0x2534, 0x0420, 0x1044, 0x1910, 0x3258, + 0x2634, 0x0520, 0x1144, 0x1a10, 0x3458, + 0x2a24, 0x0910, 0x1534, 0x1e00, 0x3648, + 0x2b24, 0x0a10, 0x1634, 0x1f00, 0x3748, + 0x2c24, 0x0b10, 0x1734, 0x2000, 0x3848, + 0x2d24, 0x0b14, 0x1738, 0x2100, 0x3948, + 0x2e24, 0x0a14, 0x1638, 0x2200, 0x3a48, + 0x2f24, 0x0914, 0x1538, 0x2300, 0x3b48, + 0x2f28, 0x0814, 0x1438, 0x2304, 0x3b4c, + 0x2e28, 0x0714, 0x1338, 0x2204, 0x3a4c, + 0x2d28, 0x0614, 0x1238, 0x2104, 0x394c, + 0x2c28, 0x0618, 0x123c, 0x2004, 0x384c, + 0x2b28, 0x0718, 0x133c, 0x1f04, 0x374c, + 0x2a28, 0x0818, 0x143c, 0x1e04, 0x364c, + 0x2a2c, 0x0918, 0x153c, 0x1e08, 0x3650, + 0x2b2c, 0x0a18, 0x163c, 0x1f08, 0x3750, + 0x2c2c, 0x0b18, 0x173c, 0x2008, 0x3850, + 0x2d2c, 0x0b1c, 0x1740, 0x2108, 0x3950, + 0x2e2c, 0x0a1c, 0x1640, 0x2208, 0x3a50, + 0x2f2c, 0x091c, 0x1540, 0x2308, 0x3b50, + 0x2f30, 0x081c, 0x1440, 0x230c, 0x3b54, + 0x2e30, 0x071c, 0x1340, 0x220c, 0x3a54, + 0x2d30, 0x061c, 0x1240, 0x210c, 0x3954, + 0x2c30, 0x0620, 0x1244, 0x200c, 0x3854, + 0x2b30, 0x0720, 0x1344, 0x1f0c, 0x3754, + 0x2a30, 0x0820, 0x1444, 0x1e0c, 0x3654, + 0x2a34, 0x0920, 0x1544, 0x1e10, 0x3658, + 0x2b34, 0x0a20, 0x1644, 0x1f10, 0x3858, + 0x2c34, 0x0b20, 0x1744, 0x2010, 0x3a58, + 0x3024, 0x0f10, 0x1b34, 0x2400, 0x0048, + 0x3124, 0x1010, 0x1c34, 0x2500, 0x0148, + 0x3224, 0x1110, 0x1d34, 0x2600, 0x0248, + 0x3324, 0x1114, 0x1d38, 0x2700, 0x0348, + 0x3424, 0x1014, 0x1c38, 0x2800, 0x0448, + 0x3524, 0x0f14, 0x1b38, 0x2900, 0x0548, + 0x3528, 0x0e14, 0x1a38, 0x2904, 0x054c, + 0x3428, 0x0d14, 0x1938, 0x2804, 0x044c, + 0x3328, 0x0c14, 0x1838, 0x2704, 0x034c, + 0x3228, 0x0c18, 0x183c, 0x2604, 0x024c, + 0x3128, 0x0d18, 0x193c, 0x2504, 0x014c, + 0x3028, 0x0e18, 0x1a3c, 0x2404, 0x004c, + 0x302c, 0x0f18, 0x1b3c, 0x2408, 0x0050, + 0x312c, 0x1018, 0x1c3c, 0x2508, 0x0150, + 0x322c, 0x1118, 0x1d3c, 0x2608, 0x0250, + 0x332c, 0x111c, 0x1d40, 0x2708, 0x0350, + 0x342c, 0x101c, 0x1c40, 0x2808, 0x0450, + 0x352c, 0x0f1c, 0x1b40, 0x2908, 0x0550, + 0x3530, 0x0e1c, 0x1a40, 0x290c, 0x0554, + 0x3430, 0x0d1c, 0x1940, 0x280c, 0x0454, + 0x3330, 0x0c1c, 0x1840, 0x270c, 0x0354, + 0x3230, 0x0c20, 0x1844, 0x260c, 0x0254, + 0x3130, 0x0d20, 0x1944, 0x250c, 0x0154, + 0x3030, 0x0e20, 0x1a44, 0x240c, 0x0054, + 0x3034, 0x0f20, 0x1b44, 0x2410, 0x0058, + 0x3134, 0x1020, 0x1c44, 0x2510, 0x0258, + 0x3234, 0x1120, 0x1d44, 0x2610, 0x0458, + 0x3624, 0x1510, 0x2134, 0x2a00, 0x0648, + 0x3724, 0x1610, 0x2234, 0x2b00, 0x0748, + 0x3824, 0x1710, 0x2334, 0x2c00, 0x0848, + 0x3924, 0x1714, 0x2338, 0x2d00, 0x0948, + 0x3a24, 0x1614, 0x2238, 0x2e00, 0x0a48, + 0x3b24, 0x1514, 0x2138, 0x2f00, 0x0b48, + 0x3b28, 0x1414, 0x2038, 0x2f04, 0x0b4c, + 0x3a28, 0x1314, 0x1f38, 0x2e04, 0x0a4c, + 0x3928, 0x1214, 0x1e38, 0x2d04, 0x094c, + 0x3828, 0x1218, 0x1e3c, 0x2c04, 0x084c, + 0x3728, 0x1318, 0x1f3c, 0x2b04, 0x074c, + 0x3628, 0x1418, 0x203c, 0x2a04, 0x064c, + 0x362c, 0x1518, 0x213c, 0x2a08, 0x0650, + 0x372c, 0x1618, 0x223c, 0x2b08, 0x0750, + 0x382c, 0x1718, 0x233c, 0x2c08, 0x0850, + 0x392c, 0x171c, 0x2340, 0x2d08, 0x0950, + 0x3a2c, 0x161c, 0x2240, 0x2e08, 0x0a50, + 0x3b2c, 0x151c, 0x2140, 0x2f08, 0x0b50, + 0x3b30, 0x141c, 0x2040, 0x2f0c, 0x0b54, + 0x3a30, 0x131c, 0x1f40, 0x2e0c, 0x0a54, + 0x3930, 0x121c, 0x1e40, 0x2d0c, 0x0954, + 0x3830, 0x1220, 0x1e44, 0x2c0c, 0x0854, + 0x3730, 0x1320, 0x1f44, 0x2b0c, 0x0754, + 0x3630, 0x1420, 0x2044, 0x2a0c, 0x0654, + 0x3634, 0x1520, 0x2144, 0x2a10, 0x0658, + 0x3734, 0x1620, 0x2244, 0x2b10, 0x0858, + 0x3834, 0x1720, 0x2344, 0x2c10, 0x0a58, + 0x0024, 0x1b10, 0x2734, 0x3000, 0x0c48, + 0x0124, 0x1c10, 0x2834, 0x3100, 0x0d48, + 0x0224, 0x1d10, 0x2934, 0x3200, 0x0e48, + 0x0324, 0x1d14, 0x2938, 0x3300, 0x0f48, + 0x0424, 0x1c14, 0x2838, 0x3400, 0x1048, + 0x0524, 0x1b14, 0x2738, 0x3500, 0x1148, + 0x0528, 0x1a14, 0x2638, 0x3504, 0x114c, + 0x0428, 0x1914, 0x2538, 0x3404, 0x104c, + 0x0328, 0x1814, 0x2438, 0x3304, 0x0f4c, + 0x0228, 0x1818, 0x243c, 0x3204, 0x0e4c, + 0x0128, 0x1918, 0x253c, 0x3104, 0x0d4c, + 0x0028, 0x1a18, 0x263c, 0x3004, 0x0c4c, + 0x002c, 0x1b18, 0x273c, 0x3008, 0x0c50, + 0x012c, 0x1c18, 0x283c, 0x3108, 0x0d50, + 0x022c, 0x1d18, 0x293c, 0x3208, 0x0e50, + 0x032c, 0x1d1c, 0x2940, 0x3308, 0x0f50, + 0x042c, 0x1c1c, 0x2840, 0x3408, 0x1050, + 0x052c, 0x1b1c, 0x2740, 0x3508, 0x1150, + 0x0530, 0x1a1c, 0x2640, 0x350c, 0x1154, + 0x0430, 0x191c, 0x2540, 0x340c, 0x1054, + 0x0330, 0x181c, 0x2440, 0x330c, 0x0f54, + 0x0230, 0x1820, 0x2444, 0x320c, 0x0e54, + 0x0130, 0x1920, 0x2544, 0x310c, 0x0d54, + 0x0030, 0x1a20, 0x2644, 0x300c, 0x0c54, + 0x0034, 0x1b20, 0x2744, 0x3010, 0x0c58, + 0x0134, 0x1c20, 0x2844, 0x3110, 0x0e58, + 0x0234, 0x1d20, 0x2944, 0x3210, 0x1058, + 0x0624, 0x2110, 0x2d34, 0x3600, 0x1248, + 0x0724, 0x2210, 0x2e34, 0x3700, 0x1348, + 0x0824, 0x2310, 0x2f34, 0x3800, 0x1448, + 0x0924, 0x2314, 0x2f38, 0x3900, 0x1548, + 0x0a24, 0x2214, 0x2e38, 0x3a00, 0x1648, + 0x0b24, 0x2114, 0x2d38, 0x3b00, 0x1748, + 0x0b28, 0x2014, 0x2c38, 0x3b04, 0x174c, + 0x0a28, 0x1f14, 0x2b38, 0x3a04, 0x164c, + 0x0928, 0x1e14, 0x2a38, 0x3904, 0x154c, + 0x0828, 0x1e18, 0x2a3c, 0x3804, 0x144c, + 0x0728, 0x1f18, 0x2b3c, 0x3704, 0x134c, + 0x0628, 0x2018, 0x2c3c, 0x3604, 0x124c, + 0x062c, 0x2118, 0x2d3c, 0x3608, 0x1250, + 0x072c, 0x2218, 0x2e3c, 0x3708, 0x1350, + 0x082c, 0x2318, 0x2f3c, 0x3808, 0x1450, + 0x092c, 0x231c, 0x2f40, 0x3908, 0x1550, + 0x0a2c, 0x221c, 0x2e40, 0x3a08, 0x1650, + 0x0b2c, 0x211c, 0x2d40, 0x3b08, 0x1750, + 0x0b30, 0x201c, 0x2c40, 0x3b0c, 0x1754, + 0x0a30, 0x1f1c, 0x2b40, 0x3a0c, 0x1654, + 0x0930, 0x1e1c, 0x2a40, 0x390c, 0x1554, + 0x0830, 0x1e20, 0x2a44, 0x380c, 0x1454, + 0x0730, 0x1f20, 0x2b44, 0x370c, 0x1354, + 0x0630, 0x2020, 0x2c44, 0x360c, 0x1254, + 0x0634, 0x2120, 0x2d44, 0x3610, 0x1258, + 0x0734, 0x2220, 0x2e44, 0x3710, 0x1458, + 0x0834, 0x2320, 0x2f44, 0x3810, 0x1658, +}; + +/* 4:2:2 macroblock placement tables created by dvtables.py */ + +/* 2 channels per frame, 10 DIF sequences per channel, + 27 video segments per DIF sequence, 5 macroblocks per video segment */ +static const uint16_t dv_place_422_525[2*10*27*5] = { + 0x0c48, 0x2424, 0x306c, 0x0000, 0x1890, + 0x0d48, 0x2524, 0x316c, 0x0100, 0x1990, + 0x0e48, 0x2624, 0x326c, 0x0200, 0x1a90, + 0x0e4c, 0x2628, 0x3270, 0x0204, 0x1a94, + 0x0d4c, 0x2528, 0x3170, 0x0104, 0x1994, + 0x0c4c, 0x2428, 0x3070, 0x0004, 0x1894, + 0x0c50, 0x242c, 0x3074, 0x0008, 0x1898, + 0x0d50, 0x252c, 0x3174, 0x0108, 0x1998, + 0x0e50, 0x262c, 0x3274, 0x0208, 0x1a98, + 0x0e54, 0x2630, 0x3278, 0x020c, 0x1a9c, + 0x0d54, 0x2530, 0x3178, 0x010c, 0x199c, + 0x0c54, 0x2430, 0x3078, 0x000c, 0x189c, + 0x0c58, 0x2434, 0x307c, 0x0010, 0x18a0, + 0x0d58, 0x2534, 0x317c, 0x0110, 0x19a0, + 0x0e58, 0x2634, 0x327c, 0x0210, 0x1aa0, + 0x0e5c, 0x2638, 0x3280, 0x0214, 0x1aa4, + 0x0d5c, 0x2538, 0x3180, 0x0114, 0x19a4, + 0x0c5c, 0x2438, 0x3080, 0x0014, 0x18a4, + 0x0c60, 0x243c, 0x3084, 0x0018, 0x18a8, + 0x0d60, 0x253c, 0x3184, 0x0118, 0x19a8, + 0x0e60, 0x263c, 0x3284, 0x0218, 0x1aa8, + 0x0e64, 0x2640, 0x3288, 0x021c, 0x1aac, + 0x0d64, 0x2540, 0x3188, 0x011c, 0x19ac, + 0x0c64, 0x2440, 0x3088, 0x001c, 0x18ac, + 0x0c68, 0x2444, 0x308c, 0x0020, 0x18b0, + 0x0d68, 0x2544, 0x318c, 0x0120, 0x19b0, + 0x0e68, 0x2644, 0x328c, 0x0220, 0x1ab0, + 0x1248, 0x2a24, 0x366c, 0x0600, 0x1e90, + 0x1348, 0x2b24, 0x376c, 0x0700, 0x1f90, + 0x1448, 0x2c24, 0x386c, 0x0800, 0x2090, + 0x144c, 0x2c28, 0x3870, 0x0804, 0x2094, + 0x134c, 0x2b28, 0x3770, 0x0704, 0x1f94, + 0x124c, 0x2a28, 0x3670, 0x0604, 0x1e94, + 0x1250, 0x2a2c, 0x3674, 0x0608, 0x1e98, + 0x1350, 0x2b2c, 0x3774, 0x0708, 0x1f98, + 0x1450, 0x2c2c, 0x3874, 0x0808, 0x2098, + 0x1454, 0x2c30, 0x3878, 0x080c, 0x209c, + 0x1354, 0x2b30, 0x3778, 0x070c, 0x1f9c, + 0x1254, 0x2a30, 0x3678, 0x060c, 0x1e9c, + 0x1258, 0x2a34, 0x367c, 0x0610, 0x1ea0, + 0x1358, 0x2b34, 0x377c, 0x0710, 0x1fa0, + 0x1458, 0x2c34, 0x387c, 0x0810, 0x20a0, + 0x145c, 0x2c38, 0x3880, 0x0814, 0x20a4, + 0x135c, 0x2b38, 0x3780, 0x0714, 0x1fa4, + 0x125c, 0x2a38, 0x3680, 0x0614, 0x1ea4, + 0x1260, 0x2a3c, 0x3684, 0x0618, 0x1ea8, + 0x1360, 0x2b3c, 0x3784, 0x0718, 0x1fa8, + 0x1460, 0x2c3c, 0x3884, 0x0818, 0x20a8, + 0x1464, 0x2c40, 0x3888, 0x081c, 0x20ac, + 0x1364, 0x2b40, 0x3788, 0x071c, 0x1fac, + 0x1264, 0x2a40, 0x3688, 0x061c, 0x1eac, + 0x1268, 0x2a44, 0x368c, 0x0620, 0x1eb0, + 0x1368, 0x2b44, 0x378c, 0x0720, 0x1fb0, + 0x1468, 0x2c44, 0x388c, 0x0820, 0x20b0, + 0x1848, 0x3024, 0x006c, 0x0c00, 0x2490, + 0x1948, 0x3124, 0x016c, 0x0d00, 0x2590, + 0x1a48, 0x3224, 0x026c, 0x0e00, 0x2690, + 0x1a4c, 0x3228, 0x0270, 0x0e04, 0x2694, + 0x194c, 0x3128, 0x0170, 0x0d04, 0x2594, + 0x184c, 0x3028, 0x0070, 0x0c04, 0x2494, + 0x1850, 0x302c, 0x0074, 0x0c08, 0x2498, + 0x1950, 0x312c, 0x0174, 0x0d08, 0x2598, + 0x1a50, 0x322c, 0x0274, 0x0e08, 0x2698, + 0x1a54, 0x3230, 0x0278, 0x0e0c, 0x269c, + 0x1954, 0x3130, 0x0178, 0x0d0c, 0x259c, + 0x1854, 0x3030, 0x0078, 0x0c0c, 0x249c, + 0x1858, 0x3034, 0x007c, 0x0c10, 0x24a0, + 0x1958, 0x3134, 0x017c, 0x0d10, 0x25a0, + 0x1a58, 0x3234, 0x027c, 0x0e10, 0x26a0, + 0x1a5c, 0x3238, 0x0280, 0x0e14, 0x26a4, + 0x195c, 0x3138, 0x0180, 0x0d14, 0x25a4, + 0x185c, 0x3038, 0x0080, 0x0c14, 0x24a4, + 0x1860, 0x303c, 0x0084, 0x0c18, 0x24a8, + 0x1960, 0x313c, 0x0184, 0x0d18, 0x25a8, + 0x1a60, 0x323c, 0x0284, 0x0e18, 0x26a8, + 0x1a64, 0x3240, 0x0288, 0x0e1c, 0x26ac, + 0x1964, 0x3140, 0x0188, 0x0d1c, 0x25ac, + 0x1864, 0x3040, 0x0088, 0x0c1c, 0x24ac, + 0x1868, 0x3044, 0x008c, 0x0c20, 0x24b0, + 0x1968, 0x3144, 0x018c, 0x0d20, 0x25b0, + 0x1a68, 0x3244, 0x028c, 0x0e20, 0x26b0, + 0x1e48, 0x3624, 0x066c, 0x1200, 0x2a90, + 0x1f48, 0x3724, 0x076c, 0x1300, 0x2b90, + 0x2048, 0x3824, 0x086c, 0x1400, 0x2c90, + 0x204c, 0x3828, 0x0870, 0x1404, 0x2c94, + 0x1f4c, 0x3728, 0x0770, 0x1304, 0x2b94, + 0x1e4c, 0x3628, 0x0670, 0x1204, 0x2a94, + 0x1e50, 0x362c, 0x0674, 0x1208, 0x2a98, + 0x1f50, 0x372c, 0x0774, 0x1308, 0x2b98, + 0x2050, 0x382c, 0x0874, 0x1408, 0x2c98, + 0x2054, 0x3830, 0x0878, 0x140c, 0x2c9c, + 0x1f54, 0x3730, 0x0778, 0x130c, 0x2b9c, + 0x1e54, 0x3630, 0x0678, 0x120c, 0x2a9c, + 0x1e58, 0x3634, 0x067c, 0x1210, 0x2aa0, + 0x1f58, 0x3734, 0x077c, 0x1310, 0x2ba0, + 0x2058, 0x3834, 0x087c, 0x1410, 0x2ca0, + 0x205c, 0x3838, 0x0880, 0x1414, 0x2ca4, + 0x1f5c, 0x3738, 0x0780, 0x1314, 0x2ba4, + 0x1e5c, 0x3638, 0x0680, 0x1214, 0x2aa4, + 0x1e60, 0x363c, 0x0684, 0x1218, 0x2aa8, + 0x1f60, 0x373c, 0x0784, 0x1318, 0x2ba8, + 0x2060, 0x383c, 0x0884, 0x1418, 0x2ca8, + 0x2064, 0x3840, 0x0888, 0x141c, 0x2cac, + 0x1f64, 0x3740, 0x0788, 0x131c, 0x2bac, + 0x1e64, 0x3640, 0x0688, 0x121c, 0x2aac, + 0x1e68, 0x3644, 0x068c, 0x1220, 0x2ab0, + 0x1f68, 0x3744, 0x078c, 0x1320, 0x2bb0, + 0x2068, 0x3844, 0x088c, 0x1420, 0x2cb0, + 0x2448, 0x0024, 0x0c6c, 0x1800, 0x3090, + 0x2548, 0x0124, 0x0d6c, 0x1900, 0x3190, + 0x2648, 0x0224, 0x0e6c, 0x1a00, 0x3290, + 0x264c, 0x0228, 0x0e70, 0x1a04, 0x3294, + 0x254c, 0x0128, 0x0d70, 0x1904, 0x3194, + 0x244c, 0x0028, 0x0c70, 0x1804, 0x3094, + 0x2450, 0x002c, 0x0c74, 0x1808, 0x3098, + 0x2550, 0x012c, 0x0d74, 0x1908, 0x3198, + 0x2650, 0x022c, 0x0e74, 0x1a08, 0x3298, + 0x2654, 0x0230, 0x0e78, 0x1a0c, 0x329c, + 0x2554, 0x0130, 0x0d78, 0x190c, 0x319c, + 0x2454, 0x0030, 0x0c78, 0x180c, 0x309c, + 0x2458, 0x0034, 0x0c7c, 0x1810, 0x30a0, + 0x2558, 0x0134, 0x0d7c, 0x1910, 0x31a0, + 0x2658, 0x0234, 0x0e7c, 0x1a10, 0x32a0, + 0x265c, 0x0238, 0x0e80, 0x1a14, 0x32a4, + 0x255c, 0x0138, 0x0d80, 0x1914, 0x31a4, + 0x245c, 0x0038, 0x0c80, 0x1814, 0x30a4, + 0x2460, 0x003c, 0x0c84, 0x1818, 0x30a8, + 0x2560, 0x013c, 0x0d84, 0x1918, 0x31a8, + 0x2660, 0x023c, 0x0e84, 0x1a18, 0x32a8, + 0x2664, 0x0240, 0x0e88, 0x1a1c, 0x32ac, + 0x2564, 0x0140, 0x0d88, 0x191c, 0x31ac, + 0x2464, 0x0040, 0x0c88, 0x181c, 0x30ac, + 0x2468, 0x0044, 0x0c8c, 0x1820, 0x30b0, + 0x2568, 0x0144, 0x0d8c, 0x1920, 0x31b0, + 0x2668, 0x0244, 0x0e8c, 0x1a20, 0x32b0, + 0x2a48, 0x0624, 0x126c, 0x1e00, 0x3690, + 0x2b48, 0x0724, 0x136c, 0x1f00, 0x3790, + 0x2c48, 0x0824, 0x146c, 0x2000, 0x3890, + 0x2c4c, 0x0828, 0x1470, 0x2004, 0x3894, + 0x2b4c, 0x0728, 0x1370, 0x1f04, 0x3794, + 0x2a4c, 0x0628, 0x1270, 0x1e04, 0x3694, + 0x2a50, 0x062c, 0x1274, 0x1e08, 0x3698, + 0x2b50, 0x072c, 0x1374, 0x1f08, 0x3798, + 0x2c50, 0x082c, 0x1474, 0x2008, 0x3898, + 0x2c54, 0x0830, 0x1478, 0x200c, 0x389c, + 0x2b54, 0x0730, 0x1378, 0x1f0c, 0x379c, + 0x2a54, 0x0630, 0x1278, 0x1e0c, 0x369c, + 0x2a58, 0x0634, 0x127c, 0x1e10, 0x36a0, + 0x2b58, 0x0734, 0x137c, 0x1f10, 0x37a0, + 0x2c58, 0x0834, 0x147c, 0x2010, 0x38a0, + 0x2c5c, 0x0838, 0x1480, 0x2014, 0x38a4, + 0x2b5c, 0x0738, 0x1380, 0x1f14, 0x37a4, + 0x2a5c, 0x0638, 0x1280, 0x1e14, 0x36a4, + 0x2a60, 0x063c, 0x1284, 0x1e18, 0x36a8, + 0x2b60, 0x073c, 0x1384, 0x1f18, 0x37a8, + 0x2c60, 0x083c, 0x1484, 0x2018, 0x38a8, + 0x2c64, 0x0840, 0x1488, 0x201c, 0x38ac, + 0x2b64, 0x0740, 0x1388, 0x1f1c, 0x37ac, + 0x2a64, 0x0640, 0x1288, 0x1e1c, 0x36ac, + 0x2a68, 0x0644, 0x128c, 0x1e20, 0x36b0, + 0x2b68, 0x0744, 0x138c, 0x1f20, 0x37b0, + 0x2c68, 0x0844, 0x148c, 0x2020, 0x38b0, + 0x3048, 0x0c24, 0x186c, 0x2400, 0x0090, + 0x3148, 0x0d24, 0x196c, 0x2500, 0x0190, + 0x3248, 0x0e24, 0x1a6c, 0x2600, 0x0290, + 0x324c, 0x0e28, 0x1a70, 0x2604, 0x0294, + 0x314c, 0x0d28, 0x1970, 0x2504, 0x0194, + 0x304c, 0x0c28, 0x1870, 0x2404, 0x0094, + 0x3050, 0x0c2c, 0x1874, 0x2408, 0x0098, + 0x3150, 0x0d2c, 0x1974, 0x2508, 0x0198, + 0x3250, 0x0e2c, 0x1a74, 0x2608, 0x0298, + 0x3254, 0x0e30, 0x1a78, 0x260c, 0x029c, + 0x3154, 0x0d30, 0x1978, 0x250c, 0x019c, + 0x3054, 0x0c30, 0x1878, 0x240c, 0x009c, + 0x3058, 0x0c34, 0x187c, 0x2410, 0x00a0, + 0x3158, 0x0d34, 0x197c, 0x2510, 0x01a0, + 0x3258, 0x0e34, 0x1a7c, 0x2610, 0x02a0, + 0x325c, 0x0e38, 0x1a80, 0x2614, 0x02a4, + 0x315c, 0x0d38, 0x1980, 0x2514, 0x01a4, + 0x305c, 0x0c38, 0x1880, 0x2414, 0x00a4, + 0x3060, 0x0c3c, 0x1884, 0x2418, 0x00a8, + 0x3160, 0x0d3c, 0x1984, 0x2518, 0x01a8, + 0x3260, 0x0e3c, 0x1a84, 0x2618, 0x02a8, + 0x3264, 0x0e40, 0x1a88, 0x261c, 0x02ac, + 0x3164, 0x0d40, 0x1988, 0x251c, 0x01ac, + 0x3064, 0x0c40, 0x1888, 0x241c, 0x00ac, + 0x3068, 0x0c44, 0x188c, 0x2420, 0x00b0, + 0x3168, 0x0d44, 0x198c, 0x2520, 0x01b0, + 0x3268, 0x0e44, 0x1a8c, 0x2620, 0x02b0, + 0x3648, 0x1224, 0x1e6c, 0x2a00, 0x0690, + 0x3748, 0x1324, 0x1f6c, 0x2b00, 0x0790, + 0x3848, 0x1424, 0x206c, 0x2c00, 0x0890, + 0x384c, 0x1428, 0x2070, 0x2c04, 0x0894, + 0x374c, 0x1328, 0x1f70, 0x2b04, 0x0794, + 0x364c, 0x1228, 0x1e70, 0x2a04, 0x0694, + 0x3650, 0x122c, 0x1e74, 0x2a08, 0x0698, + 0x3750, 0x132c, 0x1f74, 0x2b08, 0x0798, + 0x3850, 0x142c, 0x2074, 0x2c08, 0x0898, + 0x3854, 0x1430, 0x2078, 0x2c0c, 0x089c, + 0x3754, 0x1330, 0x1f78, 0x2b0c, 0x079c, + 0x3654, 0x1230, 0x1e78, 0x2a0c, 0x069c, + 0x3658, 0x1234, 0x1e7c, 0x2a10, 0x06a0, + 0x3758, 0x1334, 0x1f7c, 0x2b10, 0x07a0, + 0x3858, 0x1434, 0x207c, 0x2c10, 0x08a0, + 0x385c, 0x1438, 0x2080, 0x2c14, 0x08a4, + 0x375c, 0x1338, 0x1f80, 0x2b14, 0x07a4, + 0x365c, 0x1238, 0x1e80, 0x2a14, 0x06a4, + 0x3660, 0x123c, 0x1e84, 0x2a18, 0x06a8, + 0x3760, 0x133c, 0x1f84, 0x2b18, 0x07a8, + 0x3860, 0x143c, 0x2084, 0x2c18, 0x08a8, + 0x3864, 0x1440, 0x2088, 0x2c1c, 0x08ac, + 0x3764, 0x1340, 0x1f88, 0x2b1c, 0x07ac, + 0x3664, 0x1240, 0x1e88, 0x2a1c, 0x06ac, + 0x3668, 0x1244, 0x1e8c, 0x2a20, 0x06b0, + 0x3768, 0x1344, 0x1f8c, 0x2b20, 0x07b0, + 0x3868, 0x1444, 0x208c, 0x2c20, 0x08b0, + 0x0048, 0x1824, 0x246c, 0x3000, 0x0c90, + 0x0148, 0x1924, 0x256c, 0x3100, 0x0d90, + 0x0248, 0x1a24, 0x266c, 0x3200, 0x0e90, + 0x024c, 0x1a28, 0x2670, 0x3204, 0x0e94, + 0x014c, 0x1928, 0x2570, 0x3104, 0x0d94, + 0x004c, 0x1828, 0x2470, 0x3004, 0x0c94, + 0x0050, 0x182c, 0x2474, 0x3008, 0x0c98, + 0x0150, 0x192c, 0x2574, 0x3108, 0x0d98, + 0x0250, 0x1a2c, 0x2674, 0x3208, 0x0e98, + 0x0254, 0x1a30, 0x2678, 0x320c, 0x0e9c, + 0x0154, 0x1930, 0x2578, 0x310c, 0x0d9c, + 0x0054, 0x1830, 0x2478, 0x300c, 0x0c9c, + 0x0058, 0x1834, 0x247c, 0x3010, 0x0ca0, + 0x0158, 0x1934, 0x257c, 0x3110, 0x0da0, + 0x0258, 0x1a34, 0x267c, 0x3210, 0x0ea0, + 0x025c, 0x1a38, 0x2680, 0x3214, 0x0ea4, + 0x015c, 0x1938, 0x2580, 0x3114, 0x0da4, + 0x005c, 0x1838, 0x2480, 0x3014, 0x0ca4, + 0x0060, 0x183c, 0x2484, 0x3018, 0x0ca8, + 0x0160, 0x193c, 0x2584, 0x3118, 0x0da8, + 0x0260, 0x1a3c, 0x2684, 0x3218, 0x0ea8, + 0x0264, 0x1a40, 0x2688, 0x321c, 0x0eac, + 0x0164, 0x1940, 0x2588, 0x311c, 0x0dac, + 0x0064, 0x1840, 0x2488, 0x301c, 0x0cac, + 0x0068, 0x1844, 0x248c, 0x3020, 0x0cb0, + 0x0168, 0x1944, 0x258c, 0x3120, 0x0db0, + 0x0268, 0x1a44, 0x268c, 0x3220, 0x0eb0, + 0x0648, 0x1e24, 0x2a6c, 0x3600, 0x1290, + 0x0748, 0x1f24, 0x2b6c, 0x3700, 0x1390, + 0x0848, 0x2024, 0x2c6c, 0x3800, 0x1490, + 0x084c, 0x2028, 0x2c70, 0x3804, 0x1494, + 0x074c, 0x1f28, 0x2b70, 0x3704, 0x1394, + 0x064c, 0x1e28, 0x2a70, 0x3604, 0x1294, + 0x0650, 0x1e2c, 0x2a74, 0x3608, 0x1298, + 0x0750, 0x1f2c, 0x2b74, 0x3708, 0x1398, + 0x0850, 0x202c, 0x2c74, 0x3808, 0x1498, + 0x0854, 0x2030, 0x2c78, 0x380c, 0x149c, + 0x0754, 0x1f30, 0x2b78, 0x370c, 0x139c, + 0x0654, 0x1e30, 0x2a78, 0x360c, 0x129c, + 0x0658, 0x1e34, 0x2a7c, 0x3610, 0x12a0, + 0x0758, 0x1f34, 0x2b7c, 0x3710, 0x13a0, + 0x0858, 0x2034, 0x2c7c, 0x3810, 0x14a0, + 0x085c, 0x2038, 0x2c80, 0x3814, 0x14a4, + 0x075c, 0x1f38, 0x2b80, 0x3714, 0x13a4, + 0x065c, 0x1e38, 0x2a80, 0x3614, 0x12a4, + 0x0660, 0x1e3c, 0x2a84, 0x3618, 0x12a8, + 0x0760, 0x1f3c, 0x2b84, 0x3718, 0x13a8, + 0x0860, 0x203c, 0x2c84, 0x3818, 0x14a8, + 0x0864, 0x2040, 0x2c88, 0x381c, 0x14ac, + 0x0764, 0x1f40, 0x2b88, 0x371c, 0x13ac, + 0x0664, 0x1e40, 0x2a88, 0x361c, 0x12ac, + 0x0668, 0x1e44, 0x2a8c, 0x3620, 0x12b0, + 0x0768, 0x1f44, 0x2b8c, 0x3720, 0x13b0, + 0x0868, 0x2044, 0x2c8c, 0x3820, 0x14b0, + 0x0f48, 0x2724, 0x336c, 0x0300, 0x1b90, + 0x1048, 0x2824, 0x346c, 0x0400, 0x1c90, + 0x1148, 0x2924, 0x356c, 0x0500, 0x1d90, + 0x114c, 0x2928, 0x3570, 0x0504, 0x1d94, + 0x104c, 0x2828, 0x3470, 0x0404, 0x1c94, + 0x0f4c, 0x2728, 0x3370, 0x0304, 0x1b94, + 0x0f50, 0x272c, 0x3374, 0x0308, 0x1b98, + 0x1050, 0x282c, 0x3474, 0x0408, 0x1c98, + 0x1150, 0x292c, 0x3574, 0x0508, 0x1d98, + 0x1154, 0x2930, 0x3578, 0x050c, 0x1d9c, + 0x1054, 0x2830, 0x3478, 0x040c, 0x1c9c, + 0x0f54, 0x2730, 0x3378, 0x030c, 0x1b9c, + 0x0f58, 0x2734, 0x337c, 0x0310, 0x1ba0, + 0x1058, 0x2834, 0x347c, 0x0410, 0x1ca0, + 0x1158, 0x2934, 0x357c, 0x0510, 0x1da0, + 0x115c, 0x2938, 0x3580, 0x0514, 0x1da4, + 0x105c, 0x2838, 0x3480, 0x0414, 0x1ca4, + 0x0f5c, 0x2738, 0x3380, 0x0314, 0x1ba4, + 0x0f60, 0x273c, 0x3384, 0x0318, 0x1ba8, + 0x1060, 0x283c, 0x3484, 0x0418, 0x1ca8, + 0x1160, 0x293c, 0x3584, 0x0518, 0x1da8, + 0x1164, 0x2940, 0x3588, 0x051c, 0x1dac, + 0x1064, 0x2840, 0x3488, 0x041c, 0x1cac, + 0x0f64, 0x2740, 0x3388, 0x031c, 0x1bac, + 0x0f68, 0x2744, 0x338c, 0x0320, 0x1bb0, + 0x1068, 0x2844, 0x348c, 0x0420, 0x1cb0, + 0x1168, 0x2944, 0x358c, 0x0520, 0x1db0, + 0x1548, 0x2d24, 0x396c, 0x0900, 0x2190, + 0x1648, 0x2e24, 0x3a6c, 0x0a00, 0x2290, + 0x1748, 0x2f24, 0x3b6c, 0x0b00, 0x2390, + 0x174c, 0x2f28, 0x3b70, 0x0b04, 0x2394, + 0x164c, 0x2e28, 0x3a70, 0x0a04, 0x2294, + 0x154c, 0x2d28, 0x3970, 0x0904, 0x2194, + 0x1550, 0x2d2c, 0x3974, 0x0908, 0x2198, + 0x1650, 0x2e2c, 0x3a74, 0x0a08, 0x2298, + 0x1750, 0x2f2c, 0x3b74, 0x0b08, 0x2398, + 0x1754, 0x2f30, 0x3b78, 0x0b0c, 0x239c, + 0x1654, 0x2e30, 0x3a78, 0x0a0c, 0x229c, + 0x1554, 0x2d30, 0x3978, 0x090c, 0x219c, + 0x1558, 0x2d34, 0x397c, 0x0910, 0x21a0, + 0x1658, 0x2e34, 0x3a7c, 0x0a10, 0x22a0, + 0x1758, 0x2f34, 0x3b7c, 0x0b10, 0x23a0, + 0x175c, 0x2f38, 0x3b80, 0x0b14, 0x23a4, + 0x165c, 0x2e38, 0x3a80, 0x0a14, 0x22a4, + 0x155c, 0x2d38, 0x3980, 0x0914, 0x21a4, + 0x1560, 0x2d3c, 0x3984, 0x0918, 0x21a8, + 0x1660, 0x2e3c, 0x3a84, 0x0a18, 0x22a8, + 0x1760, 0x2f3c, 0x3b84, 0x0b18, 0x23a8, + 0x1764, 0x2f40, 0x3b88, 0x0b1c, 0x23ac, + 0x1664, 0x2e40, 0x3a88, 0x0a1c, 0x22ac, + 0x1564, 0x2d40, 0x3988, 0x091c, 0x21ac, + 0x1568, 0x2d44, 0x398c, 0x0920, 0x21b0, + 0x1668, 0x2e44, 0x3a8c, 0x0a20, 0x22b0, + 0x1768, 0x2f44, 0x3b8c, 0x0b20, 0x23b0, + 0x1b48, 0x3324, 0x036c, 0x0f00, 0x2790, + 0x1c48, 0x3424, 0x046c, 0x1000, 0x2890, + 0x1d48, 0x3524, 0x056c, 0x1100, 0x2990, + 0x1d4c, 0x3528, 0x0570, 0x1104, 0x2994, + 0x1c4c, 0x3428, 0x0470, 0x1004, 0x2894, + 0x1b4c, 0x3328, 0x0370, 0x0f04, 0x2794, + 0x1b50, 0x332c, 0x0374, 0x0f08, 0x2798, + 0x1c50, 0x342c, 0x0474, 0x1008, 0x2898, + 0x1d50, 0x352c, 0x0574, 0x1108, 0x2998, + 0x1d54, 0x3530, 0x0578, 0x110c, 0x299c, + 0x1c54, 0x3430, 0x0478, 0x100c, 0x289c, + 0x1b54, 0x3330, 0x0378, 0x0f0c, 0x279c, + 0x1b58, 0x3334, 0x037c, 0x0f10, 0x27a0, + 0x1c58, 0x3434, 0x047c, 0x1010, 0x28a0, + 0x1d58, 0x3534, 0x057c, 0x1110, 0x29a0, + 0x1d5c, 0x3538, 0x0580, 0x1114, 0x29a4, + 0x1c5c, 0x3438, 0x0480, 0x1014, 0x28a4, + 0x1b5c, 0x3338, 0x0380, 0x0f14, 0x27a4, + 0x1b60, 0x333c, 0x0384, 0x0f18, 0x27a8, + 0x1c60, 0x343c, 0x0484, 0x1018, 0x28a8, + 0x1d60, 0x353c, 0x0584, 0x1118, 0x29a8, + 0x1d64, 0x3540, 0x0588, 0x111c, 0x29ac, + 0x1c64, 0x3440, 0x0488, 0x101c, 0x28ac, + 0x1b64, 0x3340, 0x0388, 0x0f1c, 0x27ac, + 0x1b68, 0x3344, 0x038c, 0x0f20, 0x27b0, + 0x1c68, 0x3444, 0x048c, 0x1020, 0x28b0, + 0x1d68, 0x3544, 0x058c, 0x1120, 0x29b0, + 0x2148, 0x3924, 0x096c, 0x1500, 0x2d90, + 0x2248, 0x3a24, 0x0a6c, 0x1600, 0x2e90, + 0x2348, 0x3b24, 0x0b6c, 0x1700, 0x2f90, + 0x234c, 0x3b28, 0x0b70, 0x1704, 0x2f94, + 0x224c, 0x3a28, 0x0a70, 0x1604, 0x2e94, + 0x214c, 0x3928, 0x0970, 0x1504, 0x2d94, + 0x2150, 0x392c, 0x0974, 0x1508, 0x2d98, + 0x2250, 0x3a2c, 0x0a74, 0x1608, 0x2e98, + 0x2350, 0x3b2c, 0x0b74, 0x1708, 0x2f98, + 0x2354, 0x3b30, 0x0b78, 0x170c, 0x2f9c, + 0x2254, 0x3a30, 0x0a78, 0x160c, 0x2e9c, + 0x2154, 0x3930, 0x0978, 0x150c, 0x2d9c, + 0x2158, 0x3934, 0x097c, 0x1510, 0x2da0, + 0x2258, 0x3a34, 0x0a7c, 0x1610, 0x2ea0, + 0x2358, 0x3b34, 0x0b7c, 0x1710, 0x2fa0, + 0x235c, 0x3b38, 0x0b80, 0x1714, 0x2fa4, + 0x225c, 0x3a38, 0x0a80, 0x1614, 0x2ea4, + 0x215c, 0x3938, 0x0980, 0x1514, 0x2da4, + 0x2160, 0x393c, 0x0984, 0x1518, 0x2da8, + 0x2260, 0x3a3c, 0x0a84, 0x1618, 0x2ea8, + 0x2360, 0x3b3c, 0x0b84, 0x1718, 0x2fa8, + 0x2364, 0x3b40, 0x0b88, 0x171c, 0x2fac, + 0x2264, 0x3a40, 0x0a88, 0x161c, 0x2eac, + 0x2164, 0x3940, 0x0988, 0x151c, 0x2dac, + 0x2168, 0x3944, 0x098c, 0x1520, 0x2db0, + 0x2268, 0x3a44, 0x0a8c, 0x1620, 0x2eb0, + 0x2368, 0x3b44, 0x0b8c, 0x1720, 0x2fb0, + 0x2748, 0x0324, 0x0f6c, 0x1b00, 0x3390, + 0x2848, 0x0424, 0x106c, 0x1c00, 0x3490, + 0x2948, 0x0524, 0x116c, 0x1d00, 0x3590, + 0x294c, 0x0528, 0x1170, 0x1d04, 0x3594, + 0x284c, 0x0428, 0x1070, 0x1c04, 0x3494, + 0x274c, 0x0328, 0x0f70, 0x1b04, 0x3394, + 0x2750, 0x032c, 0x0f74, 0x1b08, 0x3398, + 0x2850, 0x042c, 0x1074, 0x1c08, 0x3498, + 0x2950, 0x052c, 0x1174, 0x1d08, 0x3598, + 0x2954, 0x0530, 0x1178, 0x1d0c, 0x359c, + 0x2854, 0x0430, 0x1078, 0x1c0c, 0x349c, + 0x2754, 0x0330, 0x0f78, 0x1b0c, 0x339c, + 0x2758, 0x0334, 0x0f7c, 0x1b10, 0x33a0, + 0x2858, 0x0434, 0x107c, 0x1c10, 0x34a0, + 0x2958, 0x0534, 0x117c, 0x1d10, 0x35a0, + 0x295c, 0x0538, 0x1180, 0x1d14, 0x35a4, + 0x285c, 0x0438, 0x1080, 0x1c14, 0x34a4, + 0x275c, 0x0338, 0x0f80, 0x1b14, 0x33a4, + 0x2760, 0x033c, 0x0f84, 0x1b18, 0x33a8, + 0x2860, 0x043c, 0x1084, 0x1c18, 0x34a8, + 0x2960, 0x053c, 0x1184, 0x1d18, 0x35a8, + 0x2964, 0x0540, 0x1188, 0x1d1c, 0x35ac, + 0x2864, 0x0440, 0x1088, 0x1c1c, 0x34ac, + 0x2764, 0x0340, 0x0f88, 0x1b1c, 0x33ac, + 0x2768, 0x0344, 0x0f8c, 0x1b20, 0x33b0, + 0x2868, 0x0444, 0x108c, 0x1c20, 0x34b0, + 0x2968, 0x0544, 0x118c, 0x1d20, 0x35b0, + 0x2d48, 0x0924, 0x156c, 0x2100, 0x3990, + 0x2e48, 0x0a24, 0x166c, 0x2200, 0x3a90, + 0x2f48, 0x0b24, 0x176c, 0x2300, 0x3b90, + 0x2f4c, 0x0b28, 0x1770, 0x2304, 0x3b94, + 0x2e4c, 0x0a28, 0x1670, 0x2204, 0x3a94, + 0x2d4c, 0x0928, 0x1570, 0x2104, 0x3994, + 0x2d50, 0x092c, 0x1574, 0x2108, 0x3998, + 0x2e50, 0x0a2c, 0x1674, 0x2208, 0x3a98, + 0x2f50, 0x0b2c, 0x1774, 0x2308, 0x3b98, + 0x2f54, 0x0b30, 0x1778, 0x230c, 0x3b9c, + 0x2e54, 0x0a30, 0x1678, 0x220c, 0x3a9c, + 0x2d54, 0x0930, 0x1578, 0x210c, 0x399c, + 0x2d58, 0x0934, 0x157c, 0x2110, 0x39a0, + 0x2e58, 0x0a34, 0x167c, 0x2210, 0x3aa0, + 0x2f58, 0x0b34, 0x177c, 0x2310, 0x3ba0, + 0x2f5c, 0x0b38, 0x1780, 0x2314, 0x3ba4, + 0x2e5c, 0x0a38, 0x1680, 0x2214, 0x3aa4, + 0x2d5c, 0x0938, 0x1580, 0x2114, 0x39a4, + 0x2d60, 0x093c, 0x1584, 0x2118, 0x39a8, + 0x2e60, 0x0a3c, 0x1684, 0x2218, 0x3aa8, + 0x2f60, 0x0b3c, 0x1784, 0x2318, 0x3ba8, + 0x2f64, 0x0b40, 0x1788, 0x231c, 0x3bac, + 0x2e64, 0x0a40, 0x1688, 0x221c, 0x3aac, + 0x2d64, 0x0940, 0x1588, 0x211c, 0x39ac, + 0x2d68, 0x0944, 0x158c, 0x2120, 0x39b0, + 0x2e68, 0x0a44, 0x168c, 0x2220, 0x3ab0, + 0x2f68, 0x0b44, 0x178c, 0x2320, 0x3bb0, + 0x3348, 0x0f24, 0x1b6c, 0x2700, 0x0390, + 0x3448, 0x1024, 0x1c6c, 0x2800, 0x0490, + 0x3548, 0x1124, 0x1d6c, 0x2900, 0x0590, + 0x354c, 0x1128, 0x1d70, 0x2904, 0x0594, + 0x344c, 0x1028, 0x1c70, 0x2804, 0x0494, + 0x334c, 0x0f28, 0x1b70, 0x2704, 0x0394, + 0x3350, 0x0f2c, 0x1b74, 0x2708, 0x0398, + 0x3450, 0x102c, 0x1c74, 0x2808, 0x0498, + 0x3550, 0x112c, 0x1d74, 0x2908, 0x0598, + 0x3554, 0x1130, 0x1d78, 0x290c, 0x059c, + 0x3454, 0x1030, 0x1c78, 0x280c, 0x049c, + 0x3354, 0x0f30, 0x1b78, 0x270c, 0x039c, + 0x3358, 0x0f34, 0x1b7c, 0x2710, 0x03a0, + 0x3458, 0x1034, 0x1c7c, 0x2810, 0x04a0, + 0x3558, 0x1134, 0x1d7c, 0x2910, 0x05a0, + 0x355c, 0x1138, 0x1d80, 0x2914, 0x05a4, + 0x345c, 0x1038, 0x1c80, 0x2814, 0x04a4, + 0x335c, 0x0f38, 0x1b80, 0x2714, 0x03a4, + 0x3360, 0x0f3c, 0x1b84, 0x2718, 0x03a8, + 0x3460, 0x103c, 0x1c84, 0x2818, 0x04a8, + 0x3560, 0x113c, 0x1d84, 0x2918, 0x05a8, + 0x3564, 0x1140, 0x1d88, 0x291c, 0x05ac, + 0x3464, 0x1040, 0x1c88, 0x281c, 0x04ac, + 0x3364, 0x0f40, 0x1b88, 0x271c, 0x03ac, + 0x3368, 0x0f44, 0x1b8c, 0x2720, 0x03b0, + 0x3468, 0x1044, 0x1c8c, 0x2820, 0x04b0, + 0x3568, 0x1144, 0x1d8c, 0x2920, 0x05b0, + 0x3948, 0x1524, 0x216c, 0x2d00, 0x0990, + 0x3a48, 0x1624, 0x226c, 0x2e00, 0x0a90, + 0x3b48, 0x1724, 0x236c, 0x2f00, 0x0b90, + 0x3b4c, 0x1728, 0x2370, 0x2f04, 0x0b94, + 0x3a4c, 0x1628, 0x2270, 0x2e04, 0x0a94, + 0x394c, 0x1528, 0x2170, 0x2d04, 0x0994, + 0x3950, 0x152c, 0x2174, 0x2d08, 0x0998, + 0x3a50, 0x162c, 0x2274, 0x2e08, 0x0a98, + 0x3b50, 0x172c, 0x2374, 0x2f08, 0x0b98, + 0x3b54, 0x1730, 0x2378, 0x2f0c, 0x0b9c, + 0x3a54, 0x1630, 0x2278, 0x2e0c, 0x0a9c, + 0x3954, 0x1530, 0x2178, 0x2d0c, 0x099c, + 0x3958, 0x1534, 0x217c, 0x2d10, 0x09a0, + 0x3a58, 0x1634, 0x227c, 0x2e10, 0x0aa0, + 0x3b58, 0x1734, 0x237c, 0x2f10, 0x0ba0, + 0x3b5c, 0x1738, 0x2380, 0x2f14, 0x0ba4, + 0x3a5c, 0x1638, 0x2280, 0x2e14, 0x0aa4, + 0x395c, 0x1538, 0x2180, 0x2d14, 0x09a4, + 0x3960, 0x153c, 0x2184, 0x2d18, 0x09a8, + 0x3a60, 0x163c, 0x2284, 0x2e18, 0x0aa8, + 0x3b60, 0x173c, 0x2384, 0x2f18, 0x0ba8, + 0x3b64, 0x1740, 0x2388, 0x2f1c, 0x0bac, + 0x3a64, 0x1640, 0x2288, 0x2e1c, 0x0aac, + 0x3964, 0x1540, 0x2188, 0x2d1c, 0x09ac, + 0x3968, 0x1544, 0x218c, 0x2d20, 0x09b0, + 0x3a68, 0x1644, 0x228c, 0x2e20, 0x0ab0, + 0x3b68, 0x1744, 0x238c, 0x2f20, 0x0bb0, + 0x0348, 0x1b24, 0x276c, 0x3300, 0x0f90, + 0x0448, 0x1c24, 0x286c, 0x3400, 0x1090, + 0x0548, 0x1d24, 0x296c, 0x3500, 0x1190, + 0x054c, 0x1d28, 0x2970, 0x3504, 0x1194, + 0x044c, 0x1c28, 0x2870, 0x3404, 0x1094, + 0x034c, 0x1b28, 0x2770, 0x3304, 0x0f94, + 0x0350, 0x1b2c, 0x2774, 0x3308, 0x0f98, + 0x0450, 0x1c2c, 0x2874, 0x3408, 0x1098, + 0x0550, 0x1d2c, 0x2974, 0x3508, 0x1198, + 0x0554, 0x1d30, 0x2978, 0x350c, 0x119c, + 0x0454, 0x1c30, 0x2878, 0x340c, 0x109c, + 0x0354, 0x1b30, 0x2778, 0x330c, 0x0f9c, + 0x0358, 0x1b34, 0x277c, 0x3310, 0x0fa0, + 0x0458, 0x1c34, 0x287c, 0x3410, 0x10a0, + 0x0558, 0x1d34, 0x297c, 0x3510, 0x11a0, + 0x055c, 0x1d38, 0x2980, 0x3514, 0x11a4, + 0x045c, 0x1c38, 0x2880, 0x3414, 0x10a4, + 0x035c, 0x1b38, 0x2780, 0x3314, 0x0fa4, + 0x0360, 0x1b3c, 0x2784, 0x3318, 0x0fa8, + 0x0460, 0x1c3c, 0x2884, 0x3418, 0x10a8, + 0x0560, 0x1d3c, 0x2984, 0x3518, 0x11a8, + 0x0564, 0x1d40, 0x2988, 0x351c, 0x11ac, + 0x0464, 0x1c40, 0x2888, 0x341c, 0x10ac, + 0x0364, 0x1b40, 0x2788, 0x331c, 0x0fac, + 0x0368, 0x1b44, 0x278c, 0x3320, 0x0fb0, + 0x0468, 0x1c44, 0x288c, 0x3420, 0x10b0, + 0x0568, 0x1d44, 0x298c, 0x3520, 0x11b0, + 0x0948, 0x2124, 0x2d6c, 0x3900, 0x1590, + 0x0a48, 0x2224, 0x2e6c, 0x3a00, 0x1690, + 0x0b48, 0x2324, 0x2f6c, 0x3b00, 0x1790, + 0x0b4c, 0x2328, 0x2f70, 0x3b04, 0x1794, + 0x0a4c, 0x2228, 0x2e70, 0x3a04, 0x1694, + 0x094c, 0x2128, 0x2d70, 0x3904, 0x1594, + 0x0950, 0x212c, 0x2d74, 0x3908, 0x1598, + 0x0a50, 0x222c, 0x2e74, 0x3a08, 0x1698, + 0x0b50, 0x232c, 0x2f74, 0x3b08, 0x1798, + 0x0b54, 0x2330, 0x2f78, 0x3b0c, 0x179c, + 0x0a54, 0x2230, 0x2e78, 0x3a0c, 0x169c, + 0x0954, 0x2130, 0x2d78, 0x390c, 0x159c, + 0x0958, 0x2134, 0x2d7c, 0x3910, 0x15a0, + 0x0a58, 0x2234, 0x2e7c, 0x3a10, 0x16a0, + 0x0b58, 0x2334, 0x2f7c, 0x3b10, 0x17a0, + 0x0b5c, 0x2338, 0x2f80, 0x3b14, 0x17a4, + 0x0a5c, 0x2238, 0x2e80, 0x3a14, 0x16a4, + 0x095c, 0x2138, 0x2d80, 0x3914, 0x15a4, + 0x0960, 0x213c, 0x2d84, 0x3918, 0x15a8, + 0x0a60, 0x223c, 0x2e84, 0x3a18, 0x16a8, + 0x0b60, 0x233c, 0x2f84, 0x3b18, 0x17a8, + 0x0b64, 0x2340, 0x2f88, 0x3b1c, 0x17ac, + 0x0a64, 0x2240, 0x2e88, 0x3a1c, 0x16ac, + 0x0964, 0x2140, 0x2d88, 0x391c, 0x15ac, + 0x0968, 0x2144, 0x2d8c, 0x3920, 0x15b0, + 0x0a68, 0x2244, 0x2e8c, 0x3a20, 0x16b0, + 0x0b68, 0x2344, 0x2f8c, 0x3b20, 0x17b0, +}; + +/* 2 channels per frame, 12 DIF sequences per channel, + 27 video segments per DIF sequence, 5 macroblocks per video segment */ +static const uint16_t dv_place_422_625[2*12*27*5] = { + 0x0c48, 0x2424, 0x306c, 0x0000, 0x1890, + 0x0d48, 0x2524, 0x316c, 0x0100, 0x1990, + 0x0e48, 0x2624, 0x326c, 0x0200, 0x1a90, + 0x0e4c, 0x2628, 0x3270, 0x0204, 0x1a94, + 0x0d4c, 0x2528, 0x3170, 0x0104, 0x1994, + 0x0c4c, 0x2428, 0x3070, 0x0004, 0x1894, + 0x0c50, 0x242c, 0x3074, 0x0008, 0x1898, + 0x0d50, 0x252c, 0x3174, 0x0108, 0x1998, + 0x0e50, 0x262c, 0x3274, 0x0208, 0x1a98, + 0x0e54, 0x2630, 0x3278, 0x020c, 0x1a9c, + 0x0d54, 0x2530, 0x3178, 0x010c, 0x199c, + 0x0c54, 0x2430, 0x3078, 0x000c, 0x189c, + 0x0c58, 0x2434, 0x307c, 0x0010, 0x18a0, + 0x0d58, 0x2534, 0x317c, 0x0110, 0x19a0, + 0x0e58, 0x2634, 0x327c, 0x0210, 0x1aa0, + 0x0e5c, 0x2638, 0x3280, 0x0214, 0x1aa4, + 0x0d5c, 0x2538, 0x3180, 0x0114, 0x19a4, + 0x0c5c, 0x2438, 0x3080, 0x0014, 0x18a4, + 0x0c60, 0x243c, 0x3084, 0x0018, 0x18a8, + 0x0d60, 0x253c, 0x3184, 0x0118, 0x19a8, + 0x0e60, 0x263c, 0x3284, 0x0218, 0x1aa8, + 0x0e64, 0x2640, 0x3288, 0x021c, 0x1aac, + 0x0d64, 0x2540, 0x3188, 0x011c, 0x19ac, + 0x0c64, 0x2440, 0x3088, 0x001c, 0x18ac, + 0x0c68, 0x2444, 0x308c, 0x0020, 0x18b0, + 0x0d68, 0x2544, 0x318c, 0x0120, 0x19b0, + 0x0e68, 0x2644, 0x328c, 0x0220, 0x1ab0, + 0x1248, 0x2a24, 0x366c, 0x0600, 0x1e90, + 0x1348, 0x2b24, 0x376c, 0x0700, 0x1f90, + 0x1448, 0x2c24, 0x386c, 0x0800, 0x2090, + 0x144c, 0x2c28, 0x3870, 0x0804, 0x2094, + 0x134c, 0x2b28, 0x3770, 0x0704, 0x1f94, + 0x124c, 0x2a28, 0x3670, 0x0604, 0x1e94, + 0x1250, 0x2a2c, 0x3674, 0x0608, 0x1e98, + 0x1350, 0x2b2c, 0x3774, 0x0708, 0x1f98, + 0x1450, 0x2c2c, 0x3874, 0x0808, 0x2098, + 0x1454, 0x2c30, 0x3878, 0x080c, 0x209c, + 0x1354, 0x2b30, 0x3778, 0x070c, 0x1f9c, + 0x1254, 0x2a30, 0x3678, 0x060c, 0x1e9c, + 0x1258, 0x2a34, 0x367c, 0x0610, 0x1ea0, + 0x1358, 0x2b34, 0x377c, 0x0710, 0x1fa0, + 0x1458, 0x2c34, 0x387c, 0x0810, 0x20a0, + 0x145c, 0x2c38, 0x3880, 0x0814, 0x20a4, + 0x135c, 0x2b38, 0x3780, 0x0714, 0x1fa4, + 0x125c, 0x2a38, 0x3680, 0x0614, 0x1ea4, + 0x1260, 0x2a3c, 0x3684, 0x0618, 0x1ea8, + 0x1360, 0x2b3c, 0x3784, 0x0718, 0x1fa8, + 0x1460, 0x2c3c, 0x3884, 0x0818, 0x20a8, + 0x1464, 0x2c40, 0x3888, 0x081c, 0x20ac, + 0x1364, 0x2b40, 0x3788, 0x071c, 0x1fac, + 0x1264, 0x2a40, 0x3688, 0x061c, 0x1eac, + 0x1268, 0x2a44, 0x368c, 0x0620, 0x1eb0, + 0x1368, 0x2b44, 0x378c, 0x0720, 0x1fb0, + 0x1468, 0x2c44, 0x388c, 0x0820, 0x20b0, + 0x1848, 0x3024, 0x3c6c, 0x0c00, 0x2490, + 0x1948, 0x3124, 0x3d6c, 0x0d00, 0x2590, + 0x1a48, 0x3224, 0x3e6c, 0x0e00, 0x2690, + 0x1a4c, 0x3228, 0x3e70, 0x0e04, 0x2694, + 0x194c, 0x3128, 0x3d70, 0x0d04, 0x2594, + 0x184c, 0x3028, 0x3c70, 0x0c04, 0x2494, + 0x1850, 0x302c, 0x3c74, 0x0c08, 0x2498, + 0x1950, 0x312c, 0x3d74, 0x0d08, 0x2598, + 0x1a50, 0x322c, 0x3e74, 0x0e08, 0x2698, + 0x1a54, 0x3230, 0x3e78, 0x0e0c, 0x269c, + 0x1954, 0x3130, 0x3d78, 0x0d0c, 0x259c, + 0x1854, 0x3030, 0x3c78, 0x0c0c, 0x249c, + 0x1858, 0x3034, 0x3c7c, 0x0c10, 0x24a0, + 0x1958, 0x3134, 0x3d7c, 0x0d10, 0x25a0, + 0x1a58, 0x3234, 0x3e7c, 0x0e10, 0x26a0, + 0x1a5c, 0x3238, 0x3e80, 0x0e14, 0x26a4, + 0x195c, 0x3138, 0x3d80, 0x0d14, 0x25a4, + 0x185c, 0x3038, 0x3c80, 0x0c14, 0x24a4, + 0x1860, 0x303c, 0x3c84, 0x0c18, 0x24a8, + 0x1960, 0x313c, 0x3d84, 0x0d18, 0x25a8, + 0x1a60, 0x323c, 0x3e84, 0x0e18, 0x26a8, + 0x1a64, 0x3240, 0x3e88, 0x0e1c, 0x26ac, + 0x1964, 0x3140, 0x3d88, 0x0d1c, 0x25ac, + 0x1864, 0x3040, 0x3c88, 0x0c1c, 0x24ac, + 0x1868, 0x3044, 0x3c8c, 0x0c20, 0x24b0, + 0x1968, 0x3144, 0x3d8c, 0x0d20, 0x25b0, + 0x1a68, 0x3244, 0x3e8c, 0x0e20, 0x26b0, + 0x1e48, 0x3624, 0x426c, 0x1200, 0x2a90, + 0x1f48, 0x3724, 0x436c, 0x1300, 0x2b90, + 0x2048, 0x3824, 0x446c, 0x1400, 0x2c90, + 0x204c, 0x3828, 0x4470, 0x1404, 0x2c94, + 0x1f4c, 0x3728, 0x4370, 0x1304, 0x2b94, + 0x1e4c, 0x3628, 0x4270, 0x1204, 0x2a94, + 0x1e50, 0x362c, 0x4274, 0x1208, 0x2a98, + 0x1f50, 0x372c, 0x4374, 0x1308, 0x2b98, + 0x2050, 0x382c, 0x4474, 0x1408, 0x2c98, + 0x2054, 0x3830, 0x4478, 0x140c, 0x2c9c, + 0x1f54, 0x3730, 0x4378, 0x130c, 0x2b9c, + 0x1e54, 0x3630, 0x4278, 0x120c, 0x2a9c, + 0x1e58, 0x3634, 0x427c, 0x1210, 0x2aa0, + 0x1f58, 0x3734, 0x437c, 0x1310, 0x2ba0, + 0x2058, 0x3834, 0x447c, 0x1410, 0x2ca0, + 0x205c, 0x3838, 0x4480, 0x1414, 0x2ca4, + 0x1f5c, 0x3738, 0x4380, 0x1314, 0x2ba4, + 0x1e5c, 0x3638, 0x4280, 0x1214, 0x2aa4, + 0x1e60, 0x363c, 0x4284, 0x1218, 0x2aa8, + 0x1f60, 0x373c, 0x4384, 0x1318, 0x2ba8, + 0x2060, 0x383c, 0x4484, 0x1418, 0x2ca8, + 0x2064, 0x3840, 0x4488, 0x141c, 0x2cac, + 0x1f64, 0x3740, 0x4388, 0x131c, 0x2bac, + 0x1e64, 0x3640, 0x4288, 0x121c, 0x2aac, + 0x1e68, 0x3644, 0x428c, 0x1220, 0x2ab0, + 0x1f68, 0x3744, 0x438c, 0x1320, 0x2bb0, + 0x2068, 0x3844, 0x448c, 0x1420, 0x2cb0, + 0x2448, 0x3c24, 0x006c, 0x1800, 0x3090, + 0x2548, 0x3d24, 0x016c, 0x1900, 0x3190, + 0x2648, 0x3e24, 0x026c, 0x1a00, 0x3290, + 0x264c, 0x3e28, 0x0270, 0x1a04, 0x3294, + 0x254c, 0x3d28, 0x0170, 0x1904, 0x3194, + 0x244c, 0x3c28, 0x0070, 0x1804, 0x3094, + 0x2450, 0x3c2c, 0x0074, 0x1808, 0x3098, + 0x2550, 0x3d2c, 0x0174, 0x1908, 0x3198, + 0x2650, 0x3e2c, 0x0274, 0x1a08, 0x3298, + 0x2654, 0x3e30, 0x0278, 0x1a0c, 0x329c, + 0x2554, 0x3d30, 0x0178, 0x190c, 0x319c, + 0x2454, 0x3c30, 0x0078, 0x180c, 0x309c, + 0x2458, 0x3c34, 0x007c, 0x1810, 0x30a0, + 0x2558, 0x3d34, 0x017c, 0x1910, 0x31a0, + 0x2658, 0x3e34, 0x027c, 0x1a10, 0x32a0, + 0x265c, 0x3e38, 0x0280, 0x1a14, 0x32a4, + 0x255c, 0x3d38, 0x0180, 0x1914, 0x31a4, + 0x245c, 0x3c38, 0x0080, 0x1814, 0x30a4, + 0x2460, 0x3c3c, 0x0084, 0x1818, 0x30a8, + 0x2560, 0x3d3c, 0x0184, 0x1918, 0x31a8, + 0x2660, 0x3e3c, 0x0284, 0x1a18, 0x32a8, + 0x2664, 0x3e40, 0x0288, 0x1a1c, 0x32ac, + 0x2564, 0x3d40, 0x0188, 0x191c, 0x31ac, + 0x2464, 0x3c40, 0x0088, 0x181c, 0x30ac, + 0x2468, 0x3c44, 0x008c, 0x1820, 0x30b0, + 0x2568, 0x3d44, 0x018c, 0x1920, 0x31b0, + 0x2668, 0x3e44, 0x028c, 0x1a20, 0x32b0, + 0x2a48, 0x4224, 0x066c, 0x1e00, 0x3690, + 0x2b48, 0x4324, 0x076c, 0x1f00, 0x3790, + 0x2c48, 0x4424, 0x086c, 0x2000, 0x3890, + 0x2c4c, 0x4428, 0x0870, 0x2004, 0x3894, + 0x2b4c, 0x4328, 0x0770, 0x1f04, 0x3794, + 0x2a4c, 0x4228, 0x0670, 0x1e04, 0x3694, + 0x2a50, 0x422c, 0x0674, 0x1e08, 0x3698, + 0x2b50, 0x432c, 0x0774, 0x1f08, 0x3798, + 0x2c50, 0x442c, 0x0874, 0x2008, 0x3898, + 0x2c54, 0x4430, 0x0878, 0x200c, 0x389c, + 0x2b54, 0x4330, 0x0778, 0x1f0c, 0x379c, + 0x2a54, 0x4230, 0x0678, 0x1e0c, 0x369c, + 0x2a58, 0x4234, 0x067c, 0x1e10, 0x36a0, + 0x2b58, 0x4334, 0x077c, 0x1f10, 0x37a0, + 0x2c58, 0x4434, 0x087c, 0x2010, 0x38a0, + 0x2c5c, 0x4438, 0x0880, 0x2014, 0x38a4, + 0x2b5c, 0x4338, 0x0780, 0x1f14, 0x37a4, + 0x2a5c, 0x4238, 0x0680, 0x1e14, 0x36a4, + 0x2a60, 0x423c, 0x0684, 0x1e18, 0x36a8, + 0x2b60, 0x433c, 0x0784, 0x1f18, 0x37a8, + 0x2c60, 0x443c, 0x0884, 0x2018, 0x38a8, + 0x2c64, 0x4440, 0x0888, 0x201c, 0x38ac, + 0x2b64, 0x4340, 0x0788, 0x1f1c, 0x37ac, + 0x2a64, 0x4240, 0x0688, 0x1e1c, 0x36ac, + 0x2a68, 0x4244, 0x068c, 0x1e20, 0x36b0, + 0x2b68, 0x4344, 0x078c, 0x1f20, 0x37b0, + 0x2c68, 0x4444, 0x088c, 0x2020, 0x38b0, + 0x3048, 0x0024, 0x0c6c, 0x2400, 0x3c90, + 0x3148, 0x0124, 0x0d6c, 0x2500, 0x3d90, + 0x3248, 0x0224, 0x0e6c, 0x2600, 0x3e90, + 0x324c, 0x0228, 0x0e70, 0x2604, 0x3e94, + 0x314c, 0x0128, 0x0d70, 0x2504, 0x3d94, + 0x304c, 0x0028, 0x0c70, 0x2404, 0x3c94, + 0x3050, 0x002c, 0x0c74, 0x2408, 0x3c98, + 0x3150, 0x012c, 0x0d74, 0x2508, 0x3d98, + 0x3250, 0x022c, 0x0e74, 0x2608, 0x3e98, + 0x3254, 0x0230, 0x0e78, 0x260c, 0x3e9c, + 0x3154, 0x0130, 0x0d78, 0x250c, 0x3d9c, + 0x3054, 0x0030, 0x0c78, 0x240c, 0x3c9c, + 0x3058, 0x0034, 0x0c7c, 0x2410, 0x3ca0, + 0x3158, 0x0134, 0x0d7c, 0x2510, 0x3da0, + 0x3258, 0x0234, 0x0e7c, 0x2610, 0x3ea0, + 0x325c, 0x0238, 0x0e80, 0x2614, 0x3ea4, + 0x315c, 0x0138, 0x0d80, 0x2514, 0x3da4, + 0x305c, 0x0038, 0x0c80, 0x2414, 0x3ca4, + 0x3060, 0x003c, 0x0c84, 0x2418, 0x3ca8, + 0x3160, 0x013c, 0x0d84, 0x2518, 0x3da8, + 0x3260, 0x023c, 0x0e84, 0x2618, 0x3ea8, + 0x3264, 0x0240, 0x0e88, 0x261c, 0x3eac, + 0x3164, 0x0140, 0x0d88, 0x251c, 0x3dac, + 0x3064, 0x0040, 0x0c88, 0x241c, 0x3cac, + 0x3068, 0x0044, 0x0c8c, 0x2420, 0x3cb0, + 0x3168, 0x0144, 0x0d8c, 0x2520, 0x3db0, + 0x3268, 0x0244, 0x0e8c, 0x2620, 0x3eb0, + 0x3648, 0x0624, 0x126c, 0x2a00, 0x4290, + 0x3748, 0x0724, 0x136c, 0x2b00, 0x4390, + 0x3848, 0x0824, 0x146c, 0x2c00, 0x4490, + 0x384c, 0x0828, 0x1470, 0x2c04, 0x4494, + 0x374c, 0x0728, 0x1370, 0x2b04, 0x4394, + 0x364c, 0x0628, 0x1270, 0x2a04, 0x4294, + 0x3650, 0x062c, 0x1274, 0x2a08, 0x4298, + 0x3750, 0x072c, 0x1374, 0x2b08, 0x4398, + 0x3850, 0x082c, 0x1474, 0x2c08, 0x4498, + 0x3854, 0x0830, 0x1478, 0x2c0c, 0x449c, + 0x3754, 0x0730, 0x1378, 0x2b0c, 0x439c, + 0x3654, 0x0630, 0x1278, 0x2a0c, 0x429c, + 0x3658, 0x0634, 0x127c, 0x2a10, 0x42a0, + 0x3758, 0x0734, 0x137c, 0x2b10, 0x43a0, + 0x3858, 0x0834, 0x147c, 0x2c10, 0x44a0, + 0x385c, 0x0838, 0x1480, 0x2c14, 0x44a4, + 0x375c, 0x0738, 0x1380, 0x2b14, 0x43a4, + 0x365c, 0x0638, 0x1280, 0x2a14, 0x42a4, + 0x3660, 0x063c, 0x1284, 0x2a18, 0x42a8, + 0x3760, 0x073c, 0x1384, 0x2b18, 0x43a8, + 0x3860, 0x083c, 0x1484, 0x2c18, 0x44a8, + 0x3864, 0x0840, 0x1488, 0x2c1c, 0x44ac, + 0x3764, 0x0740, 0x1388, 0x2b1c, 0x43ac, + 0x3664, 0x0640, 0x1288, 0x2a1c, 0x42ac, + 0x3668, 0x0644, 0x128c, 0x2a20, 0x42b0, + 0x3768, 0x0744, 0x138c, 0x2b20, 0x43b0, + 0x3868, 0x0844, 0x148c, 0x2c20, 0x44b0, + 0x3c48, 0x0c24, 0x186c, 0x3000, 0x0090, + 0x3d48, 0x0d24, 0x196c, 0x3100, 0x0190, + 0x3e48, 0x0e24, 0x1a6c, 0x3200, 0x0290, + 0x3e4c, 0x0e28, 0x1a70, 0x3204, 0x0294, + 0x3d4c, 0x0d28, 0x1970, 0x3104, 0x0194, + 0x3c4c, 0x0c28, 0x1870, 0x3004, 0x0094, + 0x3c50, 0x0c2c, 0x1874, 0x3008, 0x0098, + 0x3d50, 0x0d2c, 0x1974, 0x3108, 0x0198, + 0x3e50, 0x0e2c, 0x1a74, 0x3208, 0x0298, + 0x3e54, 0x0e30, 0x1a78, 0x320c, 0x029c, + 0x3d54, 0x0d30, 0x1978, 0x310c, 0x019c, + 0x3c54, 0x0c30, 0x1878, 0x300c, 0x009c, + 0x3c58, 0x0c34, 0x187c, 0x3010, 0x00a0, + 0x3d58, 0x0d34, 0x197c, 0x3110, 0x01a0, + 0x3e58, 0x0e34, 0x1a7c, 0x3210, 0x02a0, + 0x3e5c, 0x0e38, 0x1a80, 0x3214, 0x02a4, + 0x3d5c, 0x0d38, 0x1980, 0x3114, 0x01a4, + 0x3c5c, 0x0c38, 0x1880, 0x3014, 0x00a4, + 0x3c60, 0x0c3c, 0x1884, 0x3018, 0x00a8, + 0x3d60, 0x0d3c, 0x1984, 0x3118, 0x01a8, + 0x3e60, 0x0e3c, 0x1a84, 0x3218, 0x02a8, + 0x3e64, 0x0e40, 0x1a88, 0x321c, 0x02ac, + 0x3d64, 0x0d40, 0x1988, 0x311c, 0x01ac, + 0x3c64, 0x0c40, 0x1888, 0x301c, 0x00ac, + 0x3c68, 0x0c44, 0x188c, 0x3020, 0x00b0, + 0x3d68, 0x0d44, 0x198c, 0x3120, 0x01b0, + 0x3e68, 0x0e44, 0x1a8c, 0x3220, 0x02b0, + 0x4248, 0x1224, 0x1e6c, 0x3600, 0x0690, + 0x4348, 0x1324, 0x1f6c, 0x3700, 0x0790, + 0x4448, 0x1424, 0x206c, 0x3800, 0x0890, + 0x444c, 0x1428, 0x2070, 0x3804, 0x0894, + 0x434c, 0x1328, 0x1f70, 0x3704, 0x0794, + 0x424c, 0x1228, 0x1e70, 0x3604, 0x0694, + 0x4250, 0x122c, 0x1e74, 0x3608, 0x0698, + 0x4350, 0x132c, 0x1f74, 0x3708, 0x0798, + 0x4450, 0x142c, 0x2074, 0x3808, 0x0898, + 0x4454, 0x1430, 0x2078, 0x380c, 0x089c, + 0x4354, 0x1330, 0x1f78, 0x370c, 0x079c, + 0x4254, 0x1230, 0x1e78, 0x360c, 0x069c, + 0x4258, 0x1234, 0x1e7c, 0x3610, 0x06a0, + 0x4358, 0x1334, 0x1f7c, 0x3710, 0x07a0, + 0x4458, 0x1434, 0x207c, 0x3810, 0x08a0, + 0x445c, 0x1438, 0x2080, 0x3814, 0x08a4, + 0x435c, 0x1338, 0x1f80, 0x3714, 0x07a4, + 0x425c, 0x1238, 0x1e80, 0x3614, 0x06a4, + 0x4260, 0x123c, 0x1e84, 0x3618, 0x06a8, + 0x4360, 0x133c, 0x1f84, 0x3718, 0x07a8, + 0x4460, 0x143c, 0x2084, 0x3818, 0x08a8, + 0x4464, 0x1440, 0x2088, 0x381c, 0x08ac, + 0x4364, 0x1340, 0x1f88, 0x371c, 0x07ac, + 0x4264, 0x1240, 0x1e88, 0x361c, 0x06ac, + 0x4268, 0x1244, 0x1e8c, 0x3620, 0x06b0, + 0x4368, 0x1344, 0x1f8c, 0x3720, 0x07b0, + 0x4468, 0x1444, 0x208c, 0x3820, 0x08b0, + 0x0048, 0x1824, 0x246c, 0x3c00, 0x0c90, + 0x0148, 0x1924, 0x256c, 0x3d00, 0x0d90, + 0x0248, 0x1a24, 0x266c, 0x3e00, 0x0e90, + 0x024c, 0x1a28, 0x2670, 0x3e04, 0x0e94, + 0x014c, 0x1928, 0x2570, 0x3d04, 0x0d94, + 0x004c, 0x1828, 0x2470, 0x3c04, 0x0c94, + 0x0050, 0x182c, 0x2474, 0x3c08, 0x0c98, + 0x0150, 0x192c, 0x2574, 0x3d08, 0x0d98, + 0x0250, 0x1a2c, 0x2674, 0x3e08, 0x0e98, + 0x0254, 0x1a30, 0x2678, 0x3e0c, 0x0e9c, + 0x0154, 0x1930, 0x2578, 0x3d0c, 0x0d9c, + 0x0054, 0x1830, 0x2478, 0x3c0c, 0x0c9c, + 0x0058, 0x1834, 0x247c, 0x3c10, 0x0ca0, + 0x0158, 0x1934, 0x257c, 0x3d10, 0x0da0, + 0x0258, 0x1a34, 0x267c, 0x3e10, 0x0ea0, + 0x025c, 0x1a38, 0x2680, 0x3e14, 0x0ea4, + 0x015c, 0x1938, 0x2580, 0x3d14, 0x0da4, + 0x005c, 0x1838, 0x2480, 0x3c14, 0x0ca4, + 0x0060, 0x183c, 0x2484, 0x3c18, 0x0ca8, + 0x0160, 0x193c, 0x2584, 0x3d18, 0x0da8, + 0x0260, 0x1a3c, 0x2684, 0x3e18, 0x0ea8, + 0x0264, 0x1a40, 0x2688, 0x3e1c, 0x0eac, + 0x0164, 0x1940, 0x2588, 0x3d1c, 0x0dac, + 0x0064, 0x1840, 0x2488, 0x3c1c, 0x0cac, + 0x0068, 0x1844, 0x248c, 0x3c20, 0x0cb0, + 0x0168, 0x1944, 0x258c, 0x3d20, 0x0db0, + 0x0268, 0x1a44, 0x268c, 0x3e20, 0x0eb0, + 0x0648, 0x1e24, 0x2a6c, 0x4200, 0x1290, + 0x0748, 0x1f24, 0x2b6c, 0x4300, 0x1390, + 0x0848, 0x2024, 0x2c6c, 0x4400, 0x1490, + 0x084c, 0x2028, 0x2c70, 0x4404, 0x1494, + 0x074c, 0x1f28, 0x2b70, 0x4304, 0x1394, + 0x064c, 0x1e28, 0x2a70, 0x4204, 0x1294, + 0x0650, 0x1e2c, 0x2a74, 0x4208, 0x1298, + 0x0750, 0x1f2c, 0x2b74, 0x4308, 0x1398, + 0x0850, 0x202c, 0x2c74, 0x4408, 0x1498, + 0x0854, 0x2030, 0x2c78, 0x440c, 0x149c, + 0x0754, 0x1f30, 0x2b78, 0x430c, 0x139c, + 0x0654, 0x1e30, 0x2a78, 0x420c, 0x129c, + 0x0658, 0x1e34, 0x2a7c, 0x4210, 0x12a0, + 0x0758, 0x1f34, 0x2b7c, 0x4310, 0x13a0, + 0x0858, 0x2034, 0x2c7c, 0x4410, 0x14a0, + 0x085c, 0x2038, 0x2c80, 0x4414, 0x14a4, + 0x075c, 0x1f38, 0x2b80, 0x4314, 0x13a4, + 0x065c, 0x1e38, 0x2a80, 0x4214, 0x12a4, + 0x0660, 0x1e3c, 0x2a84, 0x4218, 0x12a8, + 0x0760, 0x1f3c, 0x2b84, 0x4318, 0x13a8, + 0x0860, 0x203c, 0x2c84, 0x4418, 0x14a8, + 0x0864, 0x2040, 0x2c88, 0x441c, 0x14ac, + 0x0764, 0x1f40, 0x2b88, 0x431c, 0x13ac, + 0x0664, 0x1e40, 0x2a88, 0x421c, 0x12ac, + 0x0668, 0x1e44, 0x2a8c, 0x4220, 0x12b0, + 0x0768, 0x1f44, 0x2b8c, 0x4320, 0x13b0, + 0x0868, 0x2044, 0x2c8c, 0x4420, 0x14b0, + 0x0f48, 0x2724, 0x336c, 0x0300, 0x1b90, + 0x1048, 0x2824, 0x346c, 0x0400, 0x1c90, + 0x1148, 0x2924, 0x356c, 0x0500, 0x1d90, + 0x114c, 0x2928, 0x3570, 0x0504, 0x1d94, + 0x104c, 0x2828, 0x3470, 0x0404, 0x1c94, + 0x0f4c, 0x2728, 0x3370, 0x0304, 0x1b94, + 0x0f50, 0x272c, 0x3374, 0x0308, 0x1b98, + 0x1050, 0x282c, 0x3474, 0x0408, 0x1c98, + 0x1150, 0x292c, 0x3574, 0x0508, 0x1d98, + 0x1154, 0x2930, 0x3578, 0x050c, 0x1d9c, + 0x1054, 0x2830, 0x3478, 0x040c, 0x1c9c, + 0x0f54, 0x2730, 0x3378, 0x030c, 0x1b9c, + 0x0f58, 0x2734, 0x337c, 0x0310, 0x1ba0, + 0x1058, 0x2834, 0x347c, 0x0410, 0x1ca0, + 0x1158, 0x2934, 0x357c, 0x0510, 0x1da0, + 0x115c, 0x2938, 0x3580, 0x0514, 0x1da4, + 0x105c, 0x2838, 0x3480, 0x0414, 0x1ca4, + 0x0f5c, 0x2738, 0x3380, 0x0314, 0x1ba4, + 0x0f60, 0x273c, 0x3384, 0x0318, 0x1ba8, + 0x1060, 0x283c, 0x3484, 0x0418, 0x1ca8, + 0x1160, 0x293c, 0x3584, 0x0518, 0x1da8, + 0x1164, 0x2940, 0x3588, 0x051c, 0x1dac, + 0x1064, 0x2840, 0x3488, 0x041c, 0x1cac, + 0x0f64, 0x2740, 0x3388, 0x031c, 0x1bac, + 0x0f68, 0x2744, 0x338c, 0x0320, 0x1bb0, + 0x1068, 0x2844, 0x348c, 0x0420, 0x1cb0, + 0x1168, 0x2944, 0x358c, 0x0520, 0x1db0, + 0x1548, 0x2d24, 0x396c, 0x0900, 0x2190, + 0x1648, 0x2e24, 0x3a6c, 0x0a00, 0x2290, + 0x1748, 0x2f24, 0x3b6c, 0x0b00, 0x2390, + 0x174c, 0x2f28, 0x3b70, 0x0b04, 0x2394, + 0x164c, 0x2e28, 0x3a70, 0x0a04, 0x2294, + 0x154c, 0x2d28, 0x3970, 0x0904, 0x2194, + 0x1550, 0x2d2c, 0x3974, 0x0908, 0x2198, + 0x1650, 0x2e2c, 0x3a74, 0x0a08, 0x2298, + 0x1750, 0x2f2c, 0x3b74, 0x0b08, 0x2398, + 0x1754, 0x2f30, 0x3b78, 0x0b0c, 0x239c, + 0x1654, 0x2e30, 0x3a78, 0x0a0c, 0x229c, + 0x1554, 0x2d30, 0x3978, 0x090c, 0x219c, + 0x1558, 0x2d34, 0x397c, 0x0910, 0x21a0, + 0x1658, 0x2e34, 0x3a7c, 0x0a10, 0x22a0, + 0x1758, 0x2f34, 0x3b7c, 0x0b10, 0x23a0, + 0x175c, 0x2f38, 0x3b80, 0x0b14, 0x23a4, + 0x165c, 0x2e38, 0x3a80, 0x0a14, 0x22a4, + 0x155c, 0x2d38, 0x3980, 0x0914, 0x21a4, + 0x1560, 0x2d3c, 0x3984, 0x0918, 0x21a8, + 0x1660, 0x2e3c, 0x3a84, 0x0a18, 0x22a8, + 0x1760, 0x2f3c, 0x3b84, 0x0b18, 0x23a8, + 0x1764, 0x2f40, 0x3b88, 0x0b1c, 0x23ac, + 0x1664, 0x2e40, 0x3a88, 0x0a1c, 0x22ac, + 0x1564, 0x2d40, 0x3988, 0x091c, 0x21ac, + 0x1568, 0x2d44, 0x398c, 0x0920, 0x21b0, + 0x1668, 0x2e44, 0x3a8c, 0x0a20, 0x22b0, + 0x1768, 0x2f44, 0x3b8c, 0x0b20, 0x23b0, + 0x1b48, 0x3324, 0x3f6c, 0x0f00, 0x2790, + 0x1c48, 0x3424, 0x406c, 0x1000, 0x2890, + 0x1d48, 0x3524, 0x416c, 0x1100, 0x2990, + 0x1d4c, 0x3528, 0x4170, 0x1104, 0x2994, + 0x1c4c, 0x3428, 0x4070, 0x1004, 0x2894, + 0x1b4c, 0x3328, 0x3f70, 0x0f04, 0x2794, + 0x1b50, 0x332c, 0x3f74, 0x0f08, 0x2798, + 0x1c50, 0x342c, 0x4074, 0x1008, 0x2898, + 0x1d50, 0x352c, 0x4174, 0x1108, 0x2998, + 0x1d54, 0x3530, 0x4178, 0x110c, 0x299c, + 0x1c54, 0x3430, 0x4078, 0x100c, 0x289c, + 0x1b54, 0x3330, 0x3f78, 0x0f0c, 0x279c, + 0x1b58, 0x3334, 0x3f7c, 0x0f10, 0x27a0, + 0x1c58, 0x3434, 0x407c, 0x1010, 0x28a0, + 0x1d58, 0x3534, 0x417c, 0x1110, 0x29a0, + 0x1d5c, 0x3538, 0x4180, 0x1114, 0x29a4, + 0x1c5c, 0x3438, 0x4080, 0x1014, 0x28a4, + 0x1b5c, 0x3338, 0x3f80, 0x0f14, 0x27a4, + 0x1b60, 0x333c, 0x3f84, 0x0f18, 0x27a8, + 0x1c60, 0x343c, 0x4084, 0x1018, 0x28a8, + 0x1d60, 0x353c, 0x4184, 0x1118, 0x29a8, + 0x1d64, 0x3540, 0x4188, 0x111c, 0x29ac, + 0x1c64, 0x3440, 0x4088, 0x101c, 0x28ac, + 0x1b64, 0x3340, 0x3f88, 0x0f1c, 0x27ac, + 0x1b68, 0x3344, 0x3f8c, 0x0f20, 0x27b0, + 0x1c68, 0x3444, 0x408c, 0x1020, 0x28b0, + 0x1d68, 0x3544, 0x418c, 0x1120, 0x29b0, + 0x2148, 0x3924, 0x456c, 0x1500, 0x2d90, + 0x2248, 0x3a24, 0x466c, 0x1600, 0x2e90, + 0x2348, 0x3b24, 0x476c, 0x1700, 0x2f90, + 0x234c, 0x3b28, 0x4770, 0x1704, 0x2f94, + 0x224c, 0x3a28, 0x4670, 0x1604, 0x2e94, + 0x214c, 0x3928, 0x4570, 0x1504, 0x2d94, + 0x2150, 0x392c, 0x4574, 0x1508, 0x2d98, + 0x2250, 0x3a2c, 0x4674, 0x1608, 0x2e98, + 0x2350, 0x3b2c, 0x4774, 0x1708, 0x2f98, + 0x2354, 0x3b30, 0x4778, 0x170c, 0x2f9c, + 0x2254, 0x3a30, 0x4678, 0x160c, 0x2e9c, + 0x2154, 0x3930, 0x4578, 0x150c, 0x2d9c, + 0x2158, 0x3934, 0x457c, 0x1510, 0x2da0, + 0x2258, 0x3a34, 0x467c, 0x1610, 0x2ea0, + 0x2358, 0x3b34, 0x477c, 0x1710, 0x2fa0, + 0x235c, 0x3b38, 0x4780, 0x1714, 0x2fa4, + 0x225c, 0x3a38, 0x4680, 0x1614, 0x2ea4, + 0x215c, 0x3938, 0x4580, 0x1514, 0x2da4, + 0x2160, 0x393c, 0x4584, 0x1518, 0x2da8, + 0x2260, 0x3a3c, 0x4684, 0x1618, 0x2ea8, + 0x2360, 0x3b3c, 0x4784, 0x1718, 0x2fa8, + 0x2364, 0x3b40, 0x4788, 0x171c, 0x2fac, + 0x2264, 0x3a40, 0x4688, 0x161c, 0x2eac, + 0x2164, 0x3940, 0x4588, 0x151c, 0x2dac, + 0x2168, 0x3944, 0x458c, 0x1520, 0x2db0, + 0x2268, 0x3a44, 0x468c, 0x1620, 0x2eb0, + 0x2368, 0x3b44, 0x478c, 0x1720, 0x2fb0, + 0x2748, 0x3f24, 0x036c, 0x1b00, 0x3390, + 0x2848, 0x4024, 0x046c, 0x1c00, 0x3490, + 0x2948, 0x4124, 0x056c, 0x1d00, 0x3590, + 0x294c, 0x4128, 0x0570, 0x1d04, 0x3594, + 0x284c, 0x4028, 0x0470, 0x1c04, 0x3494, + 0x274c, 0x3f28, 0x0370, 0x1b04, 0x3394, + 0x2750, 0x3f2c, 0x0374, 0x1b08, 0x3398, + 0x2850, 0x402c, 0x0474, 0x1c08, 0x3498, + 0x2950, 0x412c, 0x0574, 0x1d08, 0x3598, + 0x2954, 0x4130, 0x0578, 0x1d0c, 0x359c, + 0x2854, 0x4030, 0x0478, 0x1c0c, 0x349c, + 0x2754, 0x3f30, 0x0378, 0x1b0c, 0x339c, + 0x2758, 0x3f34, 0x037c, 0x1b10, 0x33a0, + 0x2858, 0x4034, 0x047c, 0x1c10, 0x34a0, + 0x2958, 0x4134, 0x057c, 0x1d10, 0x35a0, + 0x295c, 0x4138, 0x0580, 0x1d14, 0x35a4, + 0x285c, 0x4038, 0x0480, 0x1c14, 0x34a4, + 0x275c, 0x3f38, 0x0380, 0x1b14, 0x33a4, + 0x2760, 0x3f3c, 0x0384, 0x1b18, 0x33a8, + 0x2860, 0x403c, 0x0484, 0x1c18, 0x34a8, + 0x2960, 0x413c, 0x0584, 0x1d18, 0x35a8, + 0x2964, 0x4140, 0x0588, 0x1d1c, 0x35ac, + 0x2864, 0x4040, 0x0488, 0x1c1c, 0x34ac, + 0x2764, 0x3f40, 0x0388, 0x1b1c, 0x33ac, + 0x2768, 0x3f44, 0x038c, 0x1b20, 0x33b0, + 0x2868, 0x4044, 0x048c, 0x1c20, 0x34b0, + 0x2968, 0x4144, 0x058c, 0x1d20, 0x35b0, + 0x2d48, 0x4524, 0x096c, 0x2100, 0x3990, + 0x2e48, 0x4624, 0x0a6c, 0x2200, 0x3a90, + 0x2f48, 0x4724, 0x0b6c, 0x2300, 0x3b90, + 0x2f4c, 0x4728, 0x0b70, 0x2304, 0x3b94, + 0x2e4c, 0x4628, 0x0a70, 0x2204, 0x3a94, + 0x2d4c, 0x4528, 0x0970, 0x2104, 0x3994, + 0x2d50, 0x452c, 0x0974, 0x2108, 0x3998, + 0x2e50, 0x462c, 0x0a74, 0x2208, 0x3a98, + 0x2f50, 0x472c, 0x0b74, 0x2308, 0x3b98, + 0x2f54, 0x4730, 0x0b78, 0x230c, 0x3b9c, + 0x2e54, 0x4630, 0x0a78, 0x220c, 0x3a9c, + 0x2d54, 0x4530, 0x0978, 0x210c, 0x399c, + 0x2d58, 0x4534, 0x097c, 0x2110, 0x39a0, + 0x2e58, 0x4634, 0x0a7c, 0x2210, 0x3aa0, + 0x2f58, 0x4734, 0x0b7c, 0x2310, 0x3ba0, + 0x2f5c, 0x4738, 0x0b80, 0x2314, 0x3ba4, + 0x2e5c, 0x4638, 0x0a80, 0x2214, 0x3aa4, + 0x2d5c, 0x4538, 0x0980, 0x2114, 0x39a4, + 0x2d60, 0x453c, 0x0984, 0x2118, 0x39a8, + 0x2e60, 0x463c, 0x0a84, 0x2218, 0x3aa8, + 0x2f60, 0x473c, 0x0b84, 0x2318, 0x3ba8, + 0x2f64, 0x4740, 0x0b88, 0x231c, 0x3bac, + 0x2e64, 0x4640, 0x0a88, 0x221c, 0x3aac, + 0x2d64, 0x4540, 0x0988, 0x211c, 0x39ac, + 0x2d68, 0x4544, 0x098c, 0x2120, 0x39b0, + 0x2e68, 0x4644, 0x0a8c, 0x2220, 0x3ab0, + 0x2f68, 0x4744, 0x0b8c, 0x2320, 0x3bb0, + 0x3348, 0x0324, 0x0f6c, 0x2700, 0x3f90, + 0x3448, 0x0424, 0x106c, 0x2800, 0x4090, + 0x3548, 0x0524, 0x116c, 0x2900, 0x4190, + 0x354c, 0x0528, 0x1170, 0x2904, 0x4194, + 0x344c, 0x0428, 0x1070, 0x2804, 0x4094, + 0x334c, 0x0328, 0x0f70, 0x2704, 0x3f94, + 0x3350, 0x032c, 0x0f74, 0x2708, 0x3f98, + 0x3450, 0x042c, 0x1074, 0x2808, 0x4098, + 0x3550, 0x052c, 0x1174, 0x2908, 0x4198, + 0x3554, 0x0530, 0x1178, 0x290c, 0x419c, + 0x3454, 0x0430, 0x1078, 0x280c, 0x409c, + 0x3354, 0x0330, 0x0f78, 0x270c, 0x3f9c, + 0x3358, 0x0334, 0x0f7c, 0x2710, 0x3fa0, + 0x3458, 0x0434, 0x107c, 0x2810, 0x40a0, + 0x3558, 0x0534, 0x117c, 0x2910, 0x41a0, + 0x355c, 0x0538, 0x1180, 0x2914, 0x41a4, + 0x345c, 0x0438, 0x1080, 0x2814, 0x40a4, + 0x335c, 0x0338, 0x0f80, 0x2714, 0x3fa4, + 0x3360, 0x033c, 0x0f84, 0x2718, 0x3fa8, + 0x3460, 0x043c, 0x1084, 0x2818, 0x40a8, + 0x3560, 0x053c, 0x1184, 0x2918, 0x41a8, + 0x3564, 0x0540, 0x1188, 0x291c, 0x41ac, + 0x3464, 0x0440, 0x1088, 0x281c, 0x40ac, + 0x3364, 0x0340, 0x0f88, 0x271c, 0x3fac, + 0x3368, 0x0344, 0x0f8c, 0x2720, 0x3fb0, + 0x3468, 0x0444, 0x108c, 0x2820, 0x40b0, + 0x3568, 0x0544, 0x118c, 0x2920, 0x41b0, + 0x3948, 0x0924, 0x156c, 0x2d00, 0x4590, + 0x3a48, 0x0a24, 0x166c, 0x2e00, 0x4690, + 0x3b48, 0x0b24, 0x176c, 0x2f00, 0x4790, + 0x3b4c, 0x0b28, 0x1770, 0x2f04, 0x4794, + 0x3a4c, 0x0a28, 0x1670, 0x2e04, 0x4694, + 0x394c, 0x0928, 0x1570, 0x2d04, 0x4594, + 0x3950, 0x092c, 0x1574, 0x2d08, 0x4598, + 0x3a50, 0x0a2c, 0x1674, 0x2e08, 0x4698, + 0x3b50, 0x0b2c, 0x1774, 0x2f08, 0x4798, + 0x3b54, 0x0b30, 0x1778, 0x2f0c, 0x479c, + 0x3a54, 0x0a30, 0x1678, 0x2e0c, 0x469c, + 0x3954, 0x0930, 0x1578, 0x2d0c, 0x459c, + 0x3958, 0x0934, 0x157c, 0x2d10, 0x45a0, + 0x3a58, 0x0a34, 0x167c, 0x2e10, 0x46a0, + 0x3b58, 0x0b34, 0x177c, 0x2f10, 0x47a0, + 0x3b5c, 0x0b38, 0x1780, 0x2f14, 0x47a4, + 0x3a5c, 0x0a38, 0x1680, 0x2e14, 0x46a4, + 0x395c, 0x0938, 0x1580, 0x2d14, 0x45a4, + 0x3960, 0x093c, 0x1584, 0x2d18, 0x45a8, + 0x3a60, 0x0a3c, 0x1684, 0x2e18, 0x46a8, + 0x3b60, 0x0b3c, 0x1784, 0x2f18, 0x47a8, + 0x3b64, 0x0b40, 0x1788, 0x2f1c, 0x47ac, + 0x3a64, 0x0a40, 0x1688, 0x2e1c, 0x46ac, + 0x3964, 0x0940, 0x1588, 0x2d1c, 0x45ac, + 0x3968, 0x0944, 0x158c, 0x2d20, 0x45b0, + 0x3a68, 0x0a44, 0x168c, 0x2e20, 0x46b0, + 0x3b68, 0x0b44, 0x178c, 0x2f20, 0x47b0, + 0x3f48, 0x0f24, 0x1b6c, 0x3300, 0x0390, + 0x4048, 0x1024, 0x1c6c, 0x3400, 0x0490, + 0x4148, 0x1124, 0x1d6c, 0x3500, 0x0590, + 0x414c, 0x1128, 0x1d70, 0x3504, 0x0594, + 0x404c, 0x1028, 0x1c70, 0x3404, 0x0494, + 0x3f4c, 0x0f28, 0x1b70, 0x3304, 0x0394, + 0x3f50, 0x0f2c, 0x1b74, 0x3308, 0x0398, + 0x4050, 0x102c, 0x1c74, 0x3408, 0x0498, + 0x4150, 0x112c, 0x1d74, 0x3508, 0x0598, + 0x4154, 0x1130, 0x1d78, 0x350c, 0x059c, + 0x4054, 0x1030, 0x1c78, 0x340c, 0x049c, + 0x3f54, 0x0f30, 0x1b78, 0x330c, 0x039c, + 0x3f58, 0x0f34, 0x1b7c, 0x3310, 0x03a0, + 0x4058, 0x1034, 0x1c7c, 0x3410, 0x04a0, + 0x4158, 0x1134, 0x1d7c, 0x3510, 0x05a0, + 0x415c, 0x1138, 0x1d80, 0x3514, 0x05a4, + 0x405c, 0x1038, 0x1c80, 0x3414, 0x04a4, + 0x3f5c, 0x0f38, 0x1b80, 0x3314, 0x03a4, + 0x3f60, 0x0f3c, 0x1b84, 0x3318, 0x03a8, + 0x4060, 0x103c, 0x1c84, 0x3418, 0x04a8, + 0x4160, 0x113c, 0x1d84, 0x3518, 0x05a8, + 0x4164, 0x1140, 0x1d88, 0x351c, 0x05ac, + 0x4064, 0x1040, 0x1c88, 0x341c, 0x04ac, + 0x3f64, 0x0f40, 0x1b88, 0x331c, 0x03ac, + 0x3f68, 0x0f44, 0x1b8c, 0x3320, 0x03b0, + 0x4068, 0x1044, 0x1c8c, 0x3420, 0x04b0, + 0x4168, 0x1144, 0x1d8c, 0x3520, 0x05b0, + 0x4548, 0x1524, 0x216c, 0x3900, 0x0990, + 0x4648, 0x1624, 0x226c, 0x3a00, 0x0a90, + 0x4748, 0x1724, 0x236c, 0x3b00, 0x0b90, + 0x474c, 0x1728, 0x2370, 0x3b04, 0x0b94, + 0x464c, 0x1628, 0x2270, 0x3a04, 0x0a94, + 0x454c, 0x1528, 0x2170, 0x3904, 0x0994, + 0x4550, 0x152c, 0x2174, 0x3908, 0x0998, + 0x4650, 0x162c, 0x2274, 0x3a08, 0x0a98, + 0x4750, 0x172c, 0x2374, 0x3b08, 0x0b98, + 0x4754, 0x1730, 0x2378, 0x3b0c, 0x0b9c, + 0x4654, 0x1630, 0x2278, 0x3a0c, 0x0a9c, + 0x4554, 0x1530, 0x2178, 0x390c, 0x099c, + 0x4558, 0x1534, 0x217c, 0x3910, 0x09a0, + 0x4658, 0x1634, 0x227c, 0x3a10, 0x0aa0, + 0x4758, 0x1734, 0x237c, 0x3b10, 0x0ba0, + 0x475c, 0x1738, 0x2380, 0x3b14, 0x0ba4, + 0x465c, 0x1638, 0x2280, 0x3a14, 0x0aa4, + 0x455c, 0x1538, 0x2180, 0x3914, 0x09a4, + 0x4560, 0x153c, 0x2184, 0x3918, 0x09a8, + 0x4660, 0x163c, 0x2284, 0x3a18, 0x0aa8, + 0x4760, 0x173c, 0x2384, 0x3b18, 0x0ba8, + 0x4764, 0x1740, 0x2388, 0x3b1c, 0x0bac, + 0x4664, 0x1640, 0x2288, 0x3a1c, 0x0aac, + 0x4564, 0x1540, 0x2188, 0x391c, 0x09ac, + 0x4568, 0x1544, 0x218c, 0x3920, 0x09b0, + 0x4668, 0x1644, 0x228c, 0x3a20, 0x0ab0, + 0x4768, 0x1744, 0x238c, 0x3b20, 0x0bb0, + 0x0348, 0x1b24, 0x276c, 0x3f00, 0x0f90, + 0x0448, 0x1c24, 0x286c, 0x4000, 0x1090, + 0x0548, 0x1d24, 0x296c, 0x4100, 0x1190, + 0x054c, 0x1d28, 0x2970, 0x4104, 0x1194, + 0x044c, 0x1c28, 0x2870, 0x4004, 0x1094, + 0x034c, 0x1b28, 0x2770, 0x3f04, 0x0f94, + 0x0350, 0x1b2c, 0x2774, 0x3f08, 0x0f98, + 0x0450, 0x1c2c, 0x2874, 0x4008, 0x1098, + 0x0550, 0x1d2c, 0x2974, 0x4108, 0x1198, + 0x0554, 0x1d30, 0x2978, 0x410c, 0x119c, + 0x0454, 0x1c30, 0x2878, 0x400c, 0x109c, + 0x0354, 0x1b30, 0x2778, 0x3f0c, 0x0f9c, + 0x0358, 0x1b34, 0x277c, 0x3f10, 0x0fa0, + 0x0458, 0x1c34, 0x287c, 0x4010, 0x10a0, + 0x0558, 0x1d34, 0x297c, 0x4110, 0x11a0, + 0x055c, 0x1d38, 0x2980, 0x4114, 0x11a4, + 0x045c, 0x1c38, 0x2880, 0x4014, 0x10a4, + 0x035c, 0x1b38, 0x2780, 0x3f14, 0x0fa4, + 0x0360, 0x1b3c, 0x2784, 0x3f18, 0x0fa8, + 0x0460, 0x1c3c, 0x2884, 0x4018, 0x10a8, + 0x0560, 0x1d3c, 0x2984, 0x4118, 0x11a8, + 0x0564, 0x1d40, 0x2988, 0x411c, 0x11ac, + 0x0464, 0x1c40, 0x2888, 0x401c, 0x10ac, + 0x0364, 0x1b40, 0x2788, 0x3f1c, 0x0fac, + 0x0368, 0x1b44, 0x278c, 0x3f20, 0x0fb0, + 0x0468, 0x1c44, 0x288c, 0x4020, 0x10b0, + 0x0568, 0x1d44, 0x298c, 0x4120, 0x11b0, + 0x0948, 0x2124, 0x2d6c, 0x4500, 0x1590, + 0x0a48, 0x2224, 0x2e6c, 0x4600, 0x1690, + 0x0b48, 0x2324, 0x2f6c, 0x4700, 0x1790, + 0x0b4c, 0x2328, 0x2f70, 0x4704, 0x1794, + 0x0a4c, 0x2228, 0x2e70, 0x4604, 0x1694, + 0x094c, 0x2128, 0x2d70, 0x4504, 0x1594, + 0x0950, 0x212c, 0x2d74, 0x4508, 0x1598, + 0x0a50, 0x222c, 0x2e74, 0x4608, 0x1698, + 0x0b50, 0x232c, 0x2f74, 0x4708, 0x1798, + 0x0b54, 0x2330, 0x2f78, 0x470c, 0x179c, + 0x0a54, 0x2230, 0x2e78, 0x460c, 0x169c, + 0x0954, 0x2130, 0x2d78, 0x450c, 0x159c, + 0x0958, 0x2134, 0x2d7c, 0x4510, 0x15a0, + 0x0a58, 0x2234, 0x2e7c, 0x4610, 0x16a0, + 0x0b58, 0x2334, 0x2f7c, 0x4710, 0x17a0, + 0x0b5c, 0x2338, 0x2f80, 0x4714, 0x17a4, + 0x0a5c, 0x2238, 0x2e80, 0x4614, 0x16a4, + 0x095c, 0x2138, 0x2d80, 0x4514, 0x15a4, + 0x0960, 0x213c, 0x2d84, 0x4518, 0x15a8, + 0x0a60, 0x223c, 0x2e84, 0x4618, 0x16a8, + 0x0b60, 0x233c, 0x2f84, 0x4718, 0x17a8, + 0x0b64, 0x2340, 0x2f88, 0x471c, 0x17ac, + 0x0a64, 0x2240, 0x2e88, 0x461c, 0x16ac, + 0x0964, 0x2140, 0x2d88, 0x451c, 0x15ac, + 0x0968, 0x2144, 0x2d8c, 0x4520, 0x15b0, + 0x0a68, 0x2244, 0x2e8c, 0x4620, 0x16b0, + 0x0b68, 0x2344, 0x2f8c, 0x4720, 0x17b0, +}; + +/* DV25/50 DCT coefficient weights and inverse weights */ +/* created by dvtables.py */ +static const int dv_weight_bits = 18; +static const int dv_weight_88[64] = { + 131072, 257107, 257107, 242189, 252167, 242189, 235923, 237536, + 237536, 235923, 229376, 231390, 223754, 231390, 229376, 222935, + 224969, 217965, 217965, 224969, 222935, 200636, 218652, 211916, + 212325, 211916, 218652, 200636, 188995, 196781, 205965, 206433, + 206433, 205965, 196781, 188995, 185364, 185364, 200636, 200704, + 200636, 185364, 185364, 174609, 180568, 195068, 195068, 180568, + 174609, 170091, 175557, 189591, 175557, 170091, 165371, 170627, + 170627, 165371, 160727, 153560, 160727, 144651, 144651, 136258, +}; +static const int dv_weight_248[64] = { + 131072, 242189, 257107, 237536, 229376, 200636, 242189, 223754, + 224969, 196781, 262144, 242189, 229376, 200636, 257107, 237536, + 211916, 185364, 235923, 217965, 229376, 211916, 206433, 180568, + 242189, 223754, 224969, 196781, 211916, 185364, 235923, 217965, + 200704, 175557, 222935, 205965, 200636, 185364, 195068, 170627, + 229376, 211916, 206433, 180568, 200704, 175557, 222935, 205965, + 175557, 153560, 188995, 174609, 165371, 144651, 200636, 185364, + 195068, 170627, 175557, 153560, 188995, 174609, 165371, 144651, +}; +static const int dv_iweight_bits = 14; +static const int dv_iweight_88[64] = { + 32768, 16710, 16710, 17735, 17015, 17735, 18197, 18079, + 18079, 18197, 18725, 18559, 19196, 18559, 18725, 19284, + 19108, 19692, 19692, 19108, 19284, 21400, 19645, 20262, + 20214, 20262, 19645, 21400, 22733, 21845, 20867, 20815, + 20815, 20867, 21845, 22733, 23173, 23173, 21400, 21400, + 21400, 23173, 23173, 24600, 23764, 22017, 22017, 23764, + 24600, 25267, 24457, 22672, 24457, 25267, 25971, 25191, + 25191, 25971, 26715, 27962, 26715, 29642, 29642, 31536, +}; +static const int dv_iweight_248[64] = { + 32768, 17735, 16710, 18079, 18725, 21400, 17735, 19196, + 19108, 21845, 16384, 17735, 18725, 21400, 16710, 18079, + 20262, 23173, 18197, 19692, 18725, 20262, 20815, 23764, + 17735, 19196, 19108, 21845, 20262, 23173, 18197, 19692, + 21400, 24457, 19284, 20867, 21400, 23173, 22017, 25191, + 18725, 20262, 20815, 23764, 21400, 24457, 19284, 20867, + 24457, 27962, 22733, 24600, 25971, 29642, 21400, 23173, + 22017, 25191, 24457, 27962, 22733, 24600, 25971, 29642, +}; + +static const uint16_t dv_audio_shuffle525[10][9] = { + { 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */ + { 6, 36, 66, 26, 56, 86, 16, 46, 76 }, + { 12, 42, 72, 2, 32, 62, 22, 52, 82 }, + { 18, 48, 78, 8, 38, 68, 28, 58, 88 }, + { 24, 54, 84, 14, 44, 74, 4, 34, 64 }, + + { 1, 31, 61, 21, 51, 81, 11, 41, 71 }, /* 2nd channel */ + { 7, 37, 67, 27, 57, 87, 17, 47, 77 }, + { 13, 43, 73, 3, 33, 63, 23, 53, 83 }, + { 19, 49, 79, 9, 39, 69, 29, 59, 89 }, + { 25, 55, 85, 15, 45, 75, 5, 35, 65 }, +}; + +static const uint16_t dv_audio_shuffle625[12][9] = { + { 0, 36, 72, 26, 62, 98, 16, 52, 88}, /* 1st channel */ + { 6, 42, 78, 32, 68, 104, 22, 58, 94}, + { 12, 48, 84, 2, 38, 74, 28, 64, 100}, + { 18, 54, 90, 8, 44, 80, 34, 70, 106}, + { 24, 60, 96, 14, 50, 86, 4, 40, 76}, + { 30, 66, 102, 20, 56, 92, 10, 46, 82}, + + { 1, 37, 73, 27, 63, 99, 17, 53, 89}, /* 2nd channel */ + { 7, 43, 79, 33, 69, 105, 23, 59, 95}, + { 13, 49, 85, 3, 39, 75, 29, 65, 101}, + { 19, 55, 91, 9, 45, 81, 35, 71, 107}, + { 25, 61, 97, 15, 51, 87, 5, 41, 77}, + { 31, 67, 103, 21, 57, 93, 11, 47, 83}, +}; + +static const __attribute__((unused)) int dv_audio_frequency[3] = { + 48000, 44100, 32000, +}; + +static const DVprofile dv_profiles[] = { + { .dsf = 0, + .frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */ + .difseg_size = 10, + .n_difchan = 1, + .frame_rate = 30000, + .ltc_divisor = 30, + .frame_rate_base = 1001, + .height = 480, + .width = 720, + .sar = {{10, 11}, {40, 33}}, + .video_place = dv_place_411, + .pix_fmt = PIX_FMT_YUV411P, + .audio_stride = 90, + .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32Khz */ + .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ + .audio_shuffle = dv_audio_shuffle525, + }, + { .dsf = 1, + .frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */ + .difseg_size = 12, + .n_difchan = 1, + .frame_rate = 25, + .frame_rate_base = 1, + .ltc_divisor = 25, + .height = 576, + .width = 720, + .sar = {{59, 54}, {118, 81}}, + .video_place = dv_place_420, + .pix_fmt = PIX_FMT_YUV420P, + .audio_stride = 108, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32Khz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, + }, + { .dsf = 1, + .frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */ + .difseg_size = 12, + .n_difchan = 1, + .frame_rate = 25, + .frame_rate_base = 1, + .ltc_divisor = 25, + .height = 576, + .width = 720, + .sar = {{59, 54}, {118, 81}}, + .video_place = dv_place_411P, + .pix_fmt = PIX_FMT_YUV411P, + .audio_stride = 108, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32Khz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, + }, + { .dsf = 0, + .frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */ + .difseg_size = 10, /* also known as "DVCPRO50" */ + .n_difchan = 2, + .frame_rate = 30000, + .ltc_divisor = 30, + .frame_rate_base = 1001, + .height = 480, + .width = 720, + .sar = {{10, 11}, {40, 33}}, + .video_place = dv_place_422_525, + .pix_fmt = PIX_FMT_YUV422P, + .audio_stride = 90, + .audio_min_samples = { 1580, 1452, 1053 }, /* for 48, 44.1 and 32Khz */ + .audio_samples_dist = { 1600, 1602, 1602, 1602, 1602 }, /* per SMPTE-314M */ + .audio_shuffle = dv_audio_shuffle525, + }, + { .dsf = 1, + .frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */ + .difseg_size = 12, /* also known as "DVCPRO50" */ + .n_difchan = 2, + .frame_rate = 25, + .frame_rate_base = 1, + .ltc_divisor = 25, + .height = 576, + .width = 720, + .sar = {{59, 54}, {118, 81}}, + .video_place = dv_place_422_625, + .pix_fmt = PIX_FMT_YUV422P, + .audio_stride = 108, + .audio_min_samples = { 1896, 1742, 1264 }, /* for 48, 44.1 and 32Khz */ + .audio_samples_dist = { 1920, 1920, 1920, 1920, 1920 }, + .audio_shuffle = dv_audio_shuffle625, + } +}; + +/* minimum number of bytes to read from a DV stream in order to determine the profile */ +#define DV_PROFILE_BYTES (6*80) /* 6 DIF blocks */ + +/* largest possible DV frame, in bytes (PAL 50Mbps) */ +#define DV_MAX_FRAME_SIZE 288000 + +static inline const DVprofile* dv_frame_profile(uint8_t* frame) +{ + if ((frame[3] & 0x80) == 0) { /* DSF flag */ + /* it's an NTSC format */ + if ((frame[80*5 + 48 + 3] & 0x4)) { /* 4:2:2 sampling */ + return &dv_profiles[3]; /* NTSC 50Mbps */ + } else { /* 4:1:1 sampling */ + return &dv_profiles[0]; /* NTSC 25Mbps */ + } + } else { + /* it's a PAL format */ + if ((frame[80*5 + 48 + 3] & 0x4)) { /* 4:2:2 sampling */ + return &dv_profiles[4]; /* PAL 50Mbps */ + } else if ((frame[5] & 0x07) == 0) { /* APT flag */ + return &dv_profiles[1]; /* PAL 25Mbps 4:2:0 */ + } else + return &dv_profiles[2]; /* PAL 25Mbps 4:1:1 */ + } +} + +static inline const DVprofile* dv_codec_profile(AVCodecContext* codec) +{ + int i; + + if (codec->width != 720) + return NULL; + + for (i=0; iheight == dv_profiles[i].height && codec->pix_fmt == dv_profiles[i].pix_fmt) + return &dv_profiles[i]; + + return NULL; +} diff --git a/mpeg4/src/libavcodec/dvdsub.c b/mpeg4/src/libavcodec/dvdsub.c new file mode 100644 index 00000000..7a075871 --- /dev/null +++ b/mpeg4/src/libavcodec/dvdsub.c @@ -0,0 +1,478 @@ +/* + * DVD subtitle decoding for ffmpeg + * Copyright (c) 2005 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avcodec.h" + +//#define DEBUG + +typedef struct DVDSubContext { +} DVDSubContext; + +static int dvdsub_init_decoder(AVCodecContext *avctx) +{ + return 0; +} + +static uint16_t getbe16(const uint8_t *p) +{ + return (p[0] << 8) | p[1]; +} + +static int get_nibble(const uint8_t *buf, int nibble_offset) +{ + return (buf[nibble_offset >> 1] >> ((1 - (nibble_offset & 1)) << 2)) & 0xf; +} + +static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, + const uint8_t *buf, int nibble_offset, int buf_size) +{ + unsigned int v; + int x, y, len, color, nibble_end; + uint8_t *d; + + nibble_end = buf_size * 2; + x = 0; + y = 0; + d = bitmap; + for(;;) { + if (nibble_offset >= nibble_end) + return -1; + v = get_nibble(buf, nibble_offset++); + if (v < 0x4) { + v = (v << 4) | get_nibble(buf, nibble_offset++); + if (v < 0x10) { + v = (v << 4) | get_nibble(buf, nibble_offset++); + if (v < 0x040) { + v = (v << 4) | get_nibble(buf, nibble_offset++); + if (v < 4) { + v |= (w - x) << 2; + } + } + } + } + len = v >> 2; + if (len > (w - x)) + len = (w - x); + color = v & 0x03; + memset(d + x, color, len); + x += len; + if (x >= w) { + y++; + if (y >= h) + break; + d += linesize; + x = 0; + /* byte align */ + nibble_offset += (nibble_offset & 1); + } + } + return 0; +} + +static void guess_palette(uint32_t *rgba_palette, + uint8_t *palette, + uint8_t *alpha, + uint32_t subtitle_color) +{ + uint8_t color_used[16]; + int nb_opaque_colors, i, level, j, r, g, b; + + for(i = 0; i < 4; i++) + rgba_palette[i] = 0; + + memset(color_used, 0, 16); + nb_opaque_colors = 0; + for(i = 0; i < 4; i++) { + if (alpha[i] != 0 && !color_used[palette[i]]) { + color_used[palette[i]] = 1; + nb_opaque_colors++; + } + } + + if (nb_opaque_colors == 0) + return; + + j = nb_opaque_colors; + memset(color_used, 0, 16); + for(i = 0; i < 4; i++) { + if (alpha[i] != 0) { + if (!color_used[palette[i]]) { + level = (0xff * j) / nb_opaque_colors; + r = (((subtitle_color >> 16) & 0xff) * level) >> 8; + g = (((subtitle_color >> 8) & 0xff) * level) >> 8; + b = (((subtitle_color >> 0) & 0xff) * level) >> 8; + rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24); + color_used[palette[i]] = (i + 1); + j--; + } else { + rgba_palette[i] = (rgba_palette[color_used[palette[i]] - 1] & 0x00ffffff) | + ((alpha[i] * 17) << 24); + } + } + } +} + +static int decode_dvd_subtitles(AVSubtitle *sub_header, + const uint8_t *buf, int buf_size) +{ + int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos; + uint8_t palette[4], alpha[4]; + int date; + int i; + int is_menu = 0; + + if (buf_size < 4) + return -1; + sub_header->rects = NULL; + sub_header->num_rects = 0; + sub_header->start_display_time = 0; + sub_header->end_display_time = 0; + + cmd_pos = getbe16(buf + 2); + while ((cmd_pos + 4) < buf_size) { + date = getbe16(buf + cmd_pos); + next_cmd_pos = getbe16(buf + cmd_pos + 2); +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "cmd_pos=0x%04x next=0x%04x date=%d\n", + cmd_pos, next_cmd_pos, date); +#endif + pos = cmd_pos + 4; + offset1 = -1; + offset2 = -1; + x1 = y1 = x2 = y2 = 0; + while (pos < buf_size) { + cmd = buf[pos++]; +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "cmd=%02x\n", cmd); +#endif + switch(cmd) { + case 0x00: + /* menu subpicture */ + is_menu = 1; + break; + case 0x01: + /* set start date */ + sub_header->start_display_time = (date << 10) / 90; + break; + case 0x02: + /* set end date */ + sub_header->end_display_time = (date << 10) / 90; + break; + case 0x03: + /* set palette */ + if ((buf_size - pos) < 2) + goto fail; + palette[3] = buf[pos] >> 4; + palette[2] = buf[pos] & 0x0f; + palette[1] = buf[pos + 1] >> 4; + palette[0] = buf[pos + 1] & 0x0f; + pos += 2; + break; + case 0x04: + /* set alpha */ + if ((buf_size - pos) < 2) + goto fail; + alpha[3] = buf[pos] >> 4; + alpha[2] = buf[pos] & 0x0f; + alpha[1] = buf[pos + 1] >> 4; + alpha[0] = buf[pos + 1] & 0x0f; + pos += 2; +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]); +#endif + break; + case 0x05: + if ((buf_size - pos) < 6) + goto fail; + x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4); + x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2]; + y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4); + y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5]; +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "x1=%d x2=%d y1=%d y2=%d\n", + x1, x2, y1, y2); +#endif + pos += 6; + break; + case 0x06: + if ((buf_size - pos) < 4) + goto fail; + offset1 = getbe16(buf + pos); + offset2 = getbe16(buf + pos + 2); +#ifdef DEBUG + av_log(NULL, AV_LOG_INFO, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2); +#endif + pos += 4; + break; + case 0xff: + default: + goto the_end; + } + } + the_end: + if (offset1 >= 0) { + int w, h; + uint8_t *bitmap; + + /* decode the bitmap */ + w = x2 - x1 + 1; + if (w < 0) + w = 0; + h = y2 - y1; + if (h < 0) + h = 0; + if (w > 0 && h > 0) { + if (sub_header->rects != NULL) { + for (i = 0; i < sub_header->num_rects; i++) { + av_free(sub_header->rects[i].bitmap); + av_free(sub_header->rects[i].rgba_palette); + } + av_freep(&sub_header->rects); + sub_header->num_rects = 0; + } + + bitmap = av_malloc(w * h); + sub_header->rects = av_mallocz(sizeof(AVSubtitleRect)); + sub_header->num_rects = 1; + sub_header->rects[0].rgba_palette = av_malloc(4 * 4); + decode_rle(bitmap, w * 2, w, h / 2, + buf, offset1 * 2, buf_size); + decode_rle(bitmap + w, w * 2, w, h / 2, + buf, offset2 * 2, buf_size); + guess_palette(sub_header->rects[0].rgba_palette, + palette, alpha, 0xffff00); + sub_header->rects[0].x = x1; + sub_header->rects[0].y = y1; + sub_header->rects[0].w = w; + sub_header->rects[0].h = h; + sub_header->rects[0].nb_colors = 4; + sub_header->rects[0].linesize = w; + sub_header->rects[0].bitmap = bitmap; + } + } + if (next_cmd_pos == cmd_pos) + break; + cmd_pos = next_cmd_pos; + } + if (sub_header->num_rects > 0) + return is_menu; + fail: + return -1; +} + +static int is_transp(const uint8_t *buf, int pitch, int n, + const uint8_t *transp_color) +{ + int i; + for(i = 0; i < n; i++) { + if (!transp_color[*buf]) + return 0; + buf += pitch; + } + return 1; +} + +/* return 0 if empty rectangle, 1 if non empty */ +static int find_smallest_bounding_rectangle(AVSubtitle *s) +{ + uint8_t transp_color[256]; + int y1, y2, x1, x2, y, w, h, i; + uint8_t *bitmap; + + if (s->num_rects == 0 || s->rects == NULL || s->rects[0].w <= 0 || s->rects[0].h <= 0) + return 0; + + memset(transp_color, 0, 256); + for(i = 0; i < s->rects[0].nb_colors; i++) { + if ((s->rects[0].rgba_palette[i] >> 24) == 0) + transp_color[i] = 1; + } + y1 = 0; + while (y1 < s->rects[0].h && is_transp(s->rects[0].bitmap + y1 * s->rects[0].linesize, + 1, s->rects[0].w, transp_color)) + y1++; + if (y1 == s->rects[0].h) { + av_freep(&s->rects[0].bitmap); + s->rects[0].w = s->rects[0].h = 0; + return 0; + } + + y2 = s->rects[0].h - 1; + while (y2 > 0 && is_transp(s->rects[0].bitmap + y2 * s->rects[0].linesize, 1, + s->rects[0].w, transp_color)) + y2--; + x1 = 0; + while (x1 < (s->rects[0].w - 1) && is_transp(s->rects[0].bitmap + x1, s->rects[0].linesize, + s->rects[0].h, transp_color)) + x1++; + x2 = s->rects[0].w - 1; + while (x2 > 0 && is_transp(s->rects[0].bitmap + x2, s->rects[0].linesize, s->rects[0].h, + transp_color)) + x2--; + w = x2 - x1 + 1; + h = y2 - y1 + 1; + bitmap = av_malloc(w * h); + if (!bitmap) + return 1; + for(y = 0; y < h; y++) { + memcpy(bitmap + w * y, s->rects[0].bitmap + x1 + (y1 + y) * s->rects[0].linesize, w); + } + av_freep(&s->rects[0].bitmap); + s->rects[0].bitmap = bitmap; + s->rects[0].linesize = w; + s->rects[0].w = w; + s->rects[0].h = h; + s->rects[0].x += x1; + s->rects[0].y += y1; + return 1; +} + +static int dvdsub_close_decoder(AVCodecContext *avctx) +{ + return 0; +} + +#ifdef DEBUG +#undef fprintf +static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h, + uint32_t *rgba_palette) +{ + int x, y, v; + FILE *f; + + f = fopen(filename, "w"); + if (!f) { + perror(filename); + exit(1); + } + fprintf(f, "P6\n" + "%d %d\n" + "%d\n", + w, h, 255); + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = rgba_palette[bitmap[y * w + x]]; + putc((v >> 16) & 0xff, f); + putc((v >> 8) & 0xff, f); + putc((v >> 0) & 0xff, f); + } + } + fclose(f); +} +#endif + +static int dvdsub_decode(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + AVSubtitle *sub = (void *)data; + int is_menu; + + is_menu = decode_dvd_subtitles(sub, buf, buf_size); + + if (is_menu < 0) { + no_subtitle: + *data_size = 0; + + return buf_size; + } + if (!is_menu && find_smallest_bounding_rectangle(sub) == 0) + goto no_subtitle; + +#if defined(DEBUG) + av_log(NULL, AV_LOG_INFO, "start=%d ms end =%d ms\n", + sub->start_display_time, + sub->end_display_time); + ppm_save("/tmp/a.ppm", sub->rects[0].bitmap, + sub->rects[0].w, sub->rects[0].h, sub->rects[0].rgba_palette); +#endif + + *data_size = 1; + return buf_size; +} + +AVCodec dvdsub_decoder = { + "dvdsub", + CODEC_TYPE_SUBTITLE, + CODEC_ID_DVD_SUBTITLE, + sizeof(DVDSubContext), + dvdsub_init_decoder, + NULL, + dvdsub_close_decoder, + dvdsub_decode, +}; + +/* parser definition */ +typedef struct DVDSubParseContext { + uint8_t *packet; + int packet_len; + int packet_index; +} DVDSubParseContext; + +static int dvdsub_parse_init(AVCodecParserContext *s) +{ + return 0; +} + +static int dvdsub_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + DVDSubParseContext *pc = s->priv_data; + + if (pc->packet_index == 0) { + if (buf_size < 2) + return 0; + pc->packet_len = (buf[0] << 8) | buf[1]; + av_freep(&pc->packet); + pc->packet = av_malloc(pc->packet_len); + } + if (pc->packet) { + if (pc->packet_index + buf_size <= pc->packet_len) { + memcpy(pc->packet + pc->packet_index, buf, buf_size); + pc->packet_index += buf_size; + if (pc->packet_index >= pc->packet_len) { + *poutbuf = pc->packet; + *poutbuf_size = pc->packet_len; + pc->packet_index = 0; + return buf_size; + } + } else { + /* erroneous size */ + pc->packet_index = 0; + } + } + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; +} + +static void dvdsub_parse_close(AVCodecParserContext *s) +{ + DVDSubParseContext *pc = s->priv_data; + av_freep(&pc->packet); +} + +AVCodecParser dvdsub_parser = { + { CODEC_ID_DVD_SUBTITLE }, + sizeof(DVDSubParseContext), + dvdsub_parse_init, + dvdsub_parse, + dvdsub_parse_close, +}; diff --git a/mpeg4/src/libavcodec/dvdsubenc.c b/mpeg4/src/libavcodec/dvdsubenc.c new file mode 100644 index 00000000..1d423af5 --- /dev/null +++ b/mpeg4/src/libavcodec/dvdsubenc.c @@ -0,0 +1,248 @@ +/* + * DVD subtitle encoding for ffmpeg + * Copyright (c) 2005 Wolfram Gloger. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avcodec.h" + +#undef NDEBUG +#include + +typedef struct DVDSubtitleContext { +} DVDSubtitleContext; + +// ncnt is the nibble counter +#define PUTNIBBLE(val)\ +do {\ + if (ncnt++ & 1)\ + *q++ = bitbuf | ((val) & 0x0f);\ + else\ + bitbuf = (val) << 4;\ +} while(0) + +static void dvd_encode_rle(uint8_t **pq, + const uint8_t *bitmap, int linesize, + int w, int h, + const int cmap[256]) +{ + uint8_t *q; + unsigned int bitbuf = 0; + int ncnt; + int x, y, len, color; + + q = *pq; + + for (y = 0; y < h; ++y) { + ncnt = 0; + for(x = 0; x < w; x += len) { + color = bitmap[x]; + for (len=1; x+len < w; ++len) + if (bitmap[x+len] != color) + break; + color = cmap[color]; + assert(color < 4); + if (len < 0x04) { + PUTNIBBLE((len << 2)|color); + } else if (len < 0x10) { + PUTNIBBLE(len >> 2); + PUTNIBBLE((len << 2)|color); + } else if (len < 0x40) { + PUTNIBBLE(0); + PUTNIBBLE(len >> 2); + PUTNIBBLE((len << 2)|color); + } else if (x+len == w) { + PUTNIBBLE(0); + PUTNIBBLE(0); + PUTNIBBLE(0); + PUTNIBBLE(color); + } else { + if (len > 0xff) + len = 0xff; + PUTNIBBLE(0); + PUTNIBBLE(len >> 6); + PUTNIBBLE(len >> 2); + PUTNIBBLE((len << 2)|color); + } + } + /* end of line */ + if (ncnt & 1) + PUTNIBBLE(0); + bitmap += linesize; + } + + *pq = q; +} + +static inline void putbe16(uint8_t **pq, uint16_t v) +{ + uint8_t *q = *pq; + *q++ = v >> 8; + *q++ = v; + *pq = q; +} + +static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size, + const AVSubtitle *h) +{ + uint8_t *q, *qq; + int object_id; + int offset1[20], offset2[20]; + int i, imax, color, alpha, rects = h->num_rects; + unsigned long hmax; + unsigned long hist[256]; + int cmap[256]; + + if (rects == 0 || h->rects == NULL) + return -1; + if (rects > 20) + rects = 20; + + // analyze bitmaps, compress to 4 colors + for (i=0; i<256; ++i) { + hist[i] = 0; + cmap[i] = 0; + } + for (object_id = 0; object_id < rects; object_id++) + for (i=0; irects[object_id].w*h->rects[object_id].h; ++i) { + color = h->rects[object_id].bitmap[i]; + // only count non-transparent pixels + alpha = h->rects[object_id].rgba_palette[color] >> 24; + hist[color] += alpha; + } + for (color=3;; --color) { + hmax = 0; + imax = 0; + for (i=0; i<256; ++i) + if (hist[i] > hmax) { + imax = i; + hmax = hist[i]; + } + if (hmax == 0) + break; + if (color == 0) + color = 3; + av_log(NULL, AV_LOG_DEBUG, "dvd_subtitle hist[%d]=%ld -> col %d\n", + imax, hist[imax], color); + cmap[imax] = color; + hist[imax] = 0; + } + + + // encode data block + q = outbuf + 4; + for (object_id = 0; object_id < rects; object_id++) { + offset1[object_id] = q - outbuf; + // worst case memory requirement: 1 nibble per pixel.. + if ((q - outbuf) + h->rects[object_id].w*h->rects[object_id].h/2 + + 17*rects + 21 > outbuf_size) { + av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n"); + return -1; + } + dvd_encode_rle(&q, h->rects[object_id].bitmap, + h->rects[object_id].w*2, + h->rects[object_id].w, h->rects[object_id].h >> 1, + cmap); + offset2[object_id] = q - outbuf; + dvd_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w, + h->rects[object_id].w*2, + h->rects[object_id].w, h->rects[object_id].h >> 1, + cmap); + } + + // set data packet size + qq = outbuf + 2; + putbe16(&qq, q - outbuf); + + // send start display command + putbe16(&q, (h->start_display_time*90) >> 10); + putbe16(&q, (q - outbuf) /*- 2 */ + 8 + 12*rects + 2); + *q++ = 0x03; // palette - 4 nibbles + *q++ = 0x03; *q++ = 0x7f; + *q++ = 0x04; // alpha - 4 nibbles + *q++ = 0xf0; *q++ = 0x00; + //*q++ = 0x0f; *q++ = 0xff; + + // XXX not sure if more than one rect can really be encoded.. + // 12 bytes per rect + for (object_id = 0; object_id < rects; object_id++) { + int x2 = h->rects[object_id].x + h->rects[object_id].w - 1; + int y2 = h->rects[object_id].y + h->rects[object_id].h - 1; + + *q++ = 0x05; + // x1 x2 -> 6 nibbles + *q++ = h->rects[object_id].x >> 4; + *q++ = (h->rects[object_id].x << 4) | ((x2 >> 8) & 0xf); + *q++ = x2; + // y1 y2 -> 6 nibbles + *q++ = h->rects[object_id].y >> 4; + *q++ = (h->rects[object_id].y << 4) | ((y2 >> 8) & 0xf); + *q++ = y2; + + *q++ = 0x06; + // offset1, offset2 + putbe16(&q, offset1[object_id]); + putbe16(&q, offset2[object_id]); + } + *q++ = 0x01; // start command + *q++ = 0xff; // terminating command + + // send stop display command last + putbe16(&q, (h->end_display_time*90) >> 10); + putbe16(&q, (q - outbuf) - 2 /*+ 4*/); + *q++ = 0x02; // set end + *q++ = 0xff; // terminating command + + qq = outbuf; + putbe16(&qq, q - outbuf); + + av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - outbuf); + return q - outbuf; +} + +static int dvdsub_init_encoder(AVCodecContext *avctx) +{ + return 0; +} + +static int dvdsub_close_encoder(AVCodecContext *avctx) +{ + return 0; +} + +static int dvdsub_encode(AVCodecContext *avctx, + unsigned char *buf, int buf_size, void *data) +{ + //DVDSubtitleContext *s = avctx->priv_data; + AVSubtitle *sub = data; + int ret; + + ret = encode_dvd_subtitles(buf, buf_size, sub); + return ret; +} + +AVCodec dvdsub_encoder = { + "dvdsub", + CODEC_TYPE_SUBTITLE, + CODEC_ID_DVD_SUBTITLE, + sizeof(DVDSubtitleContext), + dvdsub_init_encoder, + dvdsub_encode, + dvdsub_close_encoder, +}; + +/* Local Variables: */ +/* c-basic-offset:4 */ +/* End: */ diff --git a/mpeg4/src/libavcodec/error_resilience.c b/mpeg4/src/libavcodec/error_resilience.c new file mode 100644 index 00000000..9912044e --- /dev/null +++ b/mpeg4/src/libavcodec/error_resilience.c @@ -0,0 +1,1028 @@ +/* + * Error resilience / concealment + * + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file error_resilience.c + * Error resilience / concealment. + */ + +#include + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" +#include "common.h" + +static void decode_mb(MpegEncContext *s){ + s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16; + s->dest[1] = s->current_picture.data[1] + (s->mb_y * 8 * s->uvlinesize) + s->mb_x * 8; + s->dest[2] = s->current_picture.data[2] + (s->mb_y * 8 * s->uvlinesize) + s->mb_x * 8; + + MPV_decode_mb(s, s->block); +} + +/** + * replaces the current MB with a flat dc only version. + */ +static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y) +{ + int dc, dcu, dcv, y, i; + for(i=0; i<4; i++){ + dc= s->dc_val[0][mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride]; + if(dc<0) dc=0; + else if(dc>2040) dc=2040; + for(y=0; y<8; y++){ + int x; + for(x=0; x<8; x++){ + dest_y[x + (i&1)*8 + (y + (i>>1)*8)*s->linesize]= dc/8; + } + } + } + dcu = s->dc_val[1][mb_x + mb_y*s->mb_stride]; + dcv = s->dc_val[2][mb_x + mb_y*s->mb_stride]; + if (dcu<0 ) dcu=0; + else if(dcu>2040) dcu=2040; + if (dcv<0 ) dcv=0; + else if(dcv>2040) dcv=2040; + for(y=0; y<8; y++){ + int x; + for(x=0; x<8; x++){ + dest_cb[x + y*(s->uvlinesize)]= dcu/8; + dest_cr[x + y*(s->uvlinesize)]= dcv/8; + } + } +} + +static void filter181(int16_t *data, int width, int height, int stride){ + int x,y; + + /* horizontal filter */ + for(y=1; y>16; + prev_dc= data[x + y*stride]; + data[x + y*stride]= dc; + } + } + + /* vertical filter */ + for(x=1; x>16; + prev_dc= data[x + y*stride]; + data[x + y*stride]= dc; + } + } +} + +/** + * guess the dc of blocks which dont have a undamaged dc + * @param w width in 8 pixel blocks + * @param h height in 8 pixel blocks + */ +static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){ + int b_x, b_y; + + for(b_y=0; b_y>is_luma) + (b_y>>is_luma)*s->mb_stride; + + error= s->error_status_table[mb_index]; + + if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter + if(!(error&DC_ERROR)) continue; //dc-ok + + /* right block */ + for(j=b_x+1; j>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&DC_ERROR)){ + color[0]= dc[j + b_y*stride]; + distance[0]= j-b_x; + break; + } + } + + /* left block */ + for(j=b_x-1; j>=0; j--){ + int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&DC_ERROR)){ + color[1]= dc[j + b_y*stride]; + distance[1]= b_x-j; + break; + } + } + + /* bottom block */ + for(j=b_y+1; j>is_luma) + (j>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&DC_ERROR)){ + color[2]= dc[b_x + j*stride]; + distance[2]= j-b_y; + break; + } + } + + /* top block */ + for(j=b_y-1; j>=0; j--){ + int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride; + int error_j= s->error_status_table[mb_index_j]; + int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]); + if(intra_j==0 || !(error_j&DC_ERROR)){ + color[3]= dc[b_x + j*stride]; + distance[3]= b_y-j; + break; + } + } + + weight_sum=0; + guess=0; + for(j=0; j<4; j++){ + int64_t weight= 256*256*256*16/distance[j]; + guess+= weight*(int64_t)color[j]; + weight_sum+= weight; + } + guess= (guess + weight_sum/2) / weight_sum; + + dc[b_x + b_y*stride]= guess; + } + } +} + +/** + * simple horizontal deblocking filter used for error resilience + * @param w width in 8 pixel blocks + * @param h height in 8 pixel blocks + */ +static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){ + int b_x, b_y; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + for(b_y=0; b_yerror_status_table[( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride]; + int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]; + int left_intra= IS_INTRA(s->current_picture.mb_type [( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride]); + int right_intra= IS_INTRA(s->current_picture.mb_type [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]); + int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR); + int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR); + int offset= b_x*8 + b_y*stride*8; + int16_t *left_mv= s->current_picture.motion_val[0][s->b8_stride*(b_y<<(1-is_luma)) + ( b_x <<(1-is_luma))]; + int16_t *right_mv= s->current_picture.motion_val[0][s->b8_stride*(b_y<<(1-is_luma)) + ((b_x+1)<<(1-is_luma))]; + + if(!(left_damage||right_damage)) continue; // both undamaged + + if( (!left_intra) && (!right_intra) + && ABS(left_mv[0]-right_mv[0]) + ABS(left_mv[1]+right_mv[1]) < 2) continue; + + for(y=0; y<8; y++){ + int a,b,c,d; + + a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride]; + b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride]; + c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride]; + + d= ABS(b) - ((ABS(a) + ABS(c) + 1)>>1); + d= FFMAX(d, 0); + if(b<0) d= -d; + + if(d==0) continue; + + if(!(left_damage && right_damage)) + d= d*16/9; + + if(left_damage){ + dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)]; + dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)]; + dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)]; + dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)]; + } + if(right_damage){ + dst[offset + 8 + y*stride] = cm[dst[offset + 8 + y*stride] - ((d*7)>>4)]; + dst[offset + 9 + y*stride] = cm[dst[offset + 9 + y*stride] - ((d*5)>>4)]; + dst[offset + 10+ y*stride] = cm[dst[offset +10 + y*stride] - ((d*3)>>4)]; + dst[offset + 11+ y*stride] = cm[dst[offset +11 + y*stride] - ((d*1)>>4)]; + } + } + } + } +} + +/** + * simple vertical deblocking filter used for error resilience + * @param w width in 8 pixel blocks + * @param h height in 8 pixel blocks + */ +static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){ + int b_x, b_y; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + for(b_y=0; b_yerror_status_table[(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride]; + int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]; + int top_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride]); + int bottom_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]); + int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR); + int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR); + int offset= b_x*8 + b_y*stride*8; + int16_t *top_mv= s->current_picture.motion_val[0][s->b8_stride*( b_y <<(1-is_luma)) + (b_x<<(1-is_luma))]; + int16_t *bottom_mv= s->current_picture.motion_val[0][s->b8_stride*((b_y+1)<<(1-is_luma)) + (b_x<<(1-is_luma))]; + + if(!(top_damage||bottom_damage)) continue; // both undamaged + + if( (!top_intra) && (!bottom_intra) + && ABS(top_mv[0]-bottom_mv[0]) + ABS(top_mv[1]+bottom_mv[1]) < 2) continue; + + for(x=0; x<8; x++){ + int a,b,c,d; + + a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride]; + b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride]; + c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride]; + + d= ABS(b) - ((ABS(a) + ABS(c)+1)>>1); + d= FFMAX(d, 0); + if(b<0) d= -d; + + if(d==0) continue; + + if(!(top_damage && bottom_damage)) + d= d*16/9; + + if(top_damage){ + dst[offset + x + 7*stride] = cm[dst[offset + x + 7*stride] + ((d*7)>>4)]; + dst[offset + x + 6*stride] = cm[dst[offset + x + 6*stride] + ((d*5)>>4)]; + dst[offset + x + 5*stride] = cm[dst[offset + x + 5*stride] + ((d*3)>>4)]; + dst[offset + x + 4*stride] = cm[dst[offset + x + 4*stride] + ((d*1)>>4)]; + } + if(bottom_damage){ + dst[offset + x + 8*stride] = cm[dst[offset + x + 8*stride] - ((d*7)>>4)]; + dst[offset + x + 9*stride] = cm[dst[offset + x + 9*stride] - ((d*5)>>4)]; + dst[offset + x + 10*stride] = cm[dst[offset + x + 10*stride] - ((d*3)>>4)]; + dst[offset + x + 11*stride] = cm[dst[offset + x + 11*stride] - ((d*1)>>4)]; + } + } + } + } +} + +static void guess_mv(MpegEncContext *s){ + uint8_t fixed[s->mb_stride * s->mb_height]; +#define MV_FROZEN 3 +#define MV_CHANGED 2 +#define MV_UNCHANGED 1 + const int mb_stride = s->mb_stride; + const int mb_width = s->mb_width; + const int mb_height= s->mb_height; + int i, depth, num_avail; + int mb_x, mb_y; + + num_avail=0; + for(i=0; imb_num; i++){ + const int mb_xy= s->mb_index2xy[ i ]; + int f=0; + int error= s->error_status_table[mb_xy]; + + if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check + if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV + + fixed[mb_xy]= f; + if(f==MV_FROZEN) + num_avail++; + } + + if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){ + for(mb_y=0; mb_ymb_height; mb_y++){ + for(mb_x=0; mb_xmb_width; mb_x++){ + const int mb_xy= mb_x + mb_y*s->mb_stride; + + if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue; + if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue; + + s->mv_dir = MV_DIR_FORWARD; + s->mb_intra=0; + s->mv_type = MV_TYPE_16X16; + s->mb_skipped=0; + + s->dsp.clear_blocks(s->block[0]); + + s->mb_x= mb_x; + s->mb_y= mb_y; + s->mv[0][0][0]= 0; + s->mv[0][0][1]= 0; + decode_mb(s); + } + } + return; + } + + for(depth=0;; depth++){ + int changed, pass, none_left; + + none_left=1; + changed=1; + for(pass=0; (changed || pass<2) && pass<10; pass++){ + int mb_x, mb_y; +int score_sum=0; + + changed=0; + for(mb_y=0; mb_ymb_height; mb_y++){ + for(mb_x=0; mb_xmb_width; mb_x++){ + const int mb_xy= mb_x + mb_y*s->mb_stride; + int mv_predictor[8][2]={{0}}; + int pred_count=0; + int j; + int best_score=256*256*256*64; + int best_pred=0; + const int mot_stride= s->b8_stride; + const int mot_index= mb_x*2 + mb_y*2*mot_stride; + int prev_x= s->current_picture.motion_val[0][mot_index][0]; + int prev_y= s->current_picture.motion_val[0][mot_index][1]; + + if((mb_x^mb_y^pass)&1) continue; + + if(fixed[mb_xy]==MV_FROZEN) continue; + assert(!IS_INTRA(s->current_picture.mb_type[mb_xy])); + assert(s->last_picture_ptr && s->last_picture_ptr->data[0]); + + j=0; + if(mb_x>0 && fixed[mb_xy-1 ]==MV_FROZEN) j=1; + if(mb_x+10 && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1; + if(mb_y+10 && fixed[mb_xy-1 ]==MV_CHANGED) j=1; + if(mb_x+10 && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1; + if(mb_y+11) continue; + + none_left=0; + + if(mb_x>0 && fixed[mb_xy-1]){ + mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - 2][0]; + mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - 2][1]; + pred_count++; + } + if(mb_x+1current_picture.motion_val[0][mot_index + 2][0]; + mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + 2][1]; + pred_count++; + } + if(mb_y>0 && fixed[mb_xy-mb_stride]){ + mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*2][0]; + mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*2][1]; + pred_count++; + } + if(mb_y+1current_picture.motion_val[0][mot_index + mot_stride*2][0]; + mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*2][1]; + pred_count++; + } + if(pred_count==0) continue; + + if(pred_count>1){ + int sum_x=0, sum_y=0; + int max_x, max_y, min_x, min_y; + + for(j=0; j=3){ + min_y= min_x= 99999; + max_y= max_x=-99999; + }else{ + min_x=min_y=max_x=max_y=0; + } + for(j=0; jcurrent_picture.motion_val[0][mot_index][0]; + mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1]; + pred_count++; + + s->mv_dir = MV_DIR_FORWARD; + s->mb_intra=0; + s->mv_type = MV_TYPE_16X16; + s->mb_skipped=0; + + s->dsp.clear_blocks(s->block[0]); + + s->mb_x= mb_x; + s->mb_y= mb_y; + + for(j=0; jcurrent_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; + + s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0]; + s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1]; + + decode_mb(s); + + if(mb_x>0 && fixed[mb_xy-1]){ + int k; + for(k=0; k<16; k++) + score += ABS(src[k*s->linesize-1 ]-src[k*s->linesize ]); + } + if(mb_x+1linesize+15]-src[k*s->linesize+16]); + } + if(mb_y>0 && fixed[mb_xy-mb_stride]){ + int k; + for(k=0; k<16; k++) + score += ABS(src[k-s->linesize ]-src[k ]); + } + if(mb_y+1linesize*15]-src[k+s->linesize*16]); + } + + if(score <= best_score){ // <= will favor the last MV + best_score= score; + best_pred= j; + } + } +score_sum+= best_score; +//FIXME no need to set s->current_picture.motion_val[0][mot_index][0] explicit + s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[best_pred][0]; + s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[best_pred][1]; + + decode_mb(s); + + + if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){ + fixed[mb_xy]=MV_CHANGED; + changed++; + }else + fixed[mb_xy]=MV_UNCHANGED; + } + } + +// printf(".%d/%d", changed, score_sum); fflush(stdout); + } + + if(none_left) + return; + + for(i=0; imb_num; i++){ + int mb_xy= s->mb_index2xy[i]; + if(fixed[mb_xy]) + fixed[mb_xy]=MV_FROZEN; + } +// printf(":"); fflush(stdout); + } +} + +static int is_intra_more_likely(MpegEncContext *s){ + int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y; + + if(s->last_picture_ptr==NULL) return 1; //no previous frame available -> use spatial prediction + + undamaged_count=0; + for(i=0; imb_num; i++){ + const int mb_xy= s->mb_index2xy[i]; + const int error= s->error_status_table[mb_xy]; + if(!((error&DC_ERROR) && (error&MV_ERROR))) + undamaged_count++; + } + + if(undamaged_count < 5) return 0; //allmost all MBs damaged -> use temporal prediction + + skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs + is_intra_likely=0; + + j=0; + for(mb_y= 0; mb_ymb_height-1; mb_y++){ + for(mb_x= 0; mb_xmb_width; mb_x++){ + int error; + const int mb_xy= mb_x + mb_y*s->mb_stride; + + error= s->error_status_table[mb_xy]; + if((error&DC_ERROR) && (error&MV_ERROR)) + continue; //skip damaged + + j++; + if((j%skip_amount) != 0) continue; //skip a few to speed things up + + if(s->pict_type==I_TYPE){ + uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; + uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize; + + is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16); + is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16); + }else{ + if(IS_INTRA(s->current_picture.mb_type[mb_xy])) + is_intra_likely++; + else + is_intra_likely--; + } + } + } +//printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type); + return is_intra_likely > 0; +} + +void ff_er_frame_start(MpegEncContext *s){ + if(!s->error_resilience) return; + + memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_stride*s->mb_height*sizeof(uint8_t)); + s->error_count= 3*s->mb_num; +} + +/** + * adds a slice. + * @param endx x component of the last macroblock, can be -1 for the last of the previous line + * @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or + * error of the same type occured + */ +void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){ + const int start_i= clip(startx + starty * s->mb_width , 0, s->mb_num-1); + const int end_i = clip(endx + endy * s->mb_width , 0, s->mb_num); + const int start_xy= s->mb_index2xy[start_i]; + const int end_xy = s->mb_index2xy[end_i]; + int mask= -1; + + if(!s->error_resilience) return; + + mask &= ~VP_START; + if(status & (AC_ERROR|AC_END)){ + mask &= ~(AC_ERROR|AC_END); + s->error_count -= end_i - start_i + 1; + } + if(status & (DC_ERROR|DC_END)){ + mask &= ~(DC_ERROR|DC_END); + s->error_count -= end_i - start_i + 1; + } + if(status & (MV_ERROR|MV_END)){ + mask &= ~(MV_ERROR|MV_END); + s->error_count -= end_i - start_i + 1; + } + + if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) s->error_count= INT_MAX; + + if(mask == ~0x7F){ + memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t)); + }else{ + int i; + for(i=start_xy; ierror_status_table[ i ] &= mask; + } + } + + if(end_i == s->mb_num) + s->error_count= INT_MAX; + else{ + s->error_status_table[end_xy] &= mask; + s->error_status_table[end_xy] |= status; + } + + s->error_status_table[start_xy] |= VP_START; + + if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){ + int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ]; + + prev_status &= ~ VP_START; + if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX; + } +} + +void ff_er_frame_end(MpegEncContext *s){ + int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error; + int distance; + int threshold_part[4]= {100,100,100}; + int threshold= 50; + int is_intra_likely; + int size = s->b8_stride * 2 * s->mb_height; + Picture *pic= s->current_picture_ptr; + + if(!s->error_resilience || s->error_count==0 || + s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return; + + if(s->current_picture.motion_val[0] == NULL){ + av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n"); + + for(i=0; i<2; i++){ + pic->ref_index[i]= av_mallocz(size * sizeof(uint8_t)); + pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t)); + pic->motion_val[i]= pic->motion_val_base[i]+4; + } + pic->motion_subsample_log2= 3; + s->current_picture= *s->current_picture_ptr; + } + + for(i=0; i<2; i++){ + if(pic->ref_index[i]) + memset(pic->ref_index[i], 0, size * sizeof(uint8_t)); + } + + if(s->avctx->debug&FF_DEBUG_ER){ + for(mb_y=0; mb_ymb_height; mb_y++){ + for(mb_x=0; mb_xmb_width; mb_x++){ + int status= s->error_status_table[mb_x + mb_y*s->mb_stride]; + + av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status); + } + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + } + +#if 1 + /* handle overlapping slices */ + for(error_type=1; error_type<=3; error_type++){ + int end_ok=0; + + for(i=s->mb_num-1; i>=0; i--){ + const int mb_xy= s->mb_index2xy[i]; + int error= s->error_status_table[mb_xy]; + + if(error&(1<error_status_table[mb_xy]|= 1<partitioned_frame){ + int end_ok=0; + + for(i=s->mb_num-1; i>=0; i--){ + const int mb_xy= s->mb_index2xy[i]; + int error= s->error_status_table[mb_xy]; + + if(error&AC_END) + end_ok=0; + if((error&MV_END) || (error&DC_END) || (error&AC_ERROR)) + end_ok=1; + + if(!end_ok) + s->error_status_table[mb_xy]|= AC_ERROR; + + if(error&VP_START) + end_ok=0; + } + } +#endif + /* handle missing slices */ + if(s->error_resilience>=4){ + int end_ok=1; + + for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack + const int mb_xy= s->mb_index2xy[i]; + int error1= s->error_status_table[mb_xy ]; + int error2= s->error_status_table[s->mb_index2xy[i+1]]; + + if(error1&VP_START) + end_ok=1; + + if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END) + && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END) + && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninited + end_ok=0; + } + + if(!end_ok) + s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR; + } + } + +#if 1 + /* backward mark errors */ + distance=9999999; + for(error_type=1; error_type<=3; error_type++){ + for(i=s->mb_num-1; i>=0; i--){ + const int mb_xy= s->mb_index2xy[i]; + int error= s->error_status_table[mb_xy]; + + if(!s->mbskip_table[mb_xy]) //FIXME partition specific + distance++; + if(error&(1<partitioned_frame){ + if(distance < threshold_part[error_type-1]) + s->error_status_table[mb_xy]|= 1<error_status_table[mb_xy]|= 1<mb_num; i++){ + const int mb_xy= s->mb_index2xy[i]; + int old_error= s->error_status_table[mb_xy]; + + if(old_error&VP_START) + error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR); + else{ + error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR); + s->error_status_table[mb_xy]|= error; + } + } +#if 1 + /* handle not partitioned case */ + if(!s->partitioned_frame){ + for(i=0; imb_num; i++){ + const int mb_xy= s->mb_index2xy[i]; + error= s->error_status_table[mb_xy]; + if(error&(AC_ERROR|DC_ERROR|MV_ERROR)) + error|= AC_ERROR|DC_ERROR|MV_ERROR; + s->error_status_table[mb_xy]= error; + } + } +#endif + + dc_error= ac_error= mv_error=0; + for(i=0; imb_num; i++){ + const int mb_xy= s->mb_index2xy[i]; + error= s->error_status_table[mb_xy]; + if(error&DC_ERROR) dc_error ++; + if(error&AC_ERROR) ac_error ++; + if(error&MV_ERROR) mv_error ++; + } + av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error); + + is_intra_likely= is_intra_more_likely(s); + + /* set unknown mb-type to most likely */ + for(i=0; imb_num; i++){ + const int mb_xy= s->mb_index2xy[i]; + error= s->error_status_table[mb_xy]; + if(!((error&DC_ERROR) && (error&MV_ERROR))) + continue; + + if(is_intra_likely) + s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4; + else + s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0; + } + + /* handle inter blocks with damaged AC */ + for(mb_y=0; mb_ymb_height; mb_y++){ + for(mb_x=0; mb_xmb_width; mb_x++){ + const int mb_xy= mb_x + mb_y * s->mb_stride; + const int mb_type= s->current_picture.mb_type[mb_xy]; + error= s->error_status_table[mb_xy]; + + if(IS_INTRA(mb_type)) continue; //intra + if(error&MV_ERROR) continue; //inter with damaged MV + if(!(error&AC_ERROR)) continue; //undamaged inter + + s->mv_dir = MV_DIR_FORWARD; + s->mb_intra=0; + s->mb_skipped=0; + if(IS_8X8(mb_type)){ + int mb_index= mb_x*2 + mb_y*2*s->b8_stride; + int j; + s->mv_type = MV_TYPE_8X8; + for(j=0; j<4; j++){ + s->mv[0][j][0] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0]; + s->mv[0][j][1] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1]; + } + }else{ + s->mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][0]; + s->mv[0][0][1] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][1]; + } + + s->dsp.clear_blocks(s->block[0]); + + s->mb_x= mb_x; + s->mb_y= mb_y; + decode_mb(s); + } + } + + /* guess MVs */ + if(s->pict_type==B_TYPE){ + for(mb_y=0; mb_ymb_height; mb_y++){ + for(mb_x=0; mb_xmb_width; mb_x++){ + int xy= mb_x*2 + mb_y*2*s->b8_stride; + const int mb_xy= mb_x + mb_y * s->mb_stride; + const int mb_type= s->current_picture.mb_type[mb_xy]; + error= s->error_status_table[mb_xy]; + + if(IS_INTRA(mb_type)) continue; + if(!(error&MV_ERROR)) continue; //inter with undamaged MV + if(!(error&AC_ERROR)) continue; //undamaged inter + + s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD; + s->mb_intra=0; + s->mv_type = MV_TYPE_16X16; + s->mb_skipped=0; + + if(s->pp_time){ + int time_pp= s->pp_time; + int time_pb= s->pb_time; + + s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp; + s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp; + s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp; + s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp; + }else{ + s->mv[0][0][0]= 0; + s->mv[0][0][1]= 0; + s->mv[1][0][0]= 0; + s->mv[1][0][1]= 0; + } + + s->dsp.clear_blocks(s->block[0]); + s->mb_x= mb_x; + s->mb_y= mb_y; + decode_mb(s); + } + } + }else + guess_mv(s); + +#ifdef HAVE_XVMC + /* the filters below are not XvMC compatible, skip them */ + if(s->avctx->xvmc_acceleration) goto ec_clean; +#endif + /* fill DC for inter blocks */ + for(mb_y=0; mb_ymb_height; mb_y++){ + for(mb_x=0; mb_xmb_width; mb_x++){ + int dc, dcu, dcv, y, n; + int16_t *dc_ptr; + uint8_t *dest_y, *dest_cb, *dest_cr; + const int mb_xy= mb_x + mb_y * s->mb_stride; + const int mb_type= s->current_picture.mb_type[mb_xy]; + + error= s->error_status_table[mb_xy]; + + if(IS_INTRA(mb_type) && s->partitioned_frame) continue; +// if(error&MV_ERROR) continue; //inter data damaged FIXME is this good? + + dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; + dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize; + dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize; + + dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride]; + for(n=0; n<4; n++){ + dc=0; + for(y=0; y<8; y++){ + int x; + for(x=0; x<8; x++){ + dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize]; + } + } + dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3; + } + + dcu=dcv=0; + for(y=0; y<8; y++){ + int x; + for(x=0; x<8; x++){ + dcu+=dest_cb[x + y*(s->uvlinesize)]; + dcv+=dest_cr[x + y*(s->uvlinesize)]; + } + } + s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3; + s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3; + } + } +#if 1 + /* guess DC for damaged blocks */ + guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1); + guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0); + guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0); +#endif + /* filter luma DC */ + filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride); + +#if 1 + /* render DC only intra */ + for(mb_y=0; mb_ymb_height; mb_y++){ + for(mb_x=0; mb_xmb_width; mb_x++){ + uint8_t *dest_y, *dest_cb, *dest_cr; + const int mb_xy= mb_x + mb_y * s->mb_stride; + const int mb_type= s->current_picture.mb_type[mb_xy]; + + error= s->error_status_table[mb_xy]; + + if(IS_INTER(mb_type)) continue; + if(!(error&AC_ERROR)) continue; //undamaged + + dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; + dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize; + dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize; + + put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y); + } + } +#endif + + if(s->avctx->error_concealment&FF_EC_DEBLOCK){ + /* filter horizontal block boundaries */ + h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); + h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0); + h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0); + + /* filter vertical block boundaries */ + v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); + v_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0); + v_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0); + } + +#ifdef HAVE_XVMC +ec_clean: +#endif + /* clean a few tables */ + for(i=0; imb_num; i++){ + const int mb_xy= s->mb_index2xy[i]; + int error= s->error_status_table[mb_xy]; + + if(s->pict_type!=B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){ + s->mbskip_table[mb_xy]=0; + } + s->mbintra_table[mb_xy]=1; + } +} diff --git a/mpeg4/src/libavcodec/eval.c b/mpeg4/src/libavcodec/eval.c new file mode 100644 index 00000000..5b0e51d6 --- /dev/null +++ b/mpeg4/src/libavcodec/eval.c @@ -0,0 +1,226 @@ +/* + * simple arithmetic expression evaluator + * + * Copyright (c) 2002 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file eval.c + * simple arithmetic expression evaluator. + * + * see http://joe.hotchkiss.com/programming/eval/eval.html + */ + +#include "avcodec.h" +#include "mpegvideo.h" + +#include +#include +#include +#include + +#ifndef NAN + #define NAN 0 +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +typedef struct Parser{ + int stack_index; + char *s; + double *const_value; + const char **const_name; // NULL terminated + double (**func1)(void *, double a); // NULL terminated + const char **func1_name; // NULL terminated + double (**func2)(void *, double a, double b); // NULL terminated + char **func2_name; // NULL terminated + void *opaque; +} Parser; + +static double evalExpression(Parser *p); + +static int strmatch(const char *s, const char *prefix){ + int i; + for(i=0; prefix[i]; i++){ + if(prefix[i] != s[i]) return 0; + } + return 1; +} + +static double evalPrimary(Parser *p){ + double d, d2=NAN; + char *next= p->s; + int i; + + /* number */ + d= strtod(p->s, &next); + if(next != p->s){ + p->s= next; + return d; + } + + /* named constants */ + for(i=0; p->const_name && p->const_name[i]; i++){ + if(strmatch(p->s, p->const_name[i])){ + p->s+= strlen(p->const_name[i]); + return p->const_value[i]; + } + } + + p->s= strchr(p->s, '('); + if(p->s==NULL){ + av_log(NULL, AV_LOG_ERROR, "Parser: missing ( in \"%s\"\n", next); + return NAN; + } + p->s++; // "(" + d= evalExpression(p); + if(p->s[0]== ','){ + p->s++; // "," + d2= evalExpression(p); + } + if(p->s[0] != ')'){ + av_log(NULL, AV_LOG_ERROR, "Parser: missing ) in \"%s\"\n", next); + return NAN; + } + p->s++; // ")" + + if( strmatch(next, "sinh" ) ) d= sinh(d); + else if( strmatch(next, "cosh" ) ) d= cosh(d); + else if( strmatch(next, "tanh" ) ) d= tanh(d); + else if( strmatch(next, "sin" ) ) d= sin(d); + else if( strmatch(next, "cos" ) ) d= cos(d); + else if( strmatch(next, "tan" ) ) d= tan(d); + else if( strmatch(next, "exp" ) ) d= exp(d); + else if( strmatch(next, "log" ) ) d= log(d); + else if( strmatch(next, "squish") ) d= 1/(1+exp(4*d)); + else if( strmatch(next, "gauss" ) ) d= exp(-d*d/2)/sqrt(2*M_PI); + else if( strmatch(next, "abs" ) ) d= fabs(d); + else if( strmatch(next, "max" ) ) d= d > d2 ? d : d2; + else if( strmatch(next, "min" ) ) d= d < d2 ? d : d2; + else if( strmatch(next, "gt" ) ) d= d > d2 ? 1.0 : 0.0; + else if( strmatch(next, "gte" ) ) d= d >= d2 ? 1.0 : 0.0; + else if( strmatch(next, "lt" ) ) d= d > d2 ? 0.0 : 1.0; + else if( strmatch(next, "lte" ) ) d= d >= d2 ? 0.0 : 1.0; + else if( strmatch(next, "eq" ) ) d= d == d2 ? 1.0 : 0.0; + else if( strmatch(next, "(" ) ) d= d; +// else if( strmatch(next, "l1" ) ) d= 1 + d2*(d - 1); +// else if( strmatch(next, "sq01" ) ) d= (d >= 0.0 && d <=1.0) ? 1.0 : 0.0; + else{ + for(i=0; p->func1_name && p->func1_name[i]; i++){ + if(strmatch(next, p->func1_name[i])){ + return p->func1[i](p->opaque, d); + } + } + + for(i=0; p->func2_name && p->func2_name[i]; i++){ + if(strmatch(next, p->func2_name[i])){ + return p->func2[i](p->opaque, d, d2); + } + } + + av_log(NULL, AV_LOG_ERROR, "Parser: unknown function in \"%s\"\n", next); + return NAN; + } + + return d; +} + +static double evalPow(Parser *p){ + int sign= (*p->s == '+') - (*p->s == '-'); + p->s += sign&1; + return (sign|1) * evalPrimary(p); +} + +static double evalFactor(Parser *p){ + double ret= evalPow(p); + while(p->s[0]=='^'){ + p->s++; + ret= pow(ret, evalPow(p)); + } + return ret; +} + +static double evalTerm(Parser *p){ + double ret= evalFactor(p); + while(p->s[0]=='*' || p->s[0]=='/'){ + if(*p->s++ == '*') ret*= evalFactor(p); + else ret/= evalFactor(p); + } + return ret; +} + +static double evalExpression(Parser *p){ + double ret= 0; + + if(p->stack_index <= 0) //protect against stack overflows + return NAN; + p->stack_index--; + + do{ + ret += evalTerm(p); + }while(*p->s == '+' || *p->s == '-'); + + p->stack_index++; + + return ret; +} + +double ff_eval(char *s, double *const_value, const char **const_name, + double (**func1)(void *, double), const char **func1_name, + double (**func2)(void *, double, double), char **func2_name, + void *opaque){ + Parser p; + + p.stack_index=100; + p.s= s; + p.const_value= const_value; + p.const_name = const_name; + p.func1 = func1; + p.func1_name = func1_name; + p.func2 = func2; + p.func2_name = func2_name; + p.opaque = opaque; + + return evalExpression(&p); +} + +#ifdef TEST +#undef printf +static double const_values[]={ + M_PI, + M_E, + 0 +}; +static const char *const_names[]={ + "PI", + "E", + 0 +}; +main(){ + int i; + printf("%f == 12.7\n", ff_eval("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL)); + + for(i=0; i<1050; i++){ + START_TIMER + ff_eval("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL); + STOP_TIMER("ff_eval") + } +} +#endif diff --git a/mpeg4/src/libavcodec/faac.c b/mpeg4/src/libavcodec/faac.c new file mode 100644 index 00000000..2b7c5967 --- /dev/null +++ b/mpeg4/src/libavcodec/faac.c @@ -0,0 +1,131 @@ +/* + * Interface to libfaac for aac encoding + * Copyright (c) 2002 Gildas Bazin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file faacaudio.c + * Interface to libfaac for aac encoding. + */ + +#include "avcodec.h" +#include + +typedef struct FaacAudioContext { + faacEncHandle faac_handle; +} FaacAudioContext; + +static int Faac_encode_init(AVCodecContext *avctx) +{ + FaacAudioContext *s = avctx->priv_data; + faacEncConfigurationPtr faac_cfg; + unsigned long samples_input, max_bytes_output; + + /* number of channels */ + if (avctx->channels < 1 || avctx->channels > 6) + return -1; + + s->faac_handle = faacEncOpen(avctx->sample_rate, + avctx->channels, + &samples_input, &max_bytes_output); + + /* check faac version */ + faac_cfg = faacEncGetCurrentConfiguration(s->faac_handle); + if (faac_cfg->version != FAAC_CFG_VERSION) { + av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version); + faacEncClose(s->faac_handle); + return -1; + } + + /* put the options in the configuration struct */ + faac_cfg->aacObjectType = LOW; + faac_cfg->mpegVersion = MPEG4; + faac_cfg->useTns = 0; + faac_cfg->allowMidside = 1; + faac_cfg->bitRate = avctx->bit_rate / avctx->channels; + faac_cfg->bandWidth = avctx->cutoff; + if(avctx->flags & CODEC_FLAG_QSCALE) { + faac_cfg->bitRate = 0; + faac_cfg->quantqual = avctx->global_quality / FF_QP2LAMBDA; + } + faac_cfg->outputFormat = 1; + faac_cfg->inputFormat = FAAC_INPUT_16BIT; + + avctx->frame_size = samples_input / avctx->channels; + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + + /* Set decoder specific info */ + avctx->extradata_size = 0; + if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { + + unsigned char *buffer; + unsigned long decoder_specific_info_size; + + if (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer, + &decoder_specific_info_size)) { + avctx->extradata = buffer; + avctx->extradata_size = decoder_specific_info_size; + faac_cfg->outputFormat = 0; + } + } + + if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) { + av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n"); + return -1; + } + + return 0; +} + +int Faac_encode_frame(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) +{ + FaacAudioContext *s = avctx->priv_data; + int bytes_written; + + bytes_written = faacEncEncode(s->faac_handle, + data, + avctx->frame_size * avctx->channels, + frame, + buf_size); + + return bytes_written; +} + +int Faac_encode_close(AVCodecContext *avctx) +{ + FaacAudioContext *s = avctx->priv_data; + + av_freep(&avctx->coded_frame); + + //if (avctx->extradata_size) free(avctx->extradata); + + faacEncClose(s->faac_handle); + return 0; +} + +AVCodec faac_encoder = { + "aac", + CODEC_TYPE_AUDIO, + CODEC_ID_AAC, + sizeof(FaacAudioContext), + Faac_encode_init, + Faac_encode_frame, + Faac_encode_close +}; diff --git a/mpeg4/src/libavcodec/faad.c b/mpeg4/src/libavcodec/faad.c new file mode 100644 index 00000000..49cc789a --- /dev/null +++ b/mpeg4/src/libavcodec/faad.c @@ -0,0 +1,330 @@ +/* + * Faad decoder + * Copyright (c) 2003 Zdenek Kabelac. + * Copyright (c) 2004 Thomas Raivio. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file faad.c + * AAC decoder. + * + * still a bit unfinished - but it plays something + */ + +#include "avcodec.h" +#include "faad.h" + +#ifndef FAADAPI +#define FAADAPI +#endif + +/* + * when CONFIG_FAADBIN is defined the libfaad will be opened at runtime + */ +//#undef CONFIG_FAADBIN +//#define CONFIG_FAADBIN + +#ifdef CONFIG_FAADBIN +#include +static const char* libfaadname = "libfaad.so.0"; +#else +#define dlopen(a) +#define dlclose(a) +#endif + +typedef struct { + void* handle; /* dlopen handle */ + void* faac_handle; /* FAAD library handle */ + int sample_size; + int init; + + /* faad calls */ + faacDecHandle FAADAPI (*faacDecOpen)(void); + faacDecConfigurationPtr FAADAPI (*faacDecGetCurrentConfiguration)(faacDecHandle hDecoder); +#ifndef FAAD2_VERSION + int FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, + faacDecConfigurationPtr config); + int FAADAPI (*faacDecInit)(faacDecHandle hDecoder, + unsigned char *buffer, + unsigned long *samplerate, + unsigned long *channels); + int FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, + unsigned long SizeOfDecoderSpecificInfo, + unsigned long *samplerate, unsigned long *channels); + int FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, + unsigned char *buffer, + unsigned long *bytesconsumed, + short *sample_buffer, + unsigned long *samples); +#else + unsigned char FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, + faacDecConfigurationPtr config); + long FAADAPI (*faacDecInit)(faacDecHandle hDecoder, + unsigned char *buffer, + unsigned long buffer_size, + unsigned long *samplerate, + unsigned char *channels); + char FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, + unsigned long SizeOfDecoderSpecificInfo, + unsigned long *samplerate, unsigned char *channels); + void *FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, + faacDecFrameInfo *hInfo, + unsigned char *buffer, + unsigned long buffer_size); + char* FAADAPI (*faacDecGetErrorMessage)(unsigned char errcode); +#endif + + void FAADAPI (*faacDecClose)(faacDecHandle hDecoder); + + +} FAACContext; + +static const unsigned long faac_srates[] = +{ + 96000, 88200, 64000, 48000, 44100, 32000, + 24000, 22050, 16000, 12000, 11025, 8000 +}; + +static int faac_init_mp4(AVCodecContext *avctx) +{ + FAACContext *s = (FAACContext *) avctx->priv_data; + unsigned long samplerate; +#ifndef FAAD2_VERSION + unsigned long channels; +#else + unsigned char channels; +#endif + int r = 0; + + if (avctx->extradata){ + r = s->faacDecInit2(s->faac_handle, (uint8_t*) avctx->extradata, + avctx->extradata_size, + &samplerate, &channels); + if (r < 0){ + av_log(avctx, AV_LOG_ERROR, + "faacDecInit2 failed r:%d sr:%ld ch:%ld s:%d\n", + r, samplerate, (long)channels, avctx->extradata_size); + } else { + avctx->sample_rate = samplerate; + avctx->channels = channels; + s->init = 1; + } + } + + return r; +} + +static int faac_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + FAACContext *s = (FAACContext *) avctx->priv_data; +#ifndef FAAD2_VERSION + unsigned long bytesconsumed; + short *sample_buffer = NULL; + unsigned long samples; + int out; +#else + faacDecFrameInfo frame_info; + void *out; +#endif + if(buf_size == 0) + return 0; +#ifndef FAAD2_VERSION + out = s->faacDecDecode(s->faac_handle, + (unsigned char*)buf, + &bytesconsumed, + data, + &samples); + samples *= s->sample_size; + if (data_size) + *data_size = samples; + return (buf_size < (int)bytesconsumed) + ? buf_size : (int)bytesconsumed; +#else + + if(!s->init){ + unsigned long srate; + unsigned char channels; + int r = s->faacDecInit(s->faac_handle, buf, buf_size, &srate, &channels); + if(r < 0){ + av_log(avctx, AV_LOG_ERROR, "faac: codec init failed: %s\n", + s->faacDecGetErrorMessage(frame_info.error)); + return -1; + } + avctx->sample_rate = srate; + avctx->channels = channels; + s->init = 1; + } + + out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size); + + if (frame_info.error > 0) { + av_log(avctx, AV_LOG_ERROR, "faac: frame decoding failed: %s\n", + s->faacDecGetErrorMessage(frame_info.error)); + return -1; + } + + frame_info.samples *= s->sample_size; + memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one + + if (data_size) + *data_size = frame_info.samples; + + return (buf_size < (int)frame_info.bytesconsumed) + ? buf_size : (int)frame_info.bytesconsumed; +#endif +} + +static int faac_decode_end(AVCodecContext *avctx) +{ + FAACContext *s = (FAACContext *) avctx->priv_data; + + if (s->faacDecClose) + s->faacDecClose(s->faac_handle); + + dlclose(s->handle); + return 0; +} + +static int faac_decode_init(AVCodecContext *avctx) +{ + FAACContext *s = (FAACContext *) avctx->priv_data; + faacDecConfigurationPtr faac_cfg; + +#ifdef CONFIG_FAADBIN + const char* err = 0; + + s->handle = dlopen(libfaadname, RTLD_LAZY); + if (!s->handle) + { + av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n", + libfaadname, dlerror()); + return -1; + } +#define dfaac(a, b) \ + do { static const char* n = "faacDec" #a; \ + if ((s->faacDec ## a = b dlsym( s->handle, n )) == NULL) { err = n; break; } } while(0) + for(;;) { +#else /* !CONFIG_FAADBIN */ +#define dfaac(a, b) s->faacDec ## a = faacDec ## a +#endif /* CONFIG_FAADBIN */ + + // resolve all needed function calls + dfaac(Open, (faacDecHandle FAADAPI (*)(void))); + dfaac(GetCurrentConfiguration, (faacDecConfigurationPtr + FAADAPI (*)(faacDecHandle))); +#ifndef FAAD2_VERSION + dfaac(SetConfiguration, (int FAADAPI (*)(faacDecHandle, + faacDecConfigurationPtr))); + + dfaac(Init, (int FAADAPI (*)(faacDecHandle, unsigned char*, + unsigned long*, unsigned long*))); + dfaac(Init2, (int FAADAPI (*)(faacDecHandle, unsigned char*, + unsigned long, unsigned long*, + unsigned long*))); + dfaac(Close, (void FAADAPI (*)(faacDecHandle hDecoder))); + dfaac(Decode, (int FAADAPI (*)(faacDecHandle, unsigned char*, + unsigned long*, short*, unsigned long*))); +#else + dfaac(SetConfiguration, (unsigned char FAADAPI (*)(faacDecHandle, + faacDecConfigurationPtr))); + dfaac(Init, (long FAADAPI (*)(faacDecHandle, unsigned char*, + unsigned long, unsigned long*, unsigned char*))); + dfaac(Init2, (char FAADAPI (*)(faacDecHandle, unsigned char*, + unsigned long, unsigned long*, + unsigned char*))); + dfaac(Decode, (void *FAADAPI (*)(faacDecHandle, faacDecFrameInfo*, + unsigned char*, unsigned long))); + dfaac(GetErrorMessage, (char* FAADAPI (*)(unsigned char))); +#endif +#undef dfacc + +#ifdef CONFIG_FAADBIN + break; + } + if (err) { + dlclose(s->handle); + av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n", + err, libfaadname); + return -1; + } +#endif + + s->faac_handle = s->faacDecOpen(); + if (!s->faac_handle) { + av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n"); + faac_decode_end(avctx); + return -1; + } + + + faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); + + if (faac_cfg) { + switch (avctx->bits_per_sample) { + case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_sample); break; + default: + case 16: +#ifdef FAAD2_VERSION + faac_cfg->outputFormat = FAAD_FMT_16BIT; +#endif + s->sample_size = 2; + break; + case 24: +#ifdef FAAD2_VERSION + faac_cfg->outputFormat = FAAD_FMT_24BIT; +#endif + s->sample_size = 3; + break; + case 32: +#ifdef FAAD2_VERSION + faac_cfg->outputFormat = FAAD_FMT_32BIT; +#endif + s->sample_size = 4; + break; + } + + faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate; + faac_cfg->defObjectType = LC; + } + + s->faacDecSetConfiguration(s->faac_handle, faac_cfg); + + faac_init_mp4(avctx); + + return 0; +} + +#define AAC_CODEC(id, name) \ +AVCodec name ## _decoder = { \ + #name, \ + CODEC_TYPE_AUDIO, \ + id, \ + sizeof(FAACContext), \ + faac_decode_init, \ + NULL, \ + faac_decode_end, \ + faac_decode_frame, \ +} + +// FIXME - raw AAC files - maybe just one entry will be enough +AAC_CODEC(CODEC_ID_AAC, aac); +// If it's mp4 file - usually embeded into Qt Mov +AAC_CODEC(CODEC_ID_MPEG4AAC, mpeg4aac); + +#undef AAC_CODEC diff --git a/mpeg4/src/libavcodec/faandct.c b/mpeg4/src/libavcodec/faandct.c new file mode 100644 index 00000000..cd7ef7c6 --- /dev/null +++ b/mpeg4/src/libavcodec/faandct.c @@ -0,0 +1,218 @@ +/* + * Floating point AAN DCT + * Copyright (c) 2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * this implementation is based upon the IJG integer AAN DCT (see jfdctfst.c) + */ + +/** + * @file faandct.c + * @brief + * Floating point AAN DCT + * @author Michael Niedermayer + */ + +#include "dsputil.h" +#include "faandct.h" + +#define FLOAT float +#ifdef FAAN_POSTSCALE +# define SCALE(x) postscale[x] +#else +# define SCALE(x) 1 +#endif + +//numbers generated by simple c code (not as accurate as they could be) +/* +for(i=0; i<8; i++){ + printf("#define B%d %1.20llf\n", i, (long double)1.0/(cosl(i*acosl(-1.0)/(long double)16.0)*sqrtl(2))); +} +*/ +#define B0 1.00000000000000000000 +#define B1 0.72095982200694791383 // (cos(pi*1/16)sqrt(2))^-1 +#define B2 0.76536686473017954350 // (cos(pi*2/16)sqrt(2))^-1 +#define B3 0.85043009476725644878 // (cos(pi*3/16)sqrt(2))^-1 +#define B4 1.00000000000000000000 // (cos(pi*4/16)sqrt(2))^-1 +#define B5 1.27275858057283393842 // (cos(pi*5/16)sqrt(2))^-1 +#define B6 1.84775906502257351242 // (cos(pi*6/16)sqrt(2))^-1 +#define B7 3.62450978541155137218 // (cos(pi*7/16)sqrt(2))^-1 + + +#define A1 0.70710678118654752438 // cos(pi*4/16) +#define A2 0.54119610014619698435 // cos(pi*6/16)sqrt(2) +#define A5 0.38268343236508977170 // cos(pi*6/16) +#define A4 1.30656296487637652774 // cos(pi*2/16)sqrt(2) + +static FLOAT postscale[64]={ +B0*B0, B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B6, B0*B7, +B1*B0, B1*B1, B1*B2, B1*B3, B1*B4, B1*B5, B1*B6, B1*B7, +B2*B0, B2*B1, B2*B2, B2*B3, B2*B4, B2*B5, B2*B6, B2*B7, +B3*B0, B3*B1, B3*B2, B3*B3, B3*B4, B3*B5, B3*B6, B3*B7, +B4*B0, B4*B1, B4*B2, B4*B3, B4*B4, B4*B5, B4*B6, B4*B7, +B5*B0, B5*B1, B5*B2, B5*B3, B5*B4, B5*B5, B5*B6, B5*B7, +B6*B0, B6*B1, B6*B2, B6*B3, B6*B4, B6*B5, B6*B6, B6*B7, +B7*B0, B7*B1, B7*B2, B7*B3, B7*B4, B7*B5, B7*B6, B7*B7, +}; + +static always_inline void row_fdct(FLOAT temp[64], DCTELEM * data) +{ + FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FLOAT tmp10, tmp11, tmp12, tmp13; + FLOAT z1, z2, z3, z4, z5, z11, z13; + int i; + + for (i=0; i<8*8; i+=8) { + tmp0= data[0 + i] + data[7 + i]; + tmp7= data[0 + i] - data[7 + i]; + tmp1= data[1 + i] + data[6 + i]; + tmp6= data[1 + i] - data[6 + i]; + tmp2= data[2 + i] + data[5 + i]; + tmp5= data[2 + i] - data[5 + i]; + tmp3= data[3 + i] + data[4 + i]; + tmp4= data[3 + i] - data[4 + i]; + + tmp10= tmp0 + tmp3; + tmp13= tmp0 - tmp3; + tmp11= tmp1 + tmp2; + tmp12= tmp1 - tmp2; + + temp[0 + i]= tmp10 + tmp11; + temp[4 + i]= tmp10 - tmp11; + + z1= (tmp12 + tmp13)*A1; + temp[2 + i]= tmp13 + z1; + temp[6 + i]= tmp13 - z1; + + tmp10= tmp4 + tmp5; + tmp11= tmp5 + tmp6; + tmp12= tmp6 + tmp7; + + z5= (tmp10 - tmp12) * A5; + z2= tmp10*A2 + z5; + z4= tmp12*A4 + z5; + z3= tmp11*A1; + + z11= tmp7 + z3; + z13= tmp7 - z3; + + temp[5 + i]= z13 + z2; + temp[3 + i]= z13 - z2; + temp[1 + i]= z11 + z4; + temp[7 + i]= z11 - z4; + } +} + +void ff_faandct(DCTELEM * data) +{ + FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FLOAT tmp10, tmp11, tmp12, tmp13; + FLOAT z1, z2, z3, z4, z5, z11, z13; + FLOAT temp[64]; + int i; + + emms_c(); + + row_fdct(temp, data); + + for (i=0; i<8; i++) { + tmp0= temp[8*0 + i] + temp[8*7 + i]; + tmp7= temp[8*0 + i] - temp[8*7 + i]; + tmp1= temp[8*1 + i] + temp[8*6 + i]; + tmp6= temp[8*1 + i] - temp[8*6 + i]; + tmp2= temp[8*2 + i] + temp[8*5 + i]; + tmp5= temp[8*2 + i] - temp[8*5 + i]; + tmp3= temp[8*3 + i] + temp[8*4 + i]; + tmp4= temp[8*3 + i] - temp[8*4 + i]; + + tmp10= tmp0 + tmp3; + tmp13= tmp0 - tmp3; + tmp11= tmp1 + tmp2; + tmp12= tmp1 - tmp2; + + data[8*0 + i]= lrintf(SCALE(8*0 + i) * (tmp10 + tmp11)); + data[8*4 + i]= lrintf(SCALE(8*4 + i) * (tmp10 - tmp11)); + + z1= (tmp12 + tmp13)* A1; + data[8*2 + i]= lrintf(SCALE(8*2 + i) * (tmp13 + z1)); + data[8*6 + i]= lrintf(SCALE(8*6 + i) * (tmp13 - z1)); + + tmp10= tmp4 + tmp5; + tmp11= tmp5 + tmp6; + tmp12= tmp6 + tmp7; + + z5= (tmp10 - tmp12) * A5; + z2= tmp10*A2 + z5; + z4= tmp12*A4 + z5; + z3= tmp11*A1; + + z11= tmp7 + z3; + z13= tmp7 - z3; + + data[8*5 + i]= lrintf(SCALE(8*5 + i) * (z13 + z2)); + data[8*3 + i]= lrintf(SCALE(8*3 + i) * (z13 - z2)); + data[8*1 + i]= lrintf(SCALE(8*1 + i) * (z11 + z4)); + data[8*7 + i]= lrintf(SCALE(8*7 + i) * (z11 - z4)); + } +} + +void ff_faandct248(DCTELEM * data) +{ + FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + FLOAT tmp10, tmp11, tmp12, tmp13; + FLOAT z1; + FLOAT temp[64]; + int i; + + emms_c(); + + row_fdct(temp, data); + + for (i=0; i<8; i++) { + tmp0 = temp[8*0 + i] + temp[8*1 + i]; + tmp1 = temp[8*2 + i] + temp[8*3 + i]; + tmp2 = temp[8*4 + i] + temp[8*5 + i]; + tmp3 = temp[8*6 + i] + temp[8*7 + i]; + tmp4 = temp[8*0 + i] - temp[8*1 + i]; + tmp5 = temp[8*2 + i] - temp[8*3 + i]; + tmp6 = temp[8*4 + i] - temp[8*5 + i]; + tmp7 = temp[8*6 + i] - temp[8*7 + i]; + + tmp10 = tmp0 + tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + tmp13 = tmp0 - tmp3; + + data[8*0 + i] = lrintf(SCALE(8*0 + i) * (tmp10 + tmp11)); + data[8*4 + i] = lrintf(SCALE(8*4 + i) * (tmp10 - tmp11)); + + z1 = (tmp12 + tmp13)* A1; + data[8*2 + i] = lrintf(SCALE(8*2 + i) * (tmp13 + z1)); + data[8*6 + i] = lrintf(SCALE(8*6 + i) * (tmp13 - z1)); + + tmp10 = tmp4 + tmp7; + tmp11 = tmp5 + tmp6; + tmp12 = tmp5 - tmp6; + tmp13 = tmp4 - tmp7; + + data[8*1 + i] = lrintf(SCALE(8*0 + i) * (tmp10 + tmp11)); + data[8*5 + i] = lrintf(SCALE(8*4 + i) * (tmp10 - tmp11)); + + z1 = (tmp12 + tmp13)* A1; + data[8*3 + i] = lrintf(SCALE(8*2 + i) * (tmp13 + z1)); + data[8*7 + i] = lrintf(SCALE(8*6 + i) * (tmp13 - z1)); + } +} diff --git a/mpeg4/src/libavcodec/faandct.h b/mpeg4/src/libavcodec/faandct.h new file mode 100644 index 00000000..677594c0 --- /dev/null +++ b/mpeg4/src/libavcodec/faandct.h @@ -0,0 +1,31 @@ +/* + * Floating point AAN DCT + * Copyright (c) 2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file faandct.h + * @brief + * Floating point AAN DCT + * @author Michael Niedermayer + */ + +#define FAAN_POSTSCALE + +void ff_faandct(DCTELEM * data); +void ff_faandct248(DCTELEM * data); diff --git a/mpeg4/src/libavcodec/fdctref.c b/mpeg4/src/libavcodec/fdctref.c new file mode 100644 index 00000000..5eff3684 --- /dev/null +++ b/mpeg4/src/libavcodec/fdctref.c @@ -0,0 +1,158 @@ +/** + * @file fdctref.c + * forward discrete cosine transform, double precision. + */ + +/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ + +/* + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims + * any and all warranties, whether express, implied, or statuary, including any + * implied warranties or merchantability or of fitness for a particular + * purpose. In no event shall the copyright-holder be liable for any + * incidental, punitive, or consequential damages of any kind whatsoever + * arising from the use of these programs. + * + * This disclaimer of warranty extends to the user of these programs and user's + * customers, employees, agents, transferees, successors, and assigns. + * + * The MPEG Software Simulation Group does not represent or warrant that the + * programs furnished hereunder are free of infringement of any third-party + * patents. + * + * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, + * are subject to royalty fees to patent holders. Many of these patents are + * general enough such that they are unavoidable regardless of implementation + * design. + * + */ + +#include + +#ifndef PI +# ifdef M_PI +# define PI M_PI +# else +# define PI 3.14159265358979323846 +# endif +#endif + +/* global declarations */ +void init_fdct (void); +void fdct (short *block); + +/* private data */ +static double c[8][8]; /* transform coefficients */ + +void init_fdct() +{ + int i, j; + double s; + + for (i=0; i<8; i++) + { + s = (i==0) ? sqrt(0.125) : 0.5; + + for (j=0; j<8; j++) + c[i][j] = s * cos((PI/8.0)*i*(j+0.5)); + } +} + +void fdct(block) +short *block; +{ + register int i, j; + double s; + double tmp[64]; + + for(i = 0; i < 8; i++) + for(j = 0; j < 8; j++) + { + s = 0.0; + +/* + * for(k = 0; k < 8; k++) + * s += c[j][k] * block[8 * i + k]; + */ + s += c[j][0] * block[8 * i + 0]; + s += c[j][1] * block[8 * i + 1]; + s += c[j][2] * block[8 * i + 2]; + s += c[j][3] * block[8 * i + 3]; + s += c[j][4] * block[8 * i + 4]; + s += c[j][5] * block[8 * i + 5]; + s += c[j][6] * block[8 * i + 6]; + s += c[j][7] * block[8 * i + 7]; + + tmp[8 * i + j] = s; + } + + for(j = 0; j < 8; j++) + for(i = 0; i < 8; i++) + { + s = 0.0; + +/* + * for(k = 0; k < 8; k++) + * s += c[i][k] * tmp[8 * k + j]; + */ + s += c[i][0] * tmp[8 * 0 + j]; + s += c[i][1] * tmp[8 * 1 + j]; + s += c[i][2] * tmp[8 * 2 + j]; + s += c[i][3] * tmp[8 * 3 + j]; + s += c[i][4] * tmp[8 * 4 + j]; + s += c[i][5] * tmp[8 * 5 + j]; + s += c[i][6] * tmp[8 * 6 + j]; + s += c[i][7] * tmp[8 * 7 + j]; + s*=8.0; + + block[8 * i + j] = (short)floor(s + 0.499999); +/* + * reason for adding 0.499999 instead of 0.5: + * s is quite often x.5 (at least for i and/or j = 0 or 4) + * and setting the rounding threshold exactly to 0.5 leads to an + * extremely high arithmetic implementation dependency of the result; + * s being between x.5 and x.500001 (which is now incorrectly rounded + * downwards instead of upwards) is assumed to occur less often + * (if at all) + */ + } +} + +/* perform IDCT matrix multiply for 8x8 coefficient block */ + +void idct(block) +short *block; +{ + int i, j, k, v; + double partial_product; + double tmp[64]; + + for (i=0; i<8; i++) + for (j=0; j<8; j++) + { + partial_product = 0.0; + + for (k=0; k<8; k++) + partial_product+= c[k][j]*block[8*i+k]; + + tmp[8*i+j] = partial_product; + } + + /* Transpose operation is integrated into address mapping by switching + loop order of i and j */ + + for (j=0; j<8; j++) + for (i=0; i<8; i++) + { + partial_product = 0.0; + + for (k=0; k<8; k++) + partial_product+= c[k][i]*tmp[8*k+j]; + + v = (int) floor(partial_product+0.5); + block[8*i+j] = v; + } +} diff --git a/mpeg4/src/libavcodec/fft-test.c b/mpeg4/src/libavcodec/fft-test.c new file mode 100644 index 00000000..f924dcad --- /dev/null +++ b/mpeg4/src/libavcodec/fft-test.c @@ -0,0 +1,277 @@ +/** + * @file fft-test.c + * FFT and MDCT tests. + */ + +#include "dsputil.h" +#include +#include +#include + +int mm_flags; + +/* reference fft */ + +#define MUL16(a,b) ((a) * (b)) + +#define CMAC(pre, pim, are, aim, bre, bim) \ +{\ + pre += (MUL16(are, bre) - MUL16(aim, bim));\ + pim += (MUL16(are, bim) + MUL16(bre, aim));\ +} + +FFTComplex *exptab; + +void fft_ref_init(int nbits, int inverse) +{ + int n, i; + float c1, s1, alpha; + + n = 1 << nbits; + exptab = av_malloc((n / 2) * sizeof(FFTComplex)); + + for(i=0;i<(n/2);i++) { + alpha = 2 * M_PI * (float)i / (float)n; + c1 = cos(alpha); + s1 = sin(alpha); + if (!inverse) + s1 = -s1; + exptab[i].re = c1; + exptab[i].im = s1; + } +} + +void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits) +{ + int n, i, j, k, n2; + float tmp_re, tmp_im, s, c; + FFTComplex *q; + + n = 1 << nbits; + n2 = n >> 1; + for(i=0;i= n2) { + c = -exptab[k - n2].re; + s = -exptab[k - n2].im; + } else { + c = exptab[k].re; + s = exptab[k].im; + } + CMAC(tmp_re, tmp_im, c, s, q->re, q->im); + q++; + } + tabr[i].re = tmp_re; + tabr[i].im = tmp_im; + } +} + +void imdct_ref(float *out, float *in, int n) +{ + int k, i, a; + float sum, f; + + for(i=0;i= 1e-3) { + av_log(NULL, AV_LOG_ERROR, "ERROR %d: %f %f\n", + i, tab1[i], tab2[i]); + } + } +} + + +void help(void) +{ + av_log(NULL, AV_LOG_INFO,"usage: fft-test [-h] [-s] [-i] [-n b]\n" + "-h print this help\n" + "-s speed test\n" + "-m (I)MDCT test\n" + "-i inverse transform test\n" + "-n b set the transform size to 2^b\n" + ); + exit(1); +} + + + +int main(int argc, char **argv) +{ + FFTComplex *tab, *tab1, *tab_ref; + FFTSample *tabtmp, *tab2; + int it, i, c; + int do_speed = 0; + int do_mdct = 0; + int do_inverse = 0; + FFTContext s1, *s = &s1; + MDCTContext m1, *m = &m1; + int fft_nbits, fft_size; + + mm_flags = 0; + fft_nbits = 9; + for(;;) { + c = getopt(argc, argv, "hsimn:"); + if (c == -1) + break; + switch(c) { + case 'h': + help(); + break; + case 's': + do_speed = 1; + break; + case 'i': + do_inverse = 1; + break; + case 'm': + do_mdct = 1; + break; + case 'n': + fft_nbits = atoi(optarg); + break; + } + } + + fft_size = 1 << fft_nbits; + tab = av_malloc(fft_size * sizeof(FFTComplex)); + tab1 = av_malloc(fft_size * sizeof(FFTComplex)); + tab_ref = av_malloc(fft_size * sizeof(FFTComplex)); + tabtmp = av_malloc(fft_size / 2 * sizeof(FFTSample)); + tab2 = av_malloc(fft_size * sizeof(FFTSample)); + + if (do_mdct) { + if (do_inverse) + av_log(NULL, AV_LOG_INFO,"IMDCT"); + else + av_log(NULL, AV_LOG_INFO,"MDCT"); + ff_mdct_init(m, fft_nbits, do_inverse); + } else { + if (do_inverse) + av_log(NULL, AV_LOG_INFO,"IFFT"); + else + av_log(NULL, AV_LOG_INFO,"FFT"); + ff_fft_init(s, fft_nbits, do_inverse); + fft_ref_init(fft_nbits, do_inverse); + } + av_log(NULL, AV_LOG_INFO," %d test\n", fft_size); + + /* generate random data */ + + for(i=0;i= 1000000) + break; + nb_its *= 2; + } + av_log(NULL, AV_LOG_INFO,"time: %0.1f us/transform [total time=%0.2f s its=%d]\n", + (double)duration / nb_its, + (double)duration / 1000000.0, + nb_its); + } + + if (do_mdct) { + ff_mdct_end(m); + } else { + ff_fft_end(s); + } + return 0; +} diff --git a/mpeg4/src/libavcodec/fft.c b/mpeg4/src/libavcodec/fft.c new file mode 100644 index 00000000..1306abd6 --- /dev/null +++ b/mpeg4/src/libavcodec/fft.c @@ -0,0 +1,266 @@ +/* + * FFT/IFFT transforms + * Copyright (c) 2002 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file fft.c + * FFT/IFFT transforms. + */ + +#include "dsputil.h" + +/** + * The size of the FFT is 2^nbits. If inverse is TRUE, inverse FFT is + * done + */ +int ff_fft_init(FFTContext *s, int nbits, int inverse) +{ + int i, j, m, n; + float alpha, c1, s1, s2; + + s->nbits = nbits; + n = 1 << nbits; + + s->exptab = av_malloc((n / 2) * sizeof(FFTComplex)); + if (!s->exptab) + goto fail; + s->revtab = av_malloc(n * sizeof(uint16_t)); + if (!s->revtab) + goto fail; + s->inverse = inverse; + + s2 = inverse ? 1.0 : -1.0; + + for(i=0;i<(n/2);i++) { + alpha = 2 * M_PI * (float)i / (float)n; + c1 = cos(alpha); + s1 = sin(alpha) * s2; + s->exptab[i].re = c1; + s->exptab[i].im = s1; + } + s->fft_calc = ff_fft_calc_c; + s->exptab1 = NULL; + + /* compute constant table for HAVE_SSE version */ +#if (defined(HAVE_MMX) && (defined(HAVE_BUILTIN_VECTOR) || defined(HAVE_MM3DNOW))) || defined(HAVE_ALTIVEC) + { + int has_vectors = 0; + +#if defined(HAVE_MMX) + has_vectors = mm_support() & (MM_3DNOW | MM_3DNOWEXT | MM_SSE | MM_SSE2); +#endif +#if defined(HAVE_ALTIVEC) && !defined(ALTIVEC_USE_REFERENCE_C_CODE) + has_vectors = mm_support() & MM_ALTIVEC; +#endif + if (has_vectors) { + int np, nblocks, np2, l; + FFTComplex *q; + + np = 1 << nbits; + nblocks = np >> 3; + np2 = np >> 1; + s->exptab1 = av_malloc(np * 2 * sizeof(FFTComplex)); + if (!s->exptab1) + goto fail; + q = s->exptab1; + do { + for(l = 0; l < np2; l += 2 * nblocks) { + *q++ = s->exptab[l]; + *q++ = s->exptab[l + nblocks]; + + q->re = -s->exptab[l].im; + q->im = s->exptab[l].re; + q++; + q->re = -s->exptab[l + nblocks].im; + q->im = s->exptab[l + nblocks].re; + q++; + } + nblocks = nblocks >> 1; + } while (nblocks != 0); + av_freep(&s->exptab); +#if defined(HAVE_MMX) +#ifdef HAVE_MM3DNOW + if (has_vectors & MM_3DNOWEXT) + /* 3DNowEx for Athlon(XP) */ + s->fft_calc = ff_fft_calc_3dn2; + else if (has_vectors & MM_3DNOW) + /* 3DNow! for K6-2/3 */ + s->fft_calc = ff_fft_calc_3dn; +#endif +#ifdef HAVE_BUILTIN_VECTOR + if (has_vectors & MM_SSE2) + /* SSE for P4/K8 */ + s->fft_calc = ff_fft_calc_sse; + else if ((has_vectors & MM_SSE) && + s->fft_calc == ff_fft_calc_c) + /* SSE for P3 */ + s->fft_calc = ff_fft_calc_sse; +#endif +#else /* HAVE_MMX */ + s->fft_calc = ff_fft_calc_altivec; +#endif + } + } +#endif + + /* compute bit reverse table */ + + for(i=0;i> j) & 1) << (nbits-j-1); + } + s->revtab[i]=m; + } + return 0; + fail: + av_freep(&s->revtab); + av_freep(&s->exptab); + av_freep(&s->exptab1); + return -1; +} + +/* butter fly op */ +#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \ +{\ + FFTSample ax, ay, bx, by;\ + bx=pre1;\ + by=pim1;\ + ax=qre1;\ + ay=qim1;\ + pre = (bx + ax);\ + pim = (by + ay);\ + qre = (bx - ax);\ + qim = (by - ay);\ +} + +#define MUL16(a,b) ((a) * (b)) + +#define CMUL(pre, pim, are, aim, bre, bim) \ +{\ + pre = (MUL16(are, bre) - MUL16(aim, bim));\ + pim = (MUL16(are, bim) + MUL16(bre, aim));\ +} + +/** + * Do a complex FFT with the parameters defined in ff_fft_init(). The + * input data must be permuted before with s->revtab table. No + * 1.0/sqrt(n) normalization is done. + */ +void ff_fft_calc_c(FFTContext *s, FFTComplex *z) +{ + int ln = s->nbits; + int j, np, np2; + int nblocks, nloops; + register FFTComplex *p, *q; + FFTComplex *exptab = s->exptab; + int l; + FFTSample tmp_re, tmp_im; + + np = 1 << ln; + + /* pass 0 */ + + p=&z[0]; + j=(np >> 1); + do { + BF(p[0].re, p[0].im, p[1].re, p[1].im, + p[0].re, p[0].im, p[1].re, p[1].im); + p+=2; + } while (--j != 0); + + /* pass 1 */ + + + p=&z[0]; + j=np >> 2; + if (s->inverse) { + do { + BF(p[0].re, p[0].im, p[2].re, p[2].im, + p[0].re, p[0].im, p[2].re, p[2].im); + BF(p[1].re, p[1].im, p[3].re, p[3].im, + p[1].re, p[1].im, -p[3].im, p[3].re); + p+=4; + } while (--j != 0); + } else { + do { + BF(p[0].re, p[0].im, p[2].re, p[2].im, + p[0].re, p[0].im, p[2].re, p[2].im); + BF(p[1].re, p[1].im, p[3].re, p[3].im, + p[1].re, p[1].im, p[3].im, -p[3].re); + p+=4; + } while (--j != 0); + } + /* pass 2 .. ln-1 */ + + nblocks = np >> 3; + nloops = 1 << 2; + np2 = np >> 1; + do { + p = z; + q = z + nloops; + for (j = 0; j < nblocks; ++j) { + BF(p->re, p->im, q->re, q->im, + p->re, p->im, q->re, q->im); + + p++; + q++; + for(l = nblocks; l < np2; l += nblocks) { + CMUL(tmp_re, tmp_im, exptab[l].re, exptab[l].im, q->re, q->im); + BF(p->re, p->im, q->re, q->im, + p->re, p->im, tmp_re, tmp_im); + p++; + q++; + } + + p += nloops; + q += nloops; + } + nblocks = nblocks >> 1; + nloops = nloops << 1; + } while (nblocks != 0); +} + +/** + * Do the permutation needed BEFORE calling ff_fft_calc() + */ +void ff_fft_permute(FFTContext *s, FFTComplex *z) +{ + int j, k, np; + FFTComplex tmp; + const uint16_t *revtab = s->revtab; + + /* reverse */ + np = 1 << s->nbits; + for(j=0;jrevtab); + av_freep(&s->exptab); + av_freep(&s->exptab1); +} + diff --git a/mpeg4/src/libavcodec/ffv1.c b/mpeg4/src/libavcodec/ffv1.c new file mode 100644 index 00000000..36a85d9a --- /dev/null +++ b/mpeg4/src/libavcodec/ffv1.c @@ -0,0 +1,1037 @@ +/* + * FFV1 codec for libavcodec + * + * Copyright (c) 2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file ffv1.c + * FF Video Codec 1 (an experimental lossless codec) + */ + +#include "common.h" +#include "bitstream.h" +#include "avcodec.h" +#include "dsputil.h" +#include "rangecoder.h" +#include "golomb.h" + +#define MAX_PLANES 4 +#define CONTEXT_SIZE 32 + +static const int8_t quant3[256]={ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, +}; +static const int8_t quant5[256]={ + 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1, +}; +static const int8_t quant7[256]={ + 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, +-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, +-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, +-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, +-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3, +-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, +-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1, +}; +static const int8_t quant9[256]={ + 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3, +-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1, +}; +static const int8_t quant11[256]={ + 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, +-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, +-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, +-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, +-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, +-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-4,-4, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, +-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1, +}; +static const int8_t quant13[256]={ + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, +-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, +-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, +-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6, +-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5, +-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, +-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, +-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1, +}; + +static const uint8_t log2_run[32]={ + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9,10,11,12,13,14,15, +}; + +typedef struct VlcState{ + int16_t drift; + uint16_t error_sum; + int8_t bias; + uint8_t count; +} VlcState; + +typedef struct PlaneContext{ + int context_count; + uint8_t (*state)[CONTEXT_SIZE]; + VlcState *vlc_state; + uint8_t interlace_bit_state[2]; +} PlaneContext; + +typedef struct FFV1Context{ + AVCodecContext *avctx; + RangeCoder c; + GetBitContext gb; + PutBitContext pb; + int version; + int width, height; + int chroma_h_shift, chroma_v_shift; + int flags; + int picture_number; + AVFrame picture; + int plane_count; + int ac; ///< 1-> CABAC 0-> golomb rice + PlaneContext plane[MAX_PLANES]; + int16_t quant_table[5][256]; + int run_index; + int colorspace; + + DSPContext dsp; +}FFV1Context; + +static always_inline int fold(int diff, int bits){ + if(bits==8) + diff= (int8_t)diff; + else{ + diff+= 1<<(bits-1); + diff&=(1<quant_table[3][127]){ + const int TT= last2[0]; + const int LL= src[-2]; + return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF] + +f->quant_table[3][(LL-L) & 0xFF] + f->quant_table[4][(TT-T) & 0xFF]; + }else + return f->quant_table[0][(L-LT) & 0xFF] + f->quant_table[1][(LT-T) & 0xFF] + f->quant_table[2][(T-RT) & 0xFF]; +} + +static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){ + int i; + + if(v){ + const int a= ABS(v); + const int e= av_log2(a); + put_rac(c, state+0, 0); + + assert(e<=9); + + for(i=0; i=0; i--){ + put_rac(c, state+22+i, (a>>i)&1); //22..31 + } + + if(is_signed) + put_rac(c, state+11 + e, v < 0); //11..21 + }else{ + put_rac(c, state+0, 1); + } +} + +static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){ + if(get_rac(c, state+0)) + return 0; + else{ + int i, e, a; + e= 0; + while(get_rac(c, state+1 + e)){ //1..10 + e++; + } + assert(e<=9); + + a= 1; + for(i=e-1; i>=0; i--){ + a += a + get_rac(c, state+22 + i); //22..31 + } + + if(is_signed && get_rac(c, state+11 + e)) //11..21 + return -a; + else + return a; + } +} + +static inline void update_vlc_state(VlcState * const state, const int v){ + int drift= state->drift; + int count= state->count; + state->error_sum += ABS(v); + drift += v; + + if(count == 128){ //FIXME variable + count >>= 1; + drift >>= 1; + state->error_sum >>= 1; + } + count++; + + if(drift <= -count){ + if(state->bias > -128) state->bias--; + + drift += count; + if(drift <= -count) + drift= -count + 1; + }else if(drift > 0){ + if(state->bias < 127) state->bias++; + + drift -= count; + if(drift > 0) + drift= 0; + } + + state->drift= drift; + state->count= count; +} + +static inline void put_vlc_symbol(PutBitContext *pb, VlcState * const state, int v, int bits){ + int i, k, code; +//printf("final: %d ", v); + v = fold(v - state->bias, bits); + + i= state->count; + k=0; + while(i < state->error_sum){ //FIXME optimize + k++; + i += i; + } + + assert(k<=8); + +#if 0 // JPEG LS + if(k==0 && 2*state->drift <= - state->count) code= v ^ (-1); + else code= v; +#else + code= v ^ ((2*state->drift + state->count)>>31); +#endif + +//printf("v:%d/%d bias:%d error:%d drift:%d count:%d k:%d\n", v, code, state->bias, state->error_sum, state->drift, state->count, k); + set_sr_golomb(pb, code, k, 12, bits); + + update_vlc_state(state, v); +} + +static inline int get_vlc_symbol(GetBitContext *gb, VlcState * const state, int bits){ + int k, i, v, ret; + + i= state->count; + k=0; + while(i < state->error_sum){ //FIXME optimize + k++; + i += i; + } + + assert(k<=8); + + v= get_sr_golomb(gb, k, 12, bits); +//printf("v:%d bias:%d error:%d drift:%d count:%d k:%d", v, state->bias, state->error_sum, state->drift, state->count, k); + +#if 0 // JPEG LS + if(k==0 && 2*state->drift <= - state->count) v ^= (-1); +#else + v ^= ((2*state->drift + state->count)>>31); +#endif + + ret= fold(v + state->bias, bits); + + update_vlc_state(state, v); +//printf("final: %d\n", ret); + return ret; +} + +static inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){ + PlaneContext * const p= &s->plane[plane_index]; + RangeCoder * const c= &s->c; + int x; + int run_index= s->run_index; + int run_count=0; + int run_mode=0; + + if(s->ac){ + if(c->bytestream_end - c->bytestream < w*20){ + av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + }else{ + if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < w*4){ + av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + } + + for(x=0; xac){ + put_symbol(c, p->state[context], diff, 1); + }else{ + if(context == 0) run_mode=1; + + if(run_mode){ + + if(diff){ + while(run_count >= 1<pb, 1, 1); + } + + put_bits(&s->pb, 1 + log2_run[run_index], run_count); + if(run_index) run_index--; + run_count=0; + run_mode=0; + if(diff>0) diff--; + }else{ + run_count++; + } + } + +// printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, (int)put_bits_count(&s->pb)); + + if(run_mode == 0) + put_vlc_symbol(&s->pb, &p->vlc_state[context], diff, bits); + } + } + if(run_mode){ + while(run_count >= 1<pb, 1, 1); + } + + if(run_count) + put_bits(&s->pb, 1, 1); + } + s->run_index= run_index; + + return 0; +} + +static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ + int x,y,i; + const int ring_size= s->avctx->context_model ? 3 : 2; + int_fast16_t sample_buffer[ring_size][w+6], *sample[ring_size]; + s->run_index=0; + + memset(sample_buffer, 0, sizeof(sample_buffer)); + + for(y=0; yavctx->context_model ? 3 : 2; + int_fast16_t sample_buffer[3][ring_size][w+6], *sample[3][ring_size]; + s->run_index=0; + + memset(sample_buffer, 0, sizeof(sample_buffer)); + + for(y=0; y>8)&0xFF; + int r= (v>>16)&0xFF; + + b -= g; + r -= g; + g += (b + r)>>2; + b += 0x100; + r += 0x100; + +// assert(g>=0 && b>=0 && r>=0); +// assert(g<256 && b<512 && r<512); + sample[0][0][x]= g; + sample[1][0][x]= b; + sample[2][0][x]= r; + } + for(p=0; p<3; p++){ + sample[p][0][-1]= sample[p][1][0 ]; + sample[p][1][ w]= sample[p][1][w-1]; + encode_line(s, w, sample[p], FFMIN(p, 1), 9); + } + } +} + +static void write_quant_table(RangeCoder *c, int16_t *quant_table){ + int last=0; + int i; + uint8_t state[CONTEXT_SIZE]; + memset(state, 128, sizeof(state)); + + for(i=1; i<128 ; i++){ + if(quant_table[i] != quant_table[i-1]){ + put_symbol(c, state, i-last-1, 0); + last= i; + } + } + put_symbol(c, state, i-last-1, 0); +} + +static void write_header(FFV1Context *f){ + uint8_t state[CONTEXT_SIZE]; + int i; + RangeCoder * const c= &f->c; + + memset(state, 128, sizeof(state)); + + put_symbol(c, state, f->version, 0); + put_symbol(c, state, f->avctx->coder_type, 0); + put_symbol(c, state, f->colorspace, 0); //YUV cs type + put_rac(c, state, 1); //chroma planes + put_symbol(c, state, f->chroma_h_shift, 0); + put_symbol(c, state, f->chroma_v_shift, 0); + put_rac(c, state, 0); //no transparency plane + + for(i=0; i<5; i++) + write_quant_table(c, f->quant_table[i]); +} + +static int common_init(AVCodecContext *avctx){ + FFV1Context *s = avctx->priv_data; + int width, height; + + s->avctx= avctx; + s->flags= avctx->flags; + + dsputil_init(&s->dsp, avctx); + + width= s->width= avctx->width; + height= s->height= avctx->height; + + assert(width && height); + + return 0; +} + +static int encode_init(AVCodecContext *avctx) +{ + FFV1Context *s = avctx->priv_data; + int i; + + common_init(avctx); + + s->version=0; + s->ac= avctx->coder_type; + + s->plane_count=2; + for(i=0; i<256; i++){ + s->quant_table[0][i]= quant11[i]; + s->quant_table[1][i]= 11*quant11[i]; + if(avctx->context_model==0){ + s->quant_table[2][i]= 11*11*quant11[i]; + s->quant_table[3][i]= + s->quant_table[4][i]=0; + }else{ + s->quant_table[2][i]= 11*11*quant5 [i]; + s->quant_table[3][i]= 5*11*11*quant5 [i]; + s->quant_table[4][i]= 5*5*11*11*quant5 [i]; + } + } + + for(i=0; iplane_count; i++){ + PlaneContext * const p= &s->plane[i]; + + if(avctx->context_model==0){ + p->context_count= (11*11*11+1)/2; + }else{ + p->context_count= (11*11*5*5*5+1)/2; + } + + if(s->ac){ + if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t)); + }else{ + if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState)); + } + } + + avctx->coded_frame= &s->picture; + switch(avctx->pix_fmt){ + case PIX_FMT_YUV444P: + case PIX_FMT_YUV422P: + case PIX_FMT_YUV420P: + case PIX_FMT_YUV411P: + case PIX_FMT_YUV410P: + s->colorspace= 0; + break; + case PIX_FMT_RGBA32: + s->colorspace= 1; + break; + default: + av_log(avctx, AV_LOG_ERROR, "format not supported\n"); + return -1; + } + avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); + + s->picture_number=0; + + return 0; +} + + +static void clear_state(FFV1Context *f){ + int i, j; + + for(i=0; iplane_count; i++){ + PlaneContext *p= &f->plane[i]; + + p->interlace_bit_state[0]= 128; + p->interlace_bit_state[1]= 128; + + for(j=0; jcontext_count; j++){ + if(f->ac){ + memset(p->state[j], 128, sizeof(uint8_t)*CONTEXT_SIZE); + }else{ + p->vlc_state[j].drift= 0; + p->vlc_state[j].error_sum= 4; //FFMAX((RANGE + 32)/64, 2); + p->vlc_state[j].bias= 0; + p->vlc_state[j].count= 1; + } + } + } +} + +static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + FFV1Context *f = avctx->priv_data; + RangeCoder * const c= &f->c; + AVFrame *pict = data; + const int width= f->width; + const int height= f->height; + AVFrame * const p= &f->picture; + int used_count= 0; + uint8_t keystate=128; + + ff_init_range_encoder(c, buf, buf_size); +// ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); + ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); + + *p = *pict; + p->pict_type= FF_I_TYPE; + + if(avctx->gop_size==0 || f->picture_number % avctx->gop_size == 0){ + put_rac(c, &keystate, 1); + p->key_frame= 1; + write_header(f); + clear_state(f); + }else{ + put_rac(c, &keystate, 0); + p->key_frame= 0; + } + + if(!f->ac){ + used_count += ff_rac_terminate(c); +//printf("pos=%d\n", used_count); + init_put_bits(&f->pb, buf + used_count, buf_size - used_count); + } + + if(f->colorspace==0){ + const int chroma_width = -((-width )>>f->chroma_h_shift); + const int chroma_height= -((-height)>>f->chroma_v_shift); + + encode_plane(f, p->data[0], width, height, p->linesize[0], 0); + + encode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1); + encode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1); + }else{ + encode_rgb_frame(f, (uint32_t*)(p->data[0]), width, height, p->linesize[0]/4); + } + emms_c(); + + f->picture_number++; + + if(f->ac){ + return ff_rac_terminate(c); + }else{ + flush_put_bits(&f->pb); //nicer padding FIXME + return used_count + (put_bits_count(&f->pb)+7)/8; + } +} + +static void common_end(FFV1Context *s){ + int i; + + for(i=0; iplane_count; i++){ + PlaneContext *p= &s->plane[i]; + + av_freep(&p->state); + } +} + +static int encode_end(AVCodecContext *avctx) +{ + FFV1Context *s = avctx->priv_data; + + common_end(s); + + return 0; +} + +static inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){ + PlaneContext * const p= &s->plane[plane_index]; + RangeCoder * const c= &s->c; + int x; + int run_count=0; + int run_mode=0; + int run_index= s->run_index; + + for(x=0; xac){ + diff= get_symbol(c, p->state[context], 1); + }else{ + if(context == 0 && run_mode==0) run_mode=1; + + if(run_mode){ + if(run_count==0 && run_mode==1){ + if(get_bits1(&s->gb)){ + run_count = 1<gb, log2_run[run_index]); + else run_count=0; + if(run_index) run_index--; + run_mode=2; + } + } + run_count--; + if(run_count < 0){ + run_mode=0; + run_count=0; + diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); + if(diff>=0) diff++; + }else + diff=0; + }else + diff= get_vlc_symbol(&s->gb, &p->vlc_state[context], bits); + +// printf("count:%d index:%d, mode:%d, x:%d y:%d pos:%d\n", run_count, run_index, run_mode, x, y, get_bits_count(&s->gb)); + } + + if(sign) diff= -diff; + + sample[1][x]= (predict(sample[1] + x, sample[0] + x) + diff) & ((1<run_index= run_index; +} + +static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){ + int x, y; + int_fast16_t sample_buffer[2][w+6]; + int_fast16_t *sample[2]= {sample_buffer[0]+3, sample_buffer[1]+3}; + + s->run_index=0; + + memset(sample_buffer, 0, sizeof(sample_buffer)); + + for(y=0; yrun_index=0; + + memset(sample_buffer, 0, sizeof(sample_buffer)); + + for(y=0; y=0 && b>=0 && r>=0); +// assert(g<256 && b<512 && r<512); + + b -= 0x100; + r -= 0x100; + g -= (b + r)>>2; + b += g; + r += g; + + src[x + stride*y]= b + (g<<8) + (r<<16); + } + } +} + +static int read_quant_table(RangeCoder *c, int16_t *quant_table, int scale){ + int v; + int i=0; + uint8_t state[CONTEXT_SIZE]; + + memset(state, 128, sizeof(state)); + + for(v=0; i<128 ; v++){ + int len= get_symbol(c, state, 0) + 1; + + if(len + i > 128) return -1; + + while(len--){ + quant_table[i] = scale*v; + i++; +//printf("%2d ",v); +//if(i%16==0) printf("\n"); + } + } + + for(i=1; i<128; i++){ + quant_table[256-i]= -quant_table[i]; + } + quant_table[128]= -quant_table[127]; + + return 2*v - 1; +} + +static int read_header(FFV1Context *f){ + uint8_t state[CONTEXT_SIZE]; + int i, context_count; + RangeCoder * const c= &f->c; + + memset(state, 128, sizeof(state)); + + f->version= get_symbol(c, state, 0); + f->ac= f->avctx->coder_type= get_symbol(c, state, 0); + f->colorspace= get_symbol(c, state, 0); //YUV cs type + get_rac(c, state); //no chroma = false + f->chroma_h_shift= get_symbol(c, state, 0); + f->chroma_v_shift= get_symbol(c, state, 0); + get_rac(c, state); //transparency plane + f->plane_count= 2; + + if(f->colorspace==0){ + switch(16*f->chroma_h_shift + f->chroma_v_shift){ + case 0x00: f->avctx->pix_fmt= PIX_FMT_YUV444P; break; + case 0x10: f->avctx->pix_fmt= PIX_FMT_YUV422P; break; + case 0x11: f->avctx->pix_fmt= PIX_FMT_YUV420P; break; + case 0x20: f->avctx->pix_fmt= PIX_FMT_YUV411P; break; + case 0x22: f->avctx->pix_fmt= PIX_FMT_YUV410P; break; + default: + av_log(f->avctx, AV_LOG_ERROR, "format not supported\n"); + return -1; + } + }else if(f->colorspace==1){ + if(f->chroma_h_shift || f->chroma_v_shift){ + av_log(f->avctx, AV_LOG_ERROR, "chroma subsampling not supported in this colorspace\n"); + return -1; + } + f->avctx->pix_fmt= PIX_FMT_RGBA32; + }else{ + av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n"); + return -1; + } + +//printf("%d %d %d\n", f->chroma_h_shift, f->chroma_v_shift,f->avctx->pix_fmt); + + context_count=1; + for(i=0; i<5; i++){ + context_count*= read_quant_table(c, f->quant_table[i], context_count); + if(context_count < 0 || context_count > 32768){ + av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n"); + return -1; + } + } + context_count= (context_count+1)/2; + + for(i=0; iplane_count; i++){ + PlaneContext * const p= &f->plane[i]; + + p->context_count= context_count; + + if(f->ac){ + if(!p->state) p->state= av_malloc(CONTEXT_SIZE*p->context_count*sizeof(uint8_t)); + }else{ + if(!p->vlc_state) p->vlc_state= av_malloc(p->context_count*sizeof(VlcState)); + } + } + + return 0; +} + +static int decode_init(AVCodecContext *avctx) +{ +// FFV1Context *s = avctx->priv_data; + + common_init(avctx); + + return 0; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){ + FFV1Context *f = avctx->priv_data; + RangeCoder * const c= &f->c; + const int width= f->width; + const int height= f->height; + AVFrame * const p= &f->picture; + int bytes_read; + uint8_t keystate= 128; + + AVFrame *picture = data; + + ff_init_range_decoder(c, buf, buf_size); + ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); + + + p->pict_type= FF_I_TYPE; //FIXME I vs. P + if(get_rac(c, &keystate)){ + p->key_frame= 1; + if(read_header(f) < 0) + return -1; + clear_state(f); + }else{ + p->key_frame= 0; + } + if(!f->plane[0].state && !f->plane[0].vlc_state) + return -1; + + p->reference= 0; + if(avctx->get_buffer(avctx, p) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + if(avctx->debug&FF_DEBUG_PICT_INFO) + av_log(avctx, AV_LOG_ERROR, "keyframe:%d coder:%d\n", p->key_frame, f->ac); + + if(!f->ac){ + bytes_read = c->bytestream - c->bytestream_start - 1; + if(bytes_read ==0) av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n"); //FIXME +//printf("pos=%d\n", bytes_read); + init_get_bits(&f->gb, buf + bytes_read, buf_size - bytes_read); + } else { + bytes_read = 0; /* avoid warning */ + } + + if(f->colorspace==0){ + const int chroma_width = -((-width )>>f->chroma_h_shift); + const int chroma_height= -((-height)>>f->chroma_v_shift); + decode_plane(f, p->data[0], width, height, p->linesize[0], 0); + + decode_plane(f, p->data[1], chroma_width, chroma_height, p->linesize[1], 1); + decode_plane(f, p->data[2], chroma_width, chroma_height, p->linesize[2], 1); + }else{ + decode_rgb_frame(f, (uint32_t*)p->data[0], width, height, p->linesize[0]/4); + } + + emms_c(); + + f->picture_number++; + + *picture= *p; + + avctx->release_buffer(avctx, p); //FIXME + + *data_size = sizeof(AVFrame); + + if(f->ac){ + bytes_read= c->bytestream - c->bytestream_start - 1; + if(bytes_read ==0) av_log(f->avctx, AV_LOG_ERROR, "error at end of frame\n"); + }else{ + bytes_read+= (get_bits_count(&f->gb)+7)/8; + } + + return bytes_read; +} + +AVCodec ffv1_decoder = { + "ffv1", + CODEC_TYPE_VIDEO, + CODEC_ID_FFV1, + sizeof(FFV1Context), + decode_init, + NULL, + NULL, + decode_frame, + CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/, + NULL +}; + +#ifdef CONFIG_ENCODERS +AVCodec ffv1_encoder = { + "ffv1", + CODEC_TYPE_VIDEO, + CODEC_ID_FFV1, + sizeof(FFV1Context), + encode_init, + encode_frame, + encode_end, +}; +#endif diff --git a/mpeg4/src/libavcodec/flac.c b/mpeg4/src/libavcodec/flac.c new file mode 100644 index 00000000..8710e21d --- /dev/null +++ b/mpeg4/src/libavcodec/flac.c @@ -0,0 +1,779 @@ +/* + * FLAC (Free Lossless Audio Codec) decoder + * Copyright (c) 2003 Alex Beregszaszi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file flac.c + * FLAC (Free Lossless Audio Codec) decoder + * @author Alex Beregszaszi + * + * For more information on the FLAC format, visit: + * http://flac.sourceforge.net/ + * + * This decoder can be used in 1 of 2 ways: Either raw FLAC data can be fed + * through, starting from the initial 'fLaC' signature; or by passing the + * 34-byte streaminfo structure through avctx->extradata[_size] followed + * by data starting with the 0xFFF8 marker. + */ + +#include + +#include "avcodec.h" +#include "bitstream.h" +#include "golomb.h" +#include "crc.h" + +#undef NDEBUG +#include + +#define MAX_CHANNELS 8 +#define MAX_BLOCKSIZE 65535 +#define FLAC_STREAMINFO_SIZE 34 + +enum decorrelation_type { + INDEPENDENT, + LEFT_SIDE, + RIGHT_SIDE, + MID_SIDE, +}; + +typedef struct FLACContext { + AVCodecContext *avctx; + GetBitContext gb; + + int min_blocksize, max_blocksize; + int min_framesize, max_framesize; + int samplerate, channels; + int blocksize/*, last_blocksize*/; + int bps, curr_bps; + enum decorrelation_type decorrelation; + + int32_t *decoded[MAX_CHANNELS]; + uint8_t *bitstream; + int bitstream_size; + int bitstream_index; + unsigned int allocated_bitstream_size; +} FLACContext; + +#define METADATA_TYPE_STREAMINFO 0 + +static int sample_rate_table[] = +{ 0, 0, 0, 0, + 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, + 0, 0, 0, 0 }; + +static int sample_size_table[] = +{ 0, 8, 12, 0, 16, 20, 24, 0 }; + +static int blocksize_table[] = { + 0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0, +256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7 +}; + +static int64_t get_utf8(GetBitContext *gb) +{ + uint64_t val; + int ones=0, bytes; + + while(get_bits1(gb)) + ones++; + + if (ones==0) bytes=0; + else if(ones==1) return -1; + else bytes= ones - 1; + + val= get_bits(gb, 7-ones); + while(bytes--){ + const int tmp = get_bits(gb, 8); + + if((tmp>>6) != 2) + return -1; + val<<=6; + val|= tmp&0x3F; + } + return val; +} + +#if 0 +static int skip_utf8(GetBitContext *gb) +{ + int ones=0, bytes; + + while(get_bits1(gb)) + ones++; + + if (ones==0) bytes=0; + else if(ones==1) return -1; + else bytes= ones - 1; + + skip_bits(gb, 7-ones); + while(bytes--){ + const int tmp = get_bits(gb, 8); + + if((tmp>>6) != 2) + return -1; + } + return 0; +} +#endif + +static void metadata_streaminfo(FLACContext *s); +static void dump_headers(FLACContext *s); + +static int flac_decode_init(AVCodecContext * avctx) +{ + FLACContext *s = avctx->priv_data; + s->avctx = avctx; + + /* initialize based on the demuxer-supplied streamdata header */ + if (avctx->extradata_size == FLAC_STREAMINFO_SIZE) { + init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8); + metadata_streaminfo(s); + dump_headers(s); + } + + return 0; +} + +static void dump_headers(FLACContext *s) +{ + av_log(s->avctx, AV_LOG_DEBUG, " Blocksize: %d .. %d (%d)\n", s->min_blocksize, s->max_blocksize, s->blocksize); + av_log(s->avctx, AV_LOG_DEBUG, " Framesize: %d .. %d\n", s->min_framesize, s->max_framesize); + av_log(s->avctx, AV_LOG_DEBUG, " Samplerate: %d\n", s->samplerate); + av_log(s->avctx, AV_LOG_DEBUG, " Channels: %d\n", s->channels); + av_log(s->avctx, AV_LOG_DEBUG, " Bits: %d\n", s->bps); +} + +static void allocate_buffers(FLACContext *s){ + int i; + + assert(s->max_blocksize); + + if(s->max_framesize == 0 && s->max_blocksize){ + s->max_framesize= (s->channels * s->bps * s->max_blocksize + 7)/ 8; //FIXME header overhead + } + + for (i = 0; i < s->channels; i++) + { + s->decoded[i] = av_realloc(s->decoded[i], sizeof(int32_t)*s->max_blocksize); + } + + s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); +} + +static void metadata_streaminfo(FLACContext *s) +{ + /* mandatory streaminfo */ + s->min_blocksize = get_bits(&s->gb, 16); + s->max_blocksize = get_bits(&s->gb, 16); + + s->min_framesize = get_bits_long(&s->gb, 24); + s->max_framesize = get_bits_long(&s->gb, 24); + + s->samplerate = get_bits_long(&s->gb, 20); + s->channels = get_bits(&s->gb, 3) + 1; + s->bps = get_bits(&s->gb, 5) + 1; + + s->avctx->channels = s->channels; + s->avctx->sample_rate = s->samplerate; + + skip_bits(&s->gb, 36); /* total num of samples */ + + skip_bits(&s->gb, 64); /* md5 sum */ + skip_bits(&s->gb, 64); /* md5 sum */ + + allocate_buffers(s); +} + +static int decode_residuals(FLACContext *s, int channel, int pred_order) +{ + int i, tmp, partition, method_type, rice_order; + int sample = 0, samples; + + method_type = get_bits(&s->gb, 2); + if (method_type != 0){ + av_log(s->avctx, AV_LOG_DEBUG, "illegal residual coding method %d\n", method_type); + return -1; + } + + rice_order = get_bits(&s->gb, 4); + + samples= s->blocksize >> rice_order; + + sample= + i= pred_order; + for (partition = 0; partition < (1 << rice_order); partition++) + { + tmp = get_bits(&s->gb, 4); + if (tmp == 15) + { + av_log(s->avctx, AV_LOG_DEBUG, "fixed len partition\n"); + tmp = get_bits(&s->gb, 5); + for (; i < samples; i++, sample++) + s->decoded[channel][sample] = get_sbits(&s->gb, tmp); + } + else + { +// av_log(s->avctx, AV_LOG_DEBUG, "rice coded partition k=%d\n", tmp); + for (; i < samples; i++, sample++){ + s->decoded[channel][sample] = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0); + } + } + i= 0; + } + +// av_log(s->avctx, AV_LOG_DEBUG, "partitions: %d, samples: %d\n", 1 << rice_order, sample); + + return 0; +} + +static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) +{ + int i; + +// av_log(s->avctx, AV_LOG_DEBUG, " SUBFRAME FIXED\n"); + + /* warm up samples */ +// av_log(s->avctx, AV_LOG_DEBUG, " warm up samples: %d\n", pred_order); + + for (i = 0; i < pred_order; i++) + { + s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps); +// av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, s->decoded[channel][i]); + } + + if (decode_residuals(s, channel, pred_order) < 0) + return -1; + + switch(pred_order) + { + case 0: + break; + case 1: + for (i = pred_order; i < s->blocksize; i++) + s->decoded[channel][i] += s->decoded[channel][i-1]; + break; + case 2: + for (i = pred_order; i < s->blocksize; i++) + s->decoded[channel][i] += 2*s->decoded[channel][i-1] + - s->decoded[channel][i-2]; + break; + case 3: + for (i = pred_order; i < s->blocksize; i++) + s->decoded[channel][i] += 3*s->decoded[channel][i-1] + - 3*s->decoded[channel][i-2] + + s->decoded[channel][i-3]; + break; + case 4: + for (i = pred_order; i < s->blocksize; i++) + s->decoded[channel][i] += 4*s->decoded[channel][i-1] + - 6*s->decoded[channel][i-2] + + 4*s->decoded[channel][i-3] + - s->decoded[channel][i-4]; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); + return -1; + } + + return 0; +} + +static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) +{ + int sum, i, j; + int coeff_prec, qlevel; + int coeffs[pred_order]; + +// av_log(s->avctx, AV_LOG_DEBUG, " SUBFRAME LPC\n"); + + /* warm up samples */ +// av_log(s->avctx, AV_LOG_DEBUG, " warm up samples: %d\n", pred_order); + + for (i = 0; i < pred_order; i++) + { + s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps); +// av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, s->decoded[channel][i]); + } + + coeff_prec = get_bits(&s->gb, 4) + 1; + if (coeff_prec == 16) + { + av_log(s->avctx, AV_LOG_DEBUG, "invalid coeff precision\n"); + return -1; + } +// av_log(s->avctx, AV_LOG_DEBUG, " qlp coeff prec: %d\n", coeff_prec); + qlevel = get_sbits(&s->gb, 5); +// av_log(s->avctx, AV_LOG_DEBUG, " quant level: %d\n", qlevel); + if(qlevel < 0){ + av_log(s->avctx, AV_LOG_DEBUG, "qlevel %d not supported, maybe buggy stream\n", qlevel); + return -1; + } + + for (i = 0; i < pred_order; i++) + { + coeffs[i] = get_sbits(&s->gb, coeff_prec); +// av_log(s->avctx, AV_LOG_DEBUG, " %d: %d\n", i, coeffs[i]); + } + + if (decode_residuals(s, channel, pred_order) < 0) + return -1; + + for (i = pred_order; i < s->blocksize; i++) + { + sum = 0; + for (j = 0; j < pred_order; j++) + sum += coeffs[j] * s->decoded[channel][i-j-1]; + s->decoded[channel][i] += sum >> qlevel; + } + + return 0; +} + +static inline int decode_subframe(FLACContext *s, int channel) +{ + int type, wasted = 0; + int i, tmp; + + s->curr_bps = s->bps; + if(channel == 0){ + if(s->decorrelation == RIGHT_SIDE) + s->curr_bps++; + }else{ + if(s->decorrelation == LEFT_SIDE || s->decorrelation == MID_SIDE) + s->curr_bps++; + } + + if (get_bits1(&s->gb)) + { + av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n"); + return -1; + } + type = get_bits(&s->gb, 6); +// wasted = get_bits1(&s->gb); + +// if (wasted) +// { +// while (!get_bits1(&s->gb)) +// wasted++; +// if (wasted) +// wasted++; +// s->curr_bps -= wasted; +// } +#if 0 + wasted= 16 - av_log2(show_bits(&s->gb, 17)); + skip_bits(&s->gb, wasted+1); + s->curr_bps -= wasted; +#else + if (get_bits1(&s->gb)) + { + wasted = 1; + while (!get_bits1(&s->gb)) + wasted++; + s->curr_bps -= wasted; + av_log(s->avctx, AV_LOG_DEBUG, "%d wasted bits\n", wasted); + } +#endif +//FIXME use av_log2 for types + if (type == 0) + { + av_log(s->avctx, AV_LOG_DEBUG, "coding type: constant\n"); + tmp = get_sbits(&s->gb, s->curr_bps); + for (i = 0; i < s->blocksize; i++) + s->decoded[channel][i] = tmp; + } + else if (type == 1) + { + av_log(s->avctx, AV_LOG_DEBUG, "coding type: verbatim\n"); + for (i = 0; i < s->blocksize; i++) + s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps); + } + else if ((type >= 8) && (type <= 12)) + { +// av_log(s->avctx, AV_LOG_DEBUG, "coding type: fixed\n"); + if (decode_subframe_fixed(s, channel, type & ~0x8) < 0) + return -1; + } + else if (type >= 32) + { +// av_log(s->avctx, AV_LOG_DEBUG, "coding type: lpc\n"); + if (decode_subframe_lpc(s, channel, (type & ~0x20)+1) < 0) + return -1; + } + else + { + av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n"); + return -1; + } + + if (wasted) + { + int i; + for (i = 0; i < s->blocksize; i++) + s->decoded[channel][i] <<= wasted; + } + + return 0; +} + +static int decode_frame(FLACContext *s) +{ + int blocksize_code, sample_rate_code, sample_size_code, assignment, i, crc8; + int decorrelation, bps, blocksize, samplerate; + + blocksize_code = get_bits(&s->gb, 4); + + sample_rate_code = get_bits(&s->gb, 4); + + assignment = get_bits(&s->gb, 4); /* channel assignment */ + if (assignment < 8 && s->channels == assignment+1) + decorrelation = INDEPENDENT; + else if (assignment >=8 && assignment < 11 && s->channels == 2) + decorrelation = LEFT_SIDE + assignment - 8; + else + { + av_log(s->avctx, AV_LOG_ERROR, "unsupported channel assignment %d (channels=%d)\n", assignment, s->channels); + return -1; + } + + sample_size_code = get_bits(&s->gb, 3); + if(sample_size_code == 0) + bps= s->bps; + else if((sample_size_code != 3) && (sample_size_code != 7)) + bps = sample_size_table[sample_size_code]; + else + { + av_log(s->avctx, AV_LOG_ERROR, "invalid sample size code (%d)\n", sample_size_code); + return -1; + } + + if (get_bits1(&s->gb)) + { + av_log(s->avctx, AV_LOG_ERROR, "broken stream, invalid padding\n"); + return -1; + } + + if(get_utf8(&s->gb) < 0){ + av_log(s->avctx, AV_LOG_ERROR, "utf8 fscked\n"); + return -1; + } +#if 0 + if (/*((blocksize_code == 6) || (blocksize_code == 7)) &&*/ + (s->min_blocksize != s->max_blocksize)){ + }else{ + } +#endif + + if (blocksize_code == 0) + blocksize = s->min_blocksize; + else if (blocksize_code == 6) + blocksize = get_bits(&s->gb, 8)+1; + else if (blocksize_code == 7) + blocksize = get_bits(&s->gb, 16)+1; + else + blocksize = blocksize_table[blocksize_code]; + + if(blocksize > s->max_blocksize){ + av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", blocksize, s->max_blocksize); + return -1; + } + + if (sample_rate_code == 0){ + samplerate= s->samplerate; + }else if ((sample_rate_code > 3) && (sample_rate_code < 12)) + samplerate = sample_rate_table[sample_rate_code]; + else if (sample_rate_code == 12) + samplerate = get_bits(&s->gb, 8) * 1000; + else if (sample_rate_code == 13) + samplerate = get_bits(&s->gb, 16); + else if (sample_rate_code == 14) + samplerate = get_bits(&s->gb, 16) * 10; + else{ + av_log(s->avctx, AV_LOG_ERROR, "illegal sample rate code %d\n", sample_rate_code); + return -1; + } + + skip_bits(&s->gb, 8); + crc8= av_crc(av_crc07, 0, s->gb.buffer, get_bits_count(&s->gb)/8); + if(crc8){ + av_log(s->avctx, AV_LOG_ERROR, "header crc mismatch crc=%2X\n", crc8); + return -1; + } + + s->blocksize = blocksize; + s->samplerate = samplerate; + s->bps = bps; + s->decorrelation= decorrelation; + +// dump_headers(s); + + /* subframes */ + for (i = 0; i < s->channels; i++) + { +// av_log(s->avctx, AV_LOG_DEBUG, "decoded: %x residual: %x\n", s->decoded[i], s->residual[i]); + if (decode_subframe(s, i) < 0) + return -1; + } + + align_get_bits(&s->gb); + + /* frame footer */ + skip_bits(&s->gb, 16); /* data crc */ + + return 0; +} + +static int flac_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + FLACContext *s = avctx->priv_data; + int metadata_last, metadata_type, metadata_size; + int tmp = 0, i, j = 0, input_buf_size = 0; + int16_t *samples = data; + + if(s->max_framesize == 0){ + s->max_framesize= 65536; // should hopefully be enough for the first header + s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); + } + + if(1 && s->max_framesize){//FIXME truncated + buf_size= FFMAX(FFMIN(buf_size, s->max_framesize - s->bitstream_size), 0); + input_buf_size= buf_size; + + if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){ +// printf("memmove\n"); + memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size); + s->bitstream_index=0; + } + memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size); + buf= &s->bitstream[s->bitstream_index]; + buf_size += s->bitstream_size; + s->bitstream_size= buf_size; + + if(buf_size < s->max_framesize){ +// printf("wanna more data ...\n"); + return input_buf_size; + } + } + + init_get_bits(&s->gb, buf, buf_size*8); + + /* fLaC signature (be) */ + if (show_bits_long(&s->gb, 32) == bswap_32(ff_get_fourcc("fLaC"))) + { + skip_bits(&s->gb, 32); + + av_log(s->avctx, AV_LOG_DEBUG, "STREAM HEADER\n"); + do { + metadata_last = get_bits(&s->gb, 1); + metadata_type = get_bits(&s->gb, 7); + metadata_size = get_bits_long(&s->gb, 24); + + av_log(s->avctx, AV_LOG_DEBUG, " metadata block: flag = %d, type = %d, size = %d\n", + metadata_last, metadata_type, + metadata_size); + if(metadata_size){ + switch(metadata_type) + { + case METADATA_TYPE_STREAMINFO:{ + metadata_streaminfo(s); + + /* Buffer might have been reallocated, reinit bitreader */ + if(buf != &s->bitstream[s->bitstream_index]) + { + int bits_count = get_bits_count(&s->gb); + buf= &s->bitstream[s->bitstream_index]; + init_get_bits(&s->gb, buf, buf_size*8); + skip_bits(&s->gb, bits_count); + } + + dump_headers(s); + break;} + default: + for(i=0; igb, 8); + } + } + } while(!metadata_last); + } + else + { + + tmp = show_bits(&s->gb, 16); + if(tmp != 0xFFF8){ + av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); + while(get_bits_count(&s->gb)/8+2 < buf_size && show_bits(&s->gb, 16) != 0xFFF8) + skip_bits(&s->gb, 8); + goto end; // we may not have enough bits left to decode a frame, so try next time + } + skip_bits(&s->gb, 16); + if (decode_frame(s) < 0){ + av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n"); + s->bitstream_size=0; + s->bitstream_index=0; + return -1; + } + } + + +#if 0 + /* fix the channel order here */ + if (s->order == MID_SIDE) + { + short *left = samples; + short *right = samples + s->blocksize; + for (i = 0; i < s->blocksize; i += 2) + { + uint32_t x = s->decoded[0][i]; + uint32_t y = s->decoded[0][i+1]; + + right[i] = x - (y / 2); + left[i] = right[i] + y; + } + *data_size = 2 * s->blocksize; + } + else + { + for (i = 0; i < s->channels; i++) + { + switch(s->order) + { + case INDEPENDENT: + for (j = 0; j < s->blocksize; j++) + samples[(s->blocksize*i)+j] = s->decoded[i][j]; + break; + case LEFT_SIDE: + case RIGHT_SIDE: + if (i == 0) + for (j = 0; j < s->blocksize; j++) + samples[(s->blocksize*i)+j] = s->decoded[0][j]; + else + for (j = 0; j < s->blocksize; j++) + samples[(s->blocksize*i)+j] = s->decoded[0][j] - s->decoded[i][j]; + break; +// case MID_SIDE: +// av_log(s->avctx, AV_LOG_DEBUG, "mid-side unsupported\n"); + } + *data_size += s->blocksize; + } + } +#else + switch(s->decorrelation) + { + case INDEPENDENT: + for (j = 0; j < s->blocksize; j++) + { + for (i = 0; i < s->channels; i++) + *(samples++) = s->decoded[i][j]; + } + break; + case LEFT_SIDE: + assert(s->channels == 2); + for (i = 0; i < s->blocksize; i++) + { + *(samples++) = s->decoded[0][i]; + *(samples++) = s->decoded[0][i] - s->decoded[1][i]; + } + break; + case RIGHT_SIDE: + assert(s->channels == 2); + for (i = 0; i < s->blocksize; i++) + { + *(samples++) = s->decoded[0][i] + s->decoded[1][i]; + *(samples++) = s->decoded[1][i]; + } + break; + case MID_SIDE: + assert(s->channels == 2); + for (i = 0; i < s->blocksize; i++) + { + int mid, side; + mid = s->decoded[0][i]; + side = s->decoded[1][i]; + +#if 1 //needs to be checked but IMHO it should be binary identical + mid -= side>>1; + *(samples++) = mid + side; + *(samples++) = mid; +#else + + mid <<= 1; + if (side & 1) + mid++; + *(samples++) = (mid + side) >> 1; + *(samples++) = (mid - side) >> 1; +#endif + } + break; + } +#endif + + *data_size = (int8_t *)samples - (int8_t *)data; +// av_log(s->avctx, AV_LOG_DEBUG, "data size: %d\n", *data_size); + +// s->last_blocksize = s->blocksize; +end: + i= (get_bits_count(&s->gb)+7)/8;; + if(i > buf_size){ + av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size); + s->bitstream_size=0; + s->bitstream_index=0; + return -1; + } + + if(s->bitstream_size){ + s->bitstream_index += i; + s->bitstream_size -= i; + return input_buf_size; + }else + return i; +} + +static int flac_decode_close(AVCodecContext *avctx) +{ + FLACContext *s = avctx->priv_data; + int i; + + for (i = 0; i < s->channels; i++) + { + av_freep(&s->decoded[i]); + } + av_freep(&s->bitstream); + + return 0; +} + +static void flac_flush(AVCodecContext *avctx){ + FLACContext *s = avctx->priv_data; + + s->bitstream_size= + s->bitstream_index= 0; +} + +AVCodec flac_decoder = { + "flac", + CODEC_TYPE_AUDIO, + CODEC_ID_FLAC, + sizeof(FLACContext), + flac_decode_init, + NULL, + flac_decode_close, + flac_decode_frame, + .flush= flac_flush, +}; diff --git a/mpeg4/src/libavcodec/flicvideo.c b/mpeg4/src/libavcodec/flicvideo.c new file mode 100644 index 00000000..fa128d0d --- /dev/null +++ b/mpeg4/src/libavcodec/flicvideo.c @@ -0,0 +1,744 @@ +/* + * FLI/FLC Animation Video Decoder + * Copyright (C) 2003, 2004 the ffmpeg project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file flic.c + * Autodesk Animator FLI/FLC Video Decoder + * by Mike Melanson (melanson@pcisys.net) + * for more information on the .fli/.flc file format and all of its many + * variations, visit: + * http://www.compuphase.com/flic.htm + * + * This decoder outputs PAL8/RGB555/RGB565 and maybe one day RGB24 + * colorspace data, depending on the FLC. To use this decoder, be + * sure that your demuxer sends the FLI file header to the decoder via + * the extradata chunk in AVCodecContext. The chunk should be 128 bytes + * large. The only exception is for FLI files from the game "Magic Carpet", + * in which the header is only 12 bytes. + */ + +#include +#include +#include +#include + +#include "common.h" +#include "avcodec.h" +#include "bswap.h" + +#define FLI_256_COLOR 4 +#define FLI_DELTA 7 +#define FLI_COLOR 11 +#define FLI_LC 12 +#define FLI_BLACK 13 +#define FLI_BRUN 15 +#define FLI_COPY 16 +#define FLI_MINI 18 +#define FLI_DTA_BRUN 25 +#define FLI_DTA_COPY 26 +#define FLI_DTA_LC 27 + +#define FLI_TYPE_CODE (0xAF11) +#define FLC_FLX_TYPE_CODE (0xAF12) +#define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */ +#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13) + +#define CHECK_PIXEL_PTR(n) \ + if (pixel_ptr + n > pixel_limit) { \ + av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \ + pixel_ptr + n, pixel_limit); \ + return -1; \ + } \ + +typedef struct FlicDecodeContext { + AVCodecContext *avctx; + AVFrame frame; + + unsigned int palette[256]; + int new_palette; + int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */ +} FlicDecodeContext; + +static int flic_decode_init(AVCodecContext *avctx) +{ + FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data; + unsigned char *fli_header = (unsigned char *)avctx->extradata; + int depth; + + s->avctx = avctx; + avctx->has_b_frames = 0; + + s->fli_type = LE_16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */ + depth = LE_16(&fli_header[12]); + + if (depth == 0) { + depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */ + } + + if (s->avctx->extradata_size == 12) { + /* special case for magic carpet FLIs */ + s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE; + } else if (s->avctx->extradata_size != 128) { + av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n"); + return -1; + } + + if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) { + depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */ + } + + switch (depth) { + case 8 : avctx->pix_fmt = PIX_FMT_PAL8; break; + case 15 : avctx->pix_fmt = PIX_FMT_RGB555; break; + case 16 : avctx->pix_fmt = PIX_FMT_RGB565; break; + case 24 : avctx->pix_fmt = PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */ + av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n"); + return -1; + break; + default : + av_log(avctx, AV_LOG_ERROR, "Unkown FLC/FLX depth of %d Bpp is unsupported.\n",depth); + return -1; + } + + s->frame.data[0] = NULL; + s->new_palette = 0; + + return 0; +} + +static int flic_decode_frame_8BPP(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data; + + int stream_ptr = 0; + int stream_ptr_after_color_chunk; + int pixel_ptr; + int palette_ptr; + unsigned char palette_idx1; + unsigned char palette_idx2; + + unsigned int frame_size; + int num_chunks; + + unsigned int chunk_size; + int chunk_type; + + int i, j; + + int color_packets; + int color_changes; + int color_shift; + unsigned char r, g, b; + + int lines; + int compressed_lines; + int starting_line; + signed short line_packets; + int y_ptr; + signed char byte_run; + int pixel_skip; + int pixel_countdown; + unsigned char *pixels; + int pixel_limit; + + s->frame.reference = 1; + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &s->frame) < 0) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + + pixels = s->frame.data[0]; + pixel_limit = s->avctx->height * s->frame.linesize[0]; + + frame_size = LE_32(&buf[stream_ptr]); + stream_ptr += 6; /* skip the magic number */ + num_chunks = LE_16(&buf[stream_ptr]); + stream_ptr += 10; /* skip padding */ + + frame_size -= 16; + + /* iterate through the chunks */ + while ((frame_size > 0) && (num_chunks > 0)) { + chunk_size = LE_32(&buf[stream_ptr]); + stream_ptr += 4; + chunk_type = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + + switch (chunk_type) { + case FLI_256_COLOR: + case FLI_COLOR: + stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6; + s->new_palette = 1; + + /* check special case: If this file is from the Magic Carpet + * game and uses 6-bit colors even though it reports 256-color + * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during + * initialization) */ + if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE)) + color_shift = 0; + else + color_shift = 2; + /* set up the palette */ + color_packets = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + palette_ptr = 0; + for (i = 0; i < color_packets; i++) { + /* first byte is how many colors to skip */ + palette_ptr += buf[stream_ptr++]; + + /* next byte indicates how many entries to change */ + color_changes = buf[stream_ptr++]; + + /* if there are 0 color changes, there are actually 256 */ + if (color_changes == 0) + color_changes = 256; + + for (j = 0; j < color_changes; j++) { + + /* wrap around, for good measure */ + if ((unsigned)palette_ptr >= 256) + palette_ptr = 0; + + r = buf[stream_ptr++] << color_shift; + g = buf[stream_ptr++] << color_shift; + b = buf[stream_ptr++] << color_shift; + s->palette[palette_ptr++] = (r << 16) | (g << 8) | b; + } + } + + /* color chunks sometimes have weird 16-bit alignment issues; + * therefore, take the hardline approach and set the stream_ptr + * to the value calculated w.r.t. the size specified by the color + * chunk header */ + stream_ptr = stream_ptr_after_color_chunk; + + break; + + case FLI_DELTA: + y_ptr = 0; + compressed_lines = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + while (compressed_lines > 0) { + line_packets = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + if (line_packets < 0) { + line_packets = -line_packets; + y_ptr += line_packets * s->frame.linesize[0]; + } else { + compressed_lines--; + pixel_ptr = y_ptr; + pixel_countdown = s->avctx->width; + for (i = 0; i < line_packets; i++) { + /* account for the skip bytes */ + pixel_skip = buf[stream_ptr++]; + pixel_ptr += pixel_skip; + pixel_countdown -= pixel_skip; + byte_run = buf[stream_ptr++]; + if (byte_run < 0) { + byte_run = -byte_run; + palette_idx1 = buf[stream_ptr++]; + palette_idx2 = buf[stream_ptr++]; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { + pixels[pixel_ptr++] = palette_idx1; + pixels[pixel_ptr++] = palette_idx2; + } + } else { + CHECK_PIXEL_PTR(byte_run * 2); + for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { + palette_idx1 = buf[stream_ptr++]; + pixels[pixel_ptr++] = palette_idx1; + } + } + } + + y_ptr += s->frame.linesize[0]; + } + } + break; + + case FLI_LC: + /* line compressed */ + starting_line = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + y_ptr = 0; + y_ptr += starting_line * s->frame.linesize[0]; + + compressed_lines = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + while (compressed_lines > 0) { + pixel_ptr = y_ptr; + pixel_countdown = s->avctx->width; + line_packets = buf[stream_ptr++]; + if (line_packets > 0) { + for (i = 0; i < line_packets; i++) { + /* account for the skip bytes */ + pixel_skip = buf[stream_ptr++]; + pixel_ptr += pixel_skip; + pixel_countdown -= pixel_skip; + byte_run = buf[stream_ptr++]; + if (byte_run > 0) { + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++, pixel_countdown--) { + palette_idx1 = buf[stream_ptr++]; + pixels[pixel_ptr++] = palette_idx1; + } + } else { + byte_run = -byte_run; + palette_idx1 = buf[stream_ptr++]; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++, pixel_countdown--) { + pixels[pixel_ptr++] = palette_idx1; + } + } + } + } + + y_ptr += s->frame.linesize[0]; + compressed_lines--; + } + break; + + case FLI_BLACK: + /* set the whole frame to color 0 (which is usually black) */ + memset(pixels, 0, + s->frame.linesize[0] * s->avctx->height); + break; + + case FLI_BRUN: + /* Byte run compression: This chunk type only occurs in the first + * FLI frame and it will update the entire frame. */ + y_ptr = 0; + for (lines = 0; lines < s->avctx->height; lines++) { + pixel_ptr = y_ptr; + /* disregard the line packets; instead, iterate through all + * pixels on a row */ + stream_ptr++; + pixel_countdown = s->avctx->width; + while (pixel_countdown > 0) { + byte_run = buf[stream_ptr++]; + if (byte_run > 0) { + palette_idx1 = buf[stream_ptr++]; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + pixels[pixel_ptr++] = palette_idx1; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } else { /* copy bytes if byte_run < 0 */ + byte_run = -byte_run; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + palette_idx1 = buf[stream_ptr++]; + pixels[pixel_ptr++] = palette_idx1; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } + } + + y_ptr += s->frame.linesize[0]; + } + break; + + case FLI_COPY: + /* copy the chunk (uncompressed frame) */ + if (chunk_size - 6 > s->avctx->width * s->avctx->height) { + av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ + "bigger than image, skipping chunk\n", chunk_size - 6); + stream_ptr += chunk_size - 6; + } else { + for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; + y_ptr += s->frame.linesize[0]) { + memcpy(&pixels[y_ptr], &buf[stream_ptr], + s->avctx->width); + stream_ptr += s->avctx->width; + } + } + break; + + case FLI_MINI: + /* some sort of a thumbnail? disregard this chunk... */ + stream_ptr += chunk_size - 6; + break; + + default: + av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type); + break; + } + + frame_size -= chunk_size; + num_chunks--; + } + + /* by the end of the chunk, the stream ptr should equal the frame + * size (minus 1, possibly); if it doesn't, issue a warning */ + if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1)) + av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ + "and final chunk ptr = %d\n", buf_size, stream_ptr); + + /* make the palette available on the way out */ +// if (s->new_palette) { + if (1) { + memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + s->frame.palette_has_changed = 1; + s->new_palette = 0; + } + + *data_size=sizeof(AVFrame); + *(AVFrame*)data = s->frame; + + return buf_size; +} + +static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + /* Note, the only difference between the 15Bpp and 16Bpp */ + /* Format is the pixel format, the packets are processed the same. */ + FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data; + + int stream_ptr = 0; + int pixel_ptr; + unsigned char palette_idx1; + + unsigned int frame_size; + int num_chunks; + + unsigned int chunk_size; + int chunk_type; + + int i, j; + + int lines; + int compressed_lines; + signed short line_packets; + int y_ptr; + signed char byte_run; + int pixel_skip; + int pixel_countdown; + unsigned char *pixels; + int pixel; + int pixel_limit; + + s->frame.reference = 1; + s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &s->frame) < 0) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + + pixels = s->frame.data[0]; + pixel_limit = s->avctx->height * s->frame.linesize[0]; + + frame_size = LE_32(&buf[stream_ptr]); + stream_ptr += 6; /* skip the magic number */ + num_chunks = LE_16(&buf[stream_ptr]); + stream_ptr += 10; /* skip padding */ + + frame_size -= 16; + + /* iterate through the chunks */ + while ((frame_size > 0) && (num_chunks > 0)) { + chunk_size = LE_32(&buf[stream_ptr]); + stream_ptr += 4; + chunk_type = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + + switch (chunk_type) { + case FLI_256_COLOR: + case FLI_COLOR: + /* For some reason, it seems that non-paletised flics do include one of these */ + /* chunks in their first frame. Why i do not know, it seems rather extraneous */ +/* av_log(avctx, AV_LOG_ERROR, "Unexpected Palette chunk %d in non-paletised FLC\n",chunk_type);*/ + stream_ptr = stream_ptr + chunk_size - 6; + break; + + case FLI_DELTA: + case FLI_DTA_LC: + y_ptr = 0; + compressed_lines = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + while (compressed_lines > 0) { + line_packets = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + if (line_packets < 0) { + line_packets = -line_packets; + y_ptr += line_packets * s->frame.linesize[0]; + } else { + compressed_lines--; + pixel_ptr = y_ptr; + pixel_countdown = s->avctx->width; + for (i = 0; i < line_packets; i++) { + /* account for the skip bytes */ + pixel_skip = buf[stream_ptr++]; + pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */ + pixel_countdown -= pixel_skip; + byte_run = buf[stream_ptr++]; + if (byte_run < 0) { + byte_run = -byte_run; + pixel = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { + *((signed short*)(&pixels[pixel_ptr])) = pixel; + pixel_ptr += 2; + } + } else { + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++, pixel_countdown--) { + *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + pixel_ptr += 2; + } + } + } + + y_ptr += s->frame.linesize[0]; + } + } + break; + + case FLI_LC: + av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n"); + stream_ptr = stream_ptr + chunk_size - 6; + break; + + case FLI_BLACK: + /* set the whole frame to 0x0000 which is balck in both 15Bpp and 16Bpp modes. */ + memset(pixels, 0x0000, + s->frame.linesize[0] * s->avctx->height * 2); + break; + + case FLI_BRUN: + y_ptr = 0; + for (lines = 0; lines < s->avctx->height; lines++) { + pixel_ptr = y_ptr; + /* disregard the line packets; instead, iterate through all + * pixels on a row */ + stream_ptr++; + pixel_countdown = (s->avctx->width * 2); + + while (pixel_countdown > 0) { + byte_run = buf[stream_ptr++]; + if (byte_run > 0) { + palette_idx1 = buf[stream_ptr++]; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + pixels[pixel_ptr++] = palette_idx1; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } else { /* copy bytes if byte_run < 0 */ + byte_run = -byte_run; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + palette_idx1 = buf[stream_ptr++]; + pixels[pixel_ptr++] = palette_idx1; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } + } + + /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed. + * This doesnt give us any good oportunity to perform word endian conversion + * during decompression. So if its requried (ie, this isnt a LE target, we do + * a second pass over the line here, swapping the bytes. + */ + pixel = 0xFF00; + if (0xFF00 != LE_16(&pixel)) /* Check if its not an LE Target */ + { + pixel_ptr = y_ptr; + pixel_countdown = s->avctx->width; + while (pixel_countdown > 0) { + *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[pixel_ptr]); + pixel_ptr += 2; + } + } + y_ptr += s->frame.linesize[0]; + } + break; + + case FLI_DTA_BRUN: + y_ptr = 0; + for (lines = 0; lines < s->avctx->height; lines++) { + pixel_ptr = y_ptr; + /* disregard the line packets; instead, iterate through all + * pixels on a row */ + stream_ptr++; + pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */ + + while (pixel_countdown > 0) { + byte_run = buf[stream_ptr++]; + if (byte_run > 0) { + pixel = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + *((signed short*)(&pixels[pixel_ptr])) = pixel; + pixel_ptr += 2; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } else { /* copy pixels if byte_run < 0 */ + byte_run = -byte_run; + CHECK_PIXEL_PTR(byte_run); + for (j = 0; j < byte_run; j++) { + *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[stream_ptr]); + stream_ptr += 2; + pixel_ptr += 2; + pixel_countdown--; + if (pixel_countdown < 0) + av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", + pixel_countdown); + } + } + } + + y_ptr += s->frame.linesize[0]; + } + break; + + case FLI_COPY: + case FLI_DTA_COPY: + /* copy the chunk (uncompressed frame) */ + if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) { + av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ + "bigger than image, skipping chunk\n", chunk_size - 6); + stream_ptr += chunk_size - 6; + } else { + + for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; + y_ptr += s->frame.linesize[0]) { + + pixel_countdown = s->avctx->width; + pixel_ptr = 0; + while (pixel_countdown > 0) { + *((signed short*)(&pixels[y_ptr + pixel_ptr])) = LE_16(&buf[stream_ptr+pixel_ptr]); + pixel_ptr += 2; + pixel_countdown--; + } + stream_ptr += s->avctx->width*2; + } + } + break; + + case FLI_MINI: + /* some sort of a thumbnail? disregard this chunk... */ + stream_ptr += chunk_size - 6; + break; + + default: + av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type); + break; + } + + frame_size -= chunk_size; + num_chunks--; + } + + /* by the end of the chunk, the stream ptr should equal the frame + * size (minus 1, possibly); if it doesn't, issue a warning */ + if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1)) + av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ + "and final chunk ptr = %d\n", buf_size, stream_ptr); + + + *data_size=sizeof(AVFrame); + *(AVFrame*)data = s->frame; + + return buf_size; +} + +static int flic_decode_frame_24BPP(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n"); + return -1; +} + +static int flic_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + if (avctx->pix_fmt == PIX_FMT_PAL8) { + return flic_decode_frame_8BPP(avctx, data, data_size, + buf, buf_size); + } + else if ((avctx->pix_fmt == PIX_FMT_RGB555) || + (avctx->pix_fmt == PIX_FMT_RGB565)) { + return flic_decode_frame_15_16BPP(avctx, data, data_size, + buf, buf_size); + } + else if (avctx->pix_fmt == PIX_FMT_BGR24) { + return flic_decode_frame_24BPP(avctx, data, data_size, + buf, buf_size); + } + + /* Shouldnt get here, ever as the pix_fmt is processed */ + /* in flic_decode_init and the above if should deal with */ + /* the finite set of possibilites allowable by here. */ + /* but in case we do, just error out. */ + av_log(avctx, AV_LOG_ERROR, "Unknown Format of FLC. My Science cant explain how this happened\n"); + return -1; +} + + +static int flic_decode_end(AVCodecContext *avctx) +{ + FlicDecodeContext *s = avctx->priv_data; + + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + return 0; +} + +AVCodec flic_decoder = { + "flic", + CODEC_TYPE_VIDEO, + CODEC_ID_FLIC, + sizeof(FlicDecodeContext), + flic_decode_init, + NULL, + flic_decode_end, + flic_decode_frame, + CODEC_CAP_DR1, + NULL, + NULL, + NULL, + NULL +}; diff --git a/mpeg4/src/libavcodec/fraps.c b/mpeg4/src/libavcodec/fraps.c new file mode 100644 index 00000000..d107e47b --- /dev/null +++ b/mpeg4/src/libavcodec/fraps.c @@ -0,0 +1,248 @@ +/* + * Fraps FPS1 decoder + * Copyright (c) 2005 Roine Gustafsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file fraps.c + * Lossless Fraps 'FPS1' decoder + * @author Roine Gustafsson + * + * Only decodes version 0 and 1 files. + * Codec algorithm for version 0 is taken from Transcode + * + * Version 2 files, which are the most commonly found Fraps files, cannot be + * decoded yet. + */ + +#include "avcodec.h" + +#define FPS_TAG MKTAG('F', 'P', 'S', 'x') + +/** + * local variable storage + */ +typedef struct FrapsContext{ + AVCodecContext *avctx; + AVFrame frame; +} FrapsContext; + + +/** + * initializes decoder + * @param avctx codec context + * @return 0 on success or negative if fails + */ +static int decode_init(AVCodecContext *avctx) +{ + FrapsContext * const s = avctx->priv_data; + + avctx->coded_frame = (AVFrame*)&s->frame; + avctx->has_b_frames = 0; + avctx->pix_fmt= PIX_FMT_NONE; /* set in decode_frame */ + + s->avctx = avctx; + s->frame.data[0] = NULL; + + return 0; +} + + +/** + * decode a frame + * @param avctx codec context + * @param data output AVFrame + * @param data_size size of output data or 0 if no picture is returned + * @param buf input data frame + * @param buf_size size of input data frame + * @return number of consumed bytes on success or negative if decode fails + */ +static int decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + FrapsContext * const s = avctx->priv_data; + AVFrame *frame = data; + AVFrame * const f = (AVFrame*)&s->frame; + uint32_t header; + unsigned int version,header_size; + unsigned int x, y; + uint32_t *buf32; + uint32_t *luma1,*luma2,*cb,*cr; + + + header = LE_32(buf); + version = header & 0xff; + header_size = (header & (1<<30))? 8 : 4; /* bit 30 means pad to 8 bytes */ + + if (version > 1) { + av_log(avctx, AV_LOG_ERROR, + "This file is encoded with Fraps version %d. " \ + "This codec can only decode version 0 and 1.\n", version); + return -1; + } + + buf+=4; + if (header_size == 8) + buf+=4; + + switch(version) { + case 0: + default: + /* Fraps v0 is a reordered YUV420 */ + avctx->pix_fmt = PIX_FMT_YUV420P; + + if ( (buf_size != avctx->width*avctx->height*3/2+header_size) && + (buf_size != header_size) ) { + av_log(avctx, AV_LOG_ERROR, + "Invalid frame length %d (should be %d)\n", + buf_size, avctx->width*avctx->height*3/2+header_size); + return -1; + } + + if (( (avctx->width % 8) != 0) || ( (avctx->height % 2) != 0 )) { + av_log(avctx, AV_LOG_ERROR, "Invalid frame size %dx%d\n", + avctx->width, avctx->height); + return -1; + } + + f->reference = 1; + f->buffer_hints = FF_BUFFER_HINTS_VALID | + FF_BUFFER_HINTS_PRESERVE | + FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, f)) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + /* bit 31 means same as previous pic */ + f->pict_type = (header & (1<<31))? FF_P_TYPE : FF_I_TYPE; + f->key_frame = f->pict_type == FF_I_TYPE; + + if (f->pict_type == FF_I_TYPE) { + buf32=(uint32_t*)buf; + for(y=0; yheight/2; y++){ + luma1=(uint32_t*)&f->data[0][ y*2*f->linesize[0] ]; + luma2=(uint32_t*)&f->data[0][ (y*2+1)*f->linesize[0] ]; + cr=(uint32_t*)&f->data[1][ y*f->linesize[1] ]; + cb=(uint32_t*)&f->data[2][ y*f->linesize[2] ]; + for(x=0; xwidth; x+=8){ + *(luma1++) = *(buf32++); + *(luma1++) = *(buf32++); + *(luma2++) = *(buf32++); + *(luma2++) = *(buf32++); + *(cr++) = *(buf32++); + *(cb++) = *(buf32++); + } + } + } + break; + + case 1: + /* Fraps v1 is an upside-down BGR24 */ + avctx->pix_fmt = PIX_FMT_BGR24; + + if ( (buf_size != avctx->width*avctx->height*3+header_size) && + (buf_size != header_size) ) { + av_log(avctx, AV_LOG_ERROR, + "Invalid frame length %d (should be %d)\n", + buf_size, avctx->width*avctx->height*3+header_size); + return -1; + } + + f->reference = 1; + f->buffer_hints = FF_BUFFER_HINTS_VALID | + FF_BUFFER_HINTS_PRESERVE | + FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, f)) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + /* bit 31 means same as previous pic */ + f->pict_type = (header & (1<<31))? FF_P_TYPE : FF_I_TYPE; + f->key_frame = f->pict_type == FF_I_TYPE; + + if (f->pict_type == FF_I_TYPE) { + for(y=0; yheight; y++) + memcpy(&f->data[0][ (avctx->height-y)*f->linesize[0] ], + &buf[y*avctx->width*3], + f->linesize[0]); + } + break; + + case 2: + /** + * Fraps v2 sub-header description. All numbers are little-endian: + * (this is all guesswork) + * + * 0: DWORD 'FPSx' + * 4: DWORD 0x00000010 unknown, perhaps flags + * 8: DWORD off_2 offset to plane 2 + * 12: DWORD off_3 offset to plane 3 + * 16: 256xDWORD freqtbl_1 frequency table for plane 1 + * 1040: plane_1 + * ... + * off_2: 256xDWORD freqtbl_2 frequency table for plane 2 + * plane_2 + * ... + * off_3: 256xDWORD freqtbl_3 frequency table for plane 3 + * plane_3 + */ + if ((BE_32(buf) != FPS_TAG)||(buf_size < (3*1024 + 8))) { + av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n"); + return -1; + } + + /* NOT FINISHED */ + + break; + } + + *frame = *f; + *data_size = sizeof(AVFrame); + + return buf_size; +} + + +/** + * closes decoder + * @param avctx codec context + * @return 0 on success or negative if fails + */ +static int decode_end(AVCodecContext *avctx) +{ + FrapsContext *s = (FrapsContext*)avctx->priv_data; + + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + return 0; +} + + +AVCodec fraps_decoder = { + "fraps", + CODEC_TYPE_VIDEO, + CODEC_ID_FRAPS, + sizeof(FrapsContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; diff --git a/mpeg4/src/libavcodec/g726.c b/mpeg4/src/libavcodec/g726.c new file mode 100644 index 00000000..8114fe0f --- /dev/null +++ b/mpeg4/src/libavcodec/g726.c @@ -0,0 +1,424 @@ +/* + * G.726 ADPCM audio codec + * Copyright (c) 2004 Roman Shaposhnik. + * + * This is a very straightforward rendition of the G.726 + * Section 4 "Computational Details". + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include "avcodec.h" +#include "common.h" +#include "bitstream.h" + +/** + * G.726 11bit float. + * G.726 Standard uses rather odd 11bit floating point arithmentic for + * numerous occasions. It's a mistery to me why they did it this way + * instead of simply using 32bit integer arithmetic. + */ +typedef struct Float11 { + int sign; /**< 1bit sign */ + int exp; /**< 4bit exponent */ + int mant; /**< 6bit mantissa */ +} Float11; + +static inline Float11* i2f(int16_t i, Float11* f) +{ + f->sign = (i < 0); + if (f->sign) + i = -i; + f->exp = av_log2_16bit(i) + !!i; + f->mant = i? (i<<6) >> f->exp : + 1<<5; + return f; +} + +static inline int16_t mult(Float11* f1, Float11* f2) +{ + int res, exp; + + exp = f1->exp + f2->exp; + res = (((f1->mant * f2->mant) + 0x30) >> 4) << 7; + res = exp > 26 ? res << (exp - 26) : res >> (26 - exp); + return (f1->sign ^ f2->sign) ? -res : res; +} + +static inline int sgn(int value) +{ + return (value < 0) ? -1 : 1; +} + +typedef struct G726Tables { + int bits; /**< bits per sample */ + int* quant; /**< quantization table */ + int* iquant; /**< inverse quantization table */ + int* W; /**< special table #1 ;-) */ + int* F; /**< special table #2 */ +} G726Tables; + +typedef struct G726Context { + G726Tables* tbls; /**< static tables needed for computation */ + + Float11 sr[2]; /**< prev. reconstructed samples */ + Float11 dq[6]; /**< prev. difference */ + int a[2]; /**< second order predictor coeffs */ + int b[6]; /**< sixth order predictor coeffs */ + int pk[2]; /**< signs of prev. 2 sez + dq */ + + int ap; /**< scale factor control */ + int yu; /**< fast scale factor */ + int yl; /**< slow scale factor */ + int dms; /**< short average magnitude of F[i] */ + int dml; /**< long average magnitude of F[i] */ + int td; /**< tone detect */ + + int se; /**< estimated signal for the next iteration */ + int sez; /**< estimated second order prediction */ + int y; /**< quantizer scaling factor for the next iteration */ +} G726Context; + +static int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ + { 260, INT_MAX }; +static int iquant_tbl16[] = + { 116, 365, 365, 116 }; +static int W_tbl16[] = + { -22, 439, 439, -22 }; +static int F_tbl16[] = + { 0, 7, 7, 0 }; + +static int quant_tbl24[] = /**< 24kbit/s 3bits per sample */ + { 7, 217, 330, INT_MAX }; +static int iquant_tbl24[] = + { INT_MIN, 135, 273, 373, 373, 273, 135, INT_MIN }; +static int W_tbl24[] = + { -4, 30, 137, 582, 582, 137, 30, -4 }; +static int F_tbl24[] = + { 0, 1, 2, 7, 7, 2, 1, 0 }; + +static int quant_tbl32[] = /**< 32kbit/s 4bits per sample */ + { -125, 79, 177, 245, 299, 348, 399, INT_MAX }; +static int iquant_tbl32[] = + { INT_MIN, 4, 135, 213, 273, 323, 373, 425, + 425, 373, 323, 273, 213, 135, 4, INT_MIN }; +static int W_tbl32[] = + { -12, 18, 41, 64, 112, 198, 355, 1122, + 1122, 355, 198, 112, 64, 41, 18, -12}; +static int F_tbl32[] = + { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 }; + +static int quant_tbl40[] = /**< 40kbit/s 5bits per sample */ + { -122, -16, 67, 138, 197, 249, 297, 338, + 377, 412, 444, 474, 501, 527, 552, INT_MAX }; +static int iquant_tbl40[] = + { INT_MIN, -66, 28, 104, 169, 224, 274, 318, + 358, 395, 429, 459, 488, 514, 539, 566, + 566, 539, 514, 488, 459, 429, 395, 358, + 318, 274, 224, 169, 104, 28, -66, INT_MIN }; +static int W_tbl40[] = + { 14, 14, 24, 39, 40, 41, 58, 100, + 141, 179, 219, 280, 358, 440, 529, 696, + 696, 529, 440, 358, 280, 219, 179, 141, + 100, 58, 41, 40, 39, 24, 14, 14 }; +static int F_tbl40[] = + { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6, + 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; + +static G726Tables G726Tables_pool[] = + {{ 2, quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 }, + { 3, quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 }, + { 4, quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 }, + { 5, quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }}; + + +/** + * Para 4.2.2 page 18: Adaptive quantizer. + */ +static inline uint8_t quant(G726Context* c, int d) +{ + int sign, exp, i, dln; + + sign = i = 0; + if (d < 0) { + sign = 1; + d = -d; + } + exp = av_log2_16bit(d); + dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2); + + while (c->tbls->quant[i] < INT_MAX && c->tbls->quant[i] < dln) + ++i; + + if (sign) + i = ~i; + if (c->tbls->bits != 2 && i == 0) /* I'm not sure this is a good idea */ + i = 0xff; + + return i; +} + +/** + * Para 4.2.3 page 22: Inverse adaptive quantizer. + */ +static inline int16_t inverse_quant(G726Context* c, int i) +{ + int dql, dex, dqt; + + dql = c->tbls->iquant[i] + (c->y >> 2); + dex = (dql>>7) & 0xf; /* 4bit exponent */ + dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */ + return (dql < 0) ? 0 : ((dqt<<7) >> (14-dex)); +} + +static inline int16_t g726_iterate(G726Context* c, int16_t I) +{ + int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0; + Float11 f; + + dq = inverse_quant(c, I); + if (I >> (c->tbls->bits - 1)) /* get the sign */ + dq = -dq; + re_signal = c->se + dq; + + /* Transition detect */ + ylint = (c->yl >> 15); + ylfrac = (c->yl >> 10) & 0x1f; + thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint; + if (c->td == 1 && abs(dq) > ((thr2+(thr2>>1))>>1)) + tr = 1; + else + tr = 0; + + /* Update second order predictor coefficient A2 and A1 */ + pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0; + dq0 = dq ? sgn(dq) : 0; + if (tr) { + c->a[0] = 0; + c->a[1] = 0; + for (i=0; i<6; i++) + c->b[i] = 0; + } else { + /* This is a bit crazy, but it really is +255 not +256 */ + fa1 = clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255); + + c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7); + c->a[1] = clip(c->a[1], -12288, 12288); + c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8); + c->a[0] = clip(c->a[0], -(15360 - c->a[1]), 15360 - c->a[1]); + + for (i=0; i<6; i++) + c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8); + } + + /* Update Dq and Sr and Pk */ + c->pk[1] = c->pk[0]; + c->pk[0] = pk0 ? pk0 : 1; + c->sr[1] = c->sr[0]; + i2f(re_signal, &c->sr[0]); + for (i=5; i>0; i--) + c->dq[i] = c->dq[i-1]; + i2f(dq, &c->dq[0]); + c->dq[0].sign = I >> (c->tbls->bits - 1); /* Isn't it crazy ?!?! */ + + /* Update tone detect [I'm not sure 'tr == 0' is really needed] */ + c->td = (tr == 0 && c->a[1] < -11776); + + /* Update Ap */ + c->dms += ((c->tbls->F[I]<<9) - c->dms) >> 5; + c->dml += ((c->tbls->F[I]<<11) - c->dml) >> 7; + if (tr) + c->ap = 256; + else if (c->y > 1535 && !c->td && (abs((c->dms << 2) - c->dml) < (c->dml >> 3))) + c->ap += (-c->ap) >> 4; + else + c->ap += (0x200 - c->ap) >> 4; + + /* Update Yu and Yl */ + c->yu = clip(c->y + (((c->tbls->W[I] << 5) - c->y) >> 5), 544, 5120); + c->yl += c->yu + ((-c->yl)>>6); + + /* Next iteration for Y */ + al = (c->ap >= 256) ? 1<<6 : c->ap >> 2; + c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6; + + /* Next iteration for SE and SEZ */ + c->se = 0; + for (i=0; i<6; i++) + c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]); + c->sez = c->se >> 1; + for (i=0; i<2; i++) + c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]); + c->se >>= 1; + + return clip(re_signal << 2, -0xffff, 0xffff); +} + +static int g726_reset(G726Context* c, int bit_rate) +{ + int i; + + c->tbls = &G726Tables_pool[bit_rate/8000 - 2]; + for (i=0; i<2; i++) { + i2f(0, &c->sr[i]); + c->a[i] = 0; + c->pk[i] = 1; + } + for (i=0; i<6; i++) { + i2f(0, &c->dq[i]); + c->b[i] = 0; + } + c->ap = 0; + c->dms = 0; + c->dml = 0; + c->yu = 544; + c->yl = 34816; + c->td = 0; + + c->se = 0; + c->sez = 0; + c->y = 544; + + return 0; +} + +static int16_t g726_decode(G726Context* c, int16_t i) +{ + return g726_iterate(c, i); +} + +static int16_t g726_encode(G726Context* c, int16_t sig) +{ + uint8_t i; + + i = quant(c, sig/4 - c->se) & ((1<tbls->bits) - 1); + g726_iterate(c, i); + return i; +} + +/* Interfacing to the libavcodec */ + +typedef struct AVG726Context { + G726Context c; + int bits_left; + int bit_buffer; + int code_size; +} AVG726Context; + +static int g726_init(AVCodecContext * avctx) +{ + AVG726Context* c = (AVG726Context*)avctx->priv_data; + + if (avctx->channels != 1 || + (avctx->bit_rate != 16000 && avctx->bit_rate != 24000 && + avctx->bit_rate != 32000 && avctx->bit_rate != 40000)) { + av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n"); + return -1; + } + if (avctx->sample_rate != 8000 && avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL) { + av_log(avctx, AV_LOG_ERROR, "G726: unsupported audio format\n"); + return -1; + } + g726_reset(&c->c, avctx->bit_rate); + c->code_size = c->c.tbls->bits; + c->bit_buffer = 0; + c->bits_left = 0; + + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return -ENOMEM; + avctx->coded_frame->key_frame = 1; + + return 0; +} + +static int g726_close(AVCodecContext *avctx) +{ + av_freep(&avctx->coded_frame); + return 0; +} + +static int g726_encode_frame(AVCodecContext *avctx, + uint8_t *dst, int buf_size, void *data) +{ + AVG726Context *c = avctx->priv_data; + short *samples = data; + PutBitContext pb; + + init_put_bits(&pb, dst, 1024*1024); + + for (; buf_size; buf_size--) + put_bits(&pb, c->code_size, g726_encode(&c->c, *samples++)); + + flush_put_bits(&pb); + + return put_bits_count(&pb)>>3; +} + +static int g726_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + AVG726Context *c = avctx->priv_data; + short *samples = data; + uint8_t code; + uint8_t mask; + GetBitContext gb; + + if (!buf_size) + goto out; + + mask = (1<code_size) - 1; + init_get_bits(&gb, buf, buf_size * 8); + if (c->bits_left) { + int s = c->code_size - c->bits_left;; + code = (c->bit_buffer << s) | get_bits(&gb, s); + *samples++ = g726_decode(&c->c, code & mask); + } + + while (get_bits_count(&gb) + c->code_size <= buf_size*8) + *samples++ = g726_decode(&c->c, get_bits(&gb, c->code_size) & mask); + + c->bits_left = buf_size*8 - get_bits_count(&gb); + c->bit_buffer = get_bits(&gb, c->bits_left); + +out: + *data_size = (uint8_t*)samples - (uint8_t*)data; + return buf_size; +} + +#ifdef CONFIG_ENCODERS +AVCodec adpcm_g726_encoder = { + "g726", + CODEC_TYPE_AUDIO, + CODEC_ID_ADPCM_G726, + sizeof(AVG726Context), + g726_init, + g726_encode_frame, + g726_close, + NULL, +}; +#endif //CONFIG_ENCODERS + +AVCodec adpcm_g726_decoder = { + "g726", + CODEC_TYPE_AUDIO, + CODEC_ID_ADPCM_G726, + sizeof(AVG726Context), + g726_init, + NULL, + g726_close, + g726_decode_frame, +}; diff --git a/mpeg4/src/libavcodec/golomb.c b/mpeg4/src/libavcodec/golomb.c new file mode 100644 index 00000000..c140b8b0 --- /dev/null +++ b/mpeg4/src/libavcodec/golomb.c @@ -0,0 +1,154 @@ +/* + * exp golomb vlc stuff + * Copyright (c) 2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file golomb.c + * @brief + * exp golomb vlc stuff + * @author Michael Niedermayer + */ + +#include "common.h" + +const uint8_t ff_golomb_vlc_len[512]={ +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, +7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, +5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 +}; + +const uint8_t ff_ue_golomb_vlc_code[512]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30, + 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +const int8_t ff_se_golomb_vlc_code[512]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15, + 4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + + +const uint8_t ff_ue_golomb_len[256]={ + 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11, +11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13, +13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, +13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17, +}; + +const uint8_t ff_interleaved_golomb_vlc_len[256]={ +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, +}; + +const uint8_t ff_interleaved_ue_golomb_vlc_code[256]={ + 15,16,7, 7, 17,18,8, 8, 3, 3, 3, 3, 3, 3, 3, 3, + 19,20,9, 9, 21,22,10,10,4, 4, 4, 4, 4, 4, 4, 4, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 23,24,11,11,25,26,12,12,5, 5, 5, 5, 5, 5, 5, 5, + 27,28,13,13,29,30,14,14,6, 6, 6, 6, 6, 6, 6, 6, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +const int8_t ff_interleaved_se_golomb_vlc_code[256]={ + 8, -8, 4, 4, 9, -9, -4, -4, 2, 2, 2, 2, 2, 2, 2, 2, + 10,-10, 5, 5, 11,-11, -5, -5, -2, -2, -2, -2, -2, -2, -2, -2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 12,-12, 6, 6, 13,-13, -6, -6, 3, 3, 3, 3, 3, 3, 3, 3, + 14,-14, 7, 7, 15,-15, -7, -7, -3, -3, -3, -3, -3, -3, -3, -3, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; diff --git a/mpeg4/src/libavcodec/golomb.h b/mpeg4/src/libavcodec/golomb.h new file mode 100644 index 00000000..ef74f15c --- /dev/null +++ b/mpeg4/src/libavcodec/golomb.h @@ -0,0 +1,469 @@ +/* + * exp golomb vlc stuff + * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2004 Alex Beregszaszi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file golomb.h + * @brief + * exp golomb vlc stuff + * @author Michael Niedermayer and Alex Beregszaszi + */ + +#define INVALID_VLC 0x80000000 + +extern const uint8_t ff_golomb_vlc_len[512]; +extern const uint8_t ff_ue_golomb_vlc_code[512]; +extern const int8_t ff_se_golomb_vlc_code[512]; +extern const uint8_t ff_ue_golomb_len[256]; + +extern const uint8_t ff_interleaved_golomb_vlc_len[256]; +extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256]; +extern const int8_t ff_interleaved_se_golomb_vlc_code[256]; + + + /** + * read unsigned exp golomb code. + */ +static inline int get_ue_golomb(GetBitContext *gb){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + if(buf >= (1<<27)){ + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_ue_golomb_vlc_code[buf]; + }else{ + log= 2*av_log2(buf) - 31; + buf>>= log; + buf--; + LAST_SKIP_BITS(re, gb, 32 - log); + CLOSE_READER(re, gb); + + return buf; + } +} + +static inline int svq3_get_ue_golomb(GetBitContext *gb){ + uint32_t buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + if(buf&0xAA800000){ + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_ue_golomb_vlc_code[buf]; + }else{ + LAST_SKIP_BITS(re, gb, 8); + UPDATE_CACHE(re, gb); + buf |= 1 | (GET_CACHE(re, gb) >> 8); + + if((buf & 0xAAAAAAAA) == 0) + return INVALID_VLC; + + for(log=31; (buf & 0x80000000) == 0; log--){ + buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + } + + LAST_SKIP_BITS(re, gb, 63 - 2*log - 8); + CLOSE_READER(re, gb); + + return ((buf << log) >> log) - 1; + } +} + +/** + * read unsigned truncated exp golomb code. + */ +static inline int get_te0_golomb(GetBitContext *gb, int range){ + assert(range >= 1); + + if(range==1) return 0; + else if(range==2) return get_bits1(gb)^1; + else return get_ue_golomb(gb); +} + +/** + * read unsigned truncated exp golomb code. + */ +static inline int get_te_golomb(GetBitContext *gb, int range){ + assert(range >= 1); + + if(range==2) return get_bits1(gb)^1; + else return get_ue_golomb(gb); +} + + +/** + * read signed exp golomb code. + */ +static inline int get_se_golomb(GetBitContext *gb){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + if(buf >= (1<<27)){ + buf >>= 32 - 9; + LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_se_golomb_vlc_code[buf]; + }else{ + log= 2*av_log2(buf) - 31; + buf>>= log; + + LAST_SKIP_BITS(re, gb, 32 - log); + CLOSE_READER(re, gb); + + if(buf&1) buf= -(buf>>1); + else buf= (buf>>1); + + return buf; + } +} + +static inline int svq3_get_se_golomb(GetBitContext *gb){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + if(buf&0xAA800000){ + buf >>= 32 - 8; + LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]); + CLOSE_READER(re, gb); + + return ff_interleaved_se_golomb_vlc_code[buf]; + }else{ + LAST_SKIP_BITS(re, gb, 8); + UPDATE_CACHE(re, gb); + buf |= 1 | (GET_CACHE(re, gb) >> 8); + + if((buf & 0xAAAAAAAA) == 0) + return INVALID_VLC; + + for(log=31; (buf & 0x80000000) == 0; log--){ + buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30); + } + + LAST_SKIP_BITS(re, gb, 63 - 2*log - 8); + CLOSE_READER(re, gb); + + return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1; + } +} + +/** + * read unsigned golomb rice code (ffv1). + */ +static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + log= av_log2(buf); + + if(log > 31-limit){ + buf >>= log - k; + buf += (30-log)<>= 32 - limit - esc_len; + LAST_SKIP_BITS(re, gb, esc_len + limit); + CLOSE_READER(re, gb); + + return buf + limit - 1; + } +} + +/** + * read unsigned golomb rice code (jpegls). + */ +static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int esc_len){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + log= av_log2(buf); + + if(log > 31-11){ + buf >>= log - k; + buf += (30-log)<>1; + else return -(v>>1); + +// return (v>>1) ^ -(v&1); +} + +/** + * read signed golomb rice code (flac). + */ +static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, int esc_len){ + int v= get_ur_golomb_jpegls(gb, k, limit, esc_len); + return (v>>1) ^ -(v&1); +} + +/** + * read unsigned golomb rice code (shorten). + */ +static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k){ + return get_ur_golomb_jpegls(gb, k, INT_MAX, 0); +} + +/** + * read signed golomb rice code (shorten). + */ +static inline int get_sr_golomb_shorten(GetBitContext* gb, int k) +{ + int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0); + if (uvar & 1) + return ~(uvar >> 1); + else + return uvar >> 1; +} + + + +#ifdef TRACE + +static inline int get_ue(GetBitContext *s, char *file, const char *func, int line){ + int show= show_bits(s, 24); + int pos= get_bits_count(s); + int i= get_ue_golomb(s); + int len= get_bits_count(s) - pos; + int bits= show>>(24-len); + + print_bin(bits, len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + + return i; +} + +static inline int get_se(GetBitContext *s, char *file, const char *func, int line){ + int show= show_bits(s, 24); + int pos= get_bits_count(s); + int i= get_se_golomb(s); + int len= get_bits_count(s) - pos; + int bits= show>>(24-len); + + print_bin(bits, len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + + return i; +} + +static inline int get_te(GetBitContext *s, int r, char *file, const char *func, int line){ + int show= show_bits(s, 24); + int pos= get_bits_count(s); + int i= get_te0_golomb(s, r); + int len= get_bits_count(s) - pos; + int bits= show>>(24-len); + + print_bin(bits, len); + + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); + + return i; +} + +#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) +#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__) + +#endif + +/** + * write unsigned exp golomb code. + */ +static inline void set_ue_golomb(PutBitContext *pb, int i){ + int e; + + assert(i>=0); + +#if 0 + if(i=0){ + put_bits(pb, 1, 1); + return; + } +#endif + if(i<256) + put_bits(pb, ff_ue_golomb_len[i], i+1); + else{ + e= av_log2(i+1); + + put_bits(pb, 2*e+1, i+1); + } +} + +/** + * write truncated unsigned exp golomb code. + */ +static inline void set_te_golomb(PutBitContext *pb, int i, int range){ + assert(range >= 1); + assert(i<=range); + + if(range==2) put_bits(pb, 1, i^1); + else set_ue_golomb(pb, i); +} + +/** + * write signed exp golomb code. 16 bits at most. + */ +static inline void set_se_golomb(PutBitContext *pb, int i){ +// if (i>32767 || i<-32767) +// av_log(NULL,AV_LOG_ERROR,"value out of range %d\n", i); +#if 0 + if(i<=0) i= -2*i; + else i= 2*i-1; +#elif 1 + i= 2*i-1; + if(i<0) i^= -1; //FIXME check if gcc does the right thing +#else + i= 2*i-1; + i^= (i>>31); +#endif + set_ue_golomb(pb, i); +} + +/** + * write unsigned golomb rice code (ffv1). + */ +static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){ + int e; + + assert(i>=0); + + e= i>>k; + if(e=0); + + e= (i>>k) + 1; + if(e>31); + + set_ur_golomb(pb, v, k, limit, esc_len); +} + +/** + * write signed golomb rice code (flac). + */ +static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, int limit, int esc_len){ + int v; + + v = -2*i-1; + v ^= (v>>31); + + set_ur_golomb_jpegls(pb, v, k, limit, esc_len); +} diff --git a/mpeg4/src/libavcodec/h261.c b/mpeg4/src/libavcodec/h261.c new file mode 100644 index 00000000..96b5af1f --- /dev/null +++ b/mpeg4/src/libavcodec/h261.c @@ -0,0 +1,1047 @@ +/* + * H261 decoder + * Copyright (c) 2002-2004 Michael Niedermayer + * Copyright (c) 2004 Maarten Daniels + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file h261.c + * h261codec. + */ + +#include "common.h" +#include "dsputil.h" +#include "avcodec.h" +#include "mpegvideo.h" +#include "h261data.h" + + +#define H261_MBA_VLC_BITS 9 +#define H261_MTYPE_VLC_BITS 6 +#define H261_MV_VLC_BITS 7 +#define H261_CBP_VLC_BITS 9 +#define TCOEFF_VLC_BITS 9 + +#define MBA_STUFFING 33 +#define MBA_STARTCODE 34 +#define IS_FIL(a) ((a)&MB_TYPE_H261_FIL) + +/** + * H261Context + */ +typedef struct H261Context{ + MpegEncContext s; + + int current_mba; + int previous_mba; + int mba_diff; + int mtype; + int current_mv_x; + int current_mv_y; + int gob_number; + int gob_start_code_skipped; // 1 if gob start code is already read before gob header is read +}H261Context; + +void ff_h261_loop_filter(MpegEncContext *s){ + H261Context * h= (H261Context*)s; + const int linesize = s->linesize; + const int uvlinesize= s->uvlinesize; + uint8_t *dest_y = s->dest[0]; + uint8_t *dest_cb= s->dest[1]; + uint8_t *dest_cr= s->dest[2]; + + if(!(IS_FIL (h->mtype))) + return; + + s->dsp.h261_loop_filter(dest_y , linesize); + s->dsp.h261_loop_filter(dest_y + 8, linesize); + s->dsp.h261_loop_filter(dest_y + 8 * linesize , linesize); + s->dsp.h261_loop_filter(dest_y + 8 * linesize + 8, linesize); + s->dsp.h261_loop_filter(dest_cb, uvlinesize); + s->dsp.h261_loop_filter(dest_cr, uvlinesize); +} + +static int ff_h261_get_picture_format(int width, int height){ + // QCIF + if (width == 176 && height == 144) + return 0; + // CIF + else if (width == 352 && height == 288) + return 1; + // ERROR + else + return -1; +} + +static void h261_encode_block(H261Context * h, DCTELEM * block, + int n); +static int h261_decode_block(H261Context *h, DCTELEM *block, + int n, int coded); + +void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){ + H261Context * h = (H261Context *) s; + int format, temp_ref; + + align_put_bits(&s->pb); + + /* Update the pointer to last GOB */ + s->ptr_lastgob = pbBufPtr(&s->pb); + + put_bits(&s->pb, 20, 0x10); /* PSC */ + + temp_ref= s->picture_number * (int64_t)30000 * s->avctx->time_base.num / + (1001 * (int64_t)s->avctx->time_base.den); //FIXME maybe this should use a timestamp + put_bits(&s->pb, 5, temp_ref & 0x1f); /* TemporalReference */ + + put_bits(&s->pb, 1, 0); /* split screen off */ + put_bits(&s->pb, 1, 0); /* camera off */ + put_bits(&s->pb, 1, 0); /* freeze picture release off */ + + format = ff_h261_get_picture_format(s->width, s->height); + + put_bits(&s->pb, 1, format); /* 0 == QCIF, 1 == CIF */ + + put_bits(&s->pb, 1, 0); /* still image mode */ + put_bits(&s->pb, 1, 0); /* reserved */ + + put_bits(&s->pb, 1, 0); /* no PEI */ + if(format == 0) + h->gob_number = -1; + else + h->gob_number = 0; + h->current_mba = 0; +} + +/** + * Encodes a group of blocks header. + */ +static void h261_encode_gob_header(MpegEncContext * s, int mb_line){ + H261Context * h = (H261Context *)s; + if(ff_h261_get_picture_format(s->width, s->height) == 0){ + h->gob_number+=2; // QCIF + } + else{ + h->gob_number++; // CIF + } + put_bits(&s->pb, 16, 1); /* GBSC */ + put_bits(&s->pb, 4, h->gob_number); /* GN */ + put_bits(&s->pb, 5, s->qscale); /* GQUANT */ + put_bits(&s->pb, 1, 0); /* no GEI */ + h->current_mba = 0; + h->previous_mba = 0; + h->current_mv_x=0; + h->current_mv_y=0; +} + +void ff_h261_reorder_mb_index(MpegEncContext* s){ + int index= s->mb_x + s->mb_y*s->mb_width; + + if(index % 33 == 0) + h261_encode_gob_header(s,0); + + /* for CIF the GOB's are fragmented in the middle of a scanline + that's why we need to adjust the x and y index of the macroblocks */ + if(ff_h261_get_picture_format(s->width,s->height) == 1){ // CIF + s->mb_x = index % 11 ; index /= 11; + s->mb_y = index % 3 ; index /= 3; + s->mb_x+= 11*(index % 2); index /= 2; + s->mb_y+= 3*index; + + ff_init_block_index(s); + ff_update_block_index(s); + } +} + +static void h261_encode_motion(H261Context * h, int val){ + MpegEncContext * const s = &h->s; + int sign, code; + if(val==0){ + code = 0; + put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); + } + else{ + if(val > 15) + val -=32; + if(val < -16) + val+=32; + sign = val < 0; + code = sign ? -val : val; + put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]); + put_bits(&s->pb,1,sign); + } +} + +static inline int get_cbp(MpegEncContext * s, + DCTELEM block[6][64]) +{ + int i, cbp; + cbp= 0; + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + return cbp; +} +void ff_h261_encode_mb(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y) +{ + H261Context * h = (H261Context *)s; + int mvd, mv_diff_x, mv_diff_y, i, cbp; + cbp = 63; // avoid warning + mvd = 0; + + h->current_mba++; + h->mtype = 0; + + if (!s->mb_intra){ + /* compute cbp */ + cbp= get_cbp(s, block); + + /* mvd indicates if this block is motion compensated */ + mvd = motion_x | motion_y; + + if((cbp | mvd | s->dquant ) == 0) { + /* skip macroblock */ + s->skip_count++; + h->current_mv_x=0; + h->current_mv_y=0; + return; + } + } + + /* MB is not skipped, encode MBA */ + put_bits(&s->pb, h261_mba_bits[(h->current_mba-h->previous_mba)-1], h261_mba_code[(h->current_mba-h->previous_mba)-1]); + + /* calculate MTYPE */ + if(!s->mb_intra){ + h->mtype++; + + if(mvd || s->loop_filter) + h->mtype+=3; + if(s->loop_filter) + h->mtype+=3; + if(cbp || s->dquant) + h->mtype++; + assert(h->mtype > 1); + } + + if(s->dquant) + h->mtype++; + + put_bits(&s->pb, h261_mtype_bits[h->mtype], h261_mtype_code[h->mtype]); + + h->mtype = h261_mtype_map[h->mtype]; + + if(IS_QUANT(h->mtype)){ + ff_set_qscale(s,s->qscale+s->dquant); + put_bits(&s->pb, 5, s->qscale); + } + + if(IS_16X16(h->mtype)){ + mv_diff_x = (motion_x >> 1) - h->current_mv_x; + mv_diff_y = (motion_y >> 1) - h->current_mv_y; + h->current_mv_x = (motion_x >> 1); + h->current_mv_y = (motion_y >> 1); + h261_encode_motion(h,mv_diff_x); + h261_encode_motion(h,mv_diff_y); + } + + h->previous_mba = h->current_mba; + + if(HAS_CBP(h->mtype)){ + put_bits(&s->pb,h261_cbp_tab[cbp-1][1],h261_cbp_tab[cbp-1][0]); + } + for(i=0; i<6; i++) { + /* encode each block */ + h261_encode_block(h, block[i], i); + } + + if ( ( h->current_mba == 11 ) || ( h->current_mba == 22 ) || ( h->current_mba == 33 ) || ( !IS_16X16 ( h->mtype ) )){ + h->current_mv_x=0; + h->current_mv_y=0; + } +} + +void ff_h261_encode_init(MpegEncContext *s){ + static int done = 0; + + if (!done) { + done = 1; + init_rl(&h261_rl_tcoeff, 1); + } + + s->min_qcoeff= -127; + s->max_qcoeff= 127; + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; +} + + +/** + * encodes a 8x8 block. + * @param block the 8x8 block + * @param n block index (0-3 are luma, 4-5 are chroma) + */ +static void h261_encode_block(H261Context * h, DCTELEM * block, int n){ + MpegEncContext * const s = &h->s; + int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code; + RLTable *rl; + + rl = &h261_rl_tcoeff; + if (s->mb_intra) { + /* DC coef */ + level = block[0]; + /* 255 cannot be represented, so we clamp */ + if (level > 254) { + level = 254; + block[0] = 254; + } + /* 0 cannot be represented also */ + else if (level < 1) { + level = 1; + block[0] = 1; + } + if (level == 128) + put_bits(&s->pb, 8, 0xff); + else + put_bits(&s->pb, 8, level); + i = 1; + } else if((block[0]==1 || block[0] == -1) && (s->block_last_index[n] > -1)){ + //special case + put_bits(&s->pb,2,block[0]>0 ? 2 : 3 ); + i = 1; + } else { + i = 0; + } + + /* AC coefs */ + last_index = s->block_last_index[n]; + last_non_zero = i - 1; + for (; i <= last_index; i++) { + j = s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + run = i - last_non_zero - 1; + last = (i == last_index); + sign = 0; + slevel = level; + if (level < 0) { + sign = 1; + level = -level; + } + code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, run, level); + if(run==0 && level < 16) + code+=1; + put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + if (code == rl->n) { + put_bits(&s->pb, 6, run); + assert(slevel != 0); + assert(level <= 127); + put_bits(&s->pb, 8, slevel & 0xff); + } else { + put_bits(&s->pb, 1, sign); + } + last_non_zero = i; + } + } + if(last_index > -1){ + put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]);// END OF BLOCK + } +} + +/***********************************************/ +/* decoding */ + +static VLC h261_mba_vlc; +static VLC h261_mtype_vlc; +static VLC h261_mv_vlc; +static VLC h261_cbp_vlc; + +void init_vlc_rl(RLTable *rl, int use_static); + +static void h261_decode_init_vlc(H261Context *h){ + static int done = 0; + + if(!done){ + done = 1; + init_vlc(&h261_mba_vlc, H261_MBA_VLC_BITS, 35, + h261_mba_bits, 1, 1, + h261_mba_code, 1, 1, 1); + init_vlc(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10, + h261_mtype_bits, 1, 1, + h261_mtype_code, 1, 1, 1); + init_vlc(&h261_mv_vlc, H261_MV_VLC_BITS, 17, + &h261_mv_tab[0][1], 2, 1, + &h261_mv_tab[0][0], 2, 1, 1); + init_vlc(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63, + &h261_cbp_tab[0][1], 2, 1, + &h261_cbp_tab[0][0], 2, 1, 1); + init_rl(&h261_rl_tcoeff, 1); + init_vlc_rl(&h261_rl_tcoeff, 1); + } +} + +static int h261_decode_init(AVCodecContext *avctx){ + H261Context *h= avctx->priv_data; + MpegEncContext * const s = &h->s; + + // set defaults + MPV_decode_defaults(s); + s->avctx = avctx; + + s->width = s->avctx->coded_width; + s->height = s->avctx->coded_height; + s->codec_id = s->avctx->codec->id; + + s->out_format = FMT_H261; + s->low_delay= 1; + avctx->pix_fmt= PIX_FMT_YUV420P; + + s->codec_id= avctx->codec->id; + + h261_decode_init_vlc(h); + + h->gob_start_code_skipped = 0; + + return 0; +} + +/** + * decodes the group of blocks header or slice header. + * @return <0 if an error occured + */ +static int h261_decode_gob_header(H261Context *h){ + unsigned int val; + MpegEncContext * const s = &h->s; + + if ( !h->gob_start_code_skipped ){ + /* Check for GOB Start Code */ + val = show_bits(&s->gb, 15); + if(val) + return -1; + + /* We have a GBSC */ + skip_bits(&s->gb, 16); + } + + h->gob_start_code_skipped = 0; + + h->gob_number = get_bits(&s->gb, 4); /* GN */ + s->qscale = get_bits(&s->gb, 5); /* GQUANT */ + + /* Check if gob_number is valid */ + if (s->mb_height==18){ //cif + if ((h->gob_number<=0) || (h->gob_number>12)) + return -1; + } + else{ //qcif + if ((h->gob_number!=1) && (h->gob_number!=3) && (h->gob_number!=5)) + return -1; + } + + /* GEI */ + while (get_bits1(&s->gb) != 0) { + skip_bits(&s->gb, 8); + } + + if(s->qscale==0) + return -1; + + // For the first transmitted macroblock in a GOB, MBA is the absolute address. For + // subsequent macroblocks, MBA is the difference between the absolute addresses of + // the macroblock and the last transmitted macroblock. + h->current_mba = 0; + h->mba_diff = 0; + + return 0; +} + +/** + * decodes the group of blocks / video packet header. + * @return <0 if no resync found + */ +static int ff_h261_resync(H261Context *h){ + MpegEncContext * const s = &h->s; + int left, ret; + + if ( h->gob_start_code_skipped ){ + ret= h261_decode_gob_header(h); + if(ret>=0) + return 0; + } + else{ + if(show_bits(&s->gb, 15)==0){ + ret= h261_decode_gob_header(h); + if(ret>=0) + return 0; + } + //ok, its not where its supposed to be ... + s->gb= s->last_resync_gb; + align_get_bits(&s->gb); + left= s->gb.size_in_bits - get_bits_count(&s->gb); + + for(;left>15+1+4+5; left-=8){ + if(show_bits(&s->gb, 15)==0){ + GetBitContext bak= s->gb; + + ret= h261_decode_gob_header(h); + if(ret>=0) + return 0; + + s->gb= bak; + } + skip_bits(&s->gb, 8); + } + } + + return -1; +} + +/** + * decodes skipped macroblocks + * @return 0 + */ +static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 ) +{ + MpegEncContext * const s = &h->s; + int i; + + s->mb_intra = 0; + + for(i=mba1; imb_x= ((h->gob_number-1) % 2) * 11 + i % 11; + s->mb_y= ((h->gob_number-1) / 2) * 3 + i / 11; + xy = s->mb_x + s->mb_y * s->mb_stride; + ff_init_block_index(s); + ff_update_block_index(s); + + for(j=0;j<6;j++) + s->block_last_index[j] = -1; + + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mb_skipped = 1; + h->mtype &= ~MB_TYPE_H261_FIL; + + MPV_decode_mb(s, s->block); + } + + return 0; +} + +static int decode_mv_component(GetBitContext *gb, int v){ + int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2); + + /* check if mv_diff is valid */ + if ( mv_diff < 0 ) + return v; + + mv_diff = mvmap[mv_diff]; + + if(mv_diff && !get_bits1(gb)) + mv_diff= -mv_diff; + + v += mv_diff; + if (v <=-16) v+= 32; + else if(v >= 16) v-= 32; + + return v; +} + +static int h261_decode_mb(H261Context *h){ + MpegEncContext * const s = &h->s; + int i, cbp, xy; + + cbp = 63; + // Read mba + do{ + h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, H261_MBA_VLC_BITS, 2); + + /* Check for slice end */ + /* NOTE: GOB can be empty (no MB data) or exist only of MBA_stuffing */ + if (h->mba_diff == MBA_STARTCODE){ // start code + h->gob_start_code_skipped = 1; + return SLICE_END; + } + } + while( h->mba_diff == MBA_STUFFING ); // stuffing + + if ( h->mba_diff < 0 ){ + if ( get_bits_count(&s->gb) + 7 >= s->gb.size_in_bits ) + return SLICE_END; + + av_log(s->avctx, AV_LOG_ERROR, "illegal mba at %d %d\n", s->mb_x, s->mb_y); + return SLICE_ERROR; + } + + h->mba_diff += 1; + h->current_mba += h->mba_diff; + + if ( h->current_mba > MBA_STUFFING ) + return SLICE_ERROR; + + s->mb_x= ((h->gob_number-1) % 2) * 11 + ((h->current_mba-1) % 11); + s->mb_y= ((h->gob_number-1) / 2) * 3 + ((h->current_mba-1) / 11); + xy = s->mb_x + s->mb_y * s->mb_stride; + ff_init_block_index(s); + ff_update_block_index(s); + + // Read mtype + h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2); + h->mtype = h261_mtype_map[h->mtype]; + + // Read mquant + if ( IS_QUANT ( h->mtype ) ){ + ff_set_qscale(s, get_bits(&s->gb, 5)); + } + + s->mb_intra = IS_INTRA4x4(h->mtype); + + // Read mv + if ( IS_16X16 ( h->mtype ) ){ + // Motion vector data is included for all MC macroblocks. MVD is obtained from the macroblock vector by subtracting the + // vector of the preceding macroblock. For this calculation the vector of the preceding macroblock is regarded as zero in the + // following three situations: + // 1) evaluating MVD for macroblocks 1, 12 and 23; + // 2) evaluating MVD for macroblocks in which MBA does not represent a difference of 1; + // 3) MTYPE of the previous macroblock was not MC. + if ( ( h->current_mba == 1 ) || ( h->current_mba == 12 ) || ( h->current_mba == 23 ) || + ( h->mba_diff != 1)) + { + h->current_mv_x = 0; + h->current_mv_y = 0; + } + + h->current_mv_x= decode_mv_component(&s->gb, h->current_mv_x); + h->current_mv_y= decode_mv_component(&s->gb, h->current_mv_y); + }else{ + h->current_mv_x = 0; + h->current_mv_y = 0; + } + + // Read cbp + if ( HAS_CBP( h->mtype ) ){ + cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1; + } + + if(s->mb_intra){ + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + goto intra; + } + + //set motion vectors + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; + s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation + s->mv[0][0][1] = h->current_mv_y * 2; + +intra: + /* decode each block */ + if(s->mb_intra || HAS_CBP(h->mtype)){ + s->dsp.clear_blocks(s->block[0]); + for (i = 0; i < 6; i++) { + if (h261_decode_block(h, s->block[i], i, cbp&32) < 0){ + return SLICE_ERROR; + } + cbp+=cbp; + } + }else{ + for (i = 0; i < 6; i++) + s->block_last_index[i]= -1; + } + + MPV_decode_mb(s, s->block); + + return SLICE_OK; +} + +/** + * decodes a macroblock + * @return <0 if an error occured + */ +static int h261_decode_block(H261Context * h, DCTELEM * block, + int n, int coded) +{ + MpegEncContext * const s = &h->s; + int code, level, i, j, run; + RLTable *rl = &h261_rl_tcoeff; + const uint8_t *scan_table; + + // For the variable length encoding there are two code tables, one being used for + // the first transmitted LEVEL in INTER, INTER+MC and INTER+MC+FIL blocks, the second + // for all other LEVELs except the first one in INTRA blocks which is fixed length + // coded with 8 bits. + // NOTE: the two code tables only differ in one VLC so we handle that manually. + scan_table = s->intra_scantable.permutated; + if (s->mb_intra){ + /* DC coef */ + level = get_bits(&s->gb, 8); + // 0 (00000000b) and -128 (10000000b) are FORBIDDEN + if((level&0x7F) == 0){ + av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y); + return -1; + } + // The code 1000 0000 is not used, the reconstruction level of 1024 being coded as 1111 1111. + if (level == 255) + level = 128; + block[0] = level; + i = 1; + }else if(coded){ + // Run Level Code + // EOB Not possible for first level when cbp is available (that's why the table is different) + // 0 1 1s + // * * 0* + int check = show_bits(&s->gb, 2); + i = 0; + if ( check & 0x2 ){ + skip_bits(&s->gb, 2); + block[0] = ( check & 0x1 ) ? -1 : 1; + i = 1; + } + }else{ + i = 0; + } + if(!coded){ + s->block_last_index[n] = i - 1; + return 0; + } + for(;;){ + code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2); + if (code < 0){ + av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y); + return -1; + } + if (code == rl->n) { + /* escape */ + // The remaining combinations of (run, level) are encoded with a 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits level. + run = get_bits(&s->gb, 6); + level = get_sbits(&s->gb, 8); + }else if(code == 0){ + break; + }else{ + run = rl->table_run[code]; + level = rl->table_level[code]; + if (get_bits1(&s->gb)) + level = -level; + } + i += run; + if (i >= 64){ + av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", s->mb_x, s->mb_y); + return -1; + } + j = scan_table[i]; + block[j] = level; + i++; + } + s->block_last_index[n] = i-1; + return 0; +} + +/** + * decodes the H261 picture header. + * @return <0 if no startcode found + */ +static int h261_decode_picture_header(H261Context *h){ + MpegEncContext * const s = &h->s; + int format, i; + uint32_t startcode= 0; + + for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>24; i-=1){ + startcode = ((startcode << 1) | get_bits(&s->gb, 1)) & 0x000FFFFF; + + if(startcode == 0x10) + break; + } + + if (startcode != 0x10){ + av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n"); + return -1; + } + + /* temporal reference */ + s->picture_number = get_bits(&s->gb, 5); /* picture timestamp */ + + /* PTYPE starts here */ + skip_bits1(&s->gb); /* split screen off */ + skip_bits1(&s->gb); /* camera off */ + skip_bits1(&s->gb); /* freeze picture release off */ + + format = get_bits1(&s->gb); + + //only 2 formats possible + if (format == 0){//QCIF + s->width = 176; + s->height = 144; + s->mb_width = 11; + s->mb_height = 9; + }else{//CIF + s->width = 352; + s->height = 288; + s->mb_width = 22; + s->mb_height = 18; + } + + s->mb_num = s->mb_width * s->mb_height; + + skip_bits1(&s->gb); /* still image mode off */ + skip_bits1(&s->gb); /* Reserved */ + + /* PEI */ + while (get_bits1(&s->gb) != 0){ + skip_bits(&s->gb, 8); + } + + // h261 has no I-FRAMES, but if we pass I_TYPE for the first frame, the codec crashes if it does + // not contain all I-blocks (e.g. when a packet is lost) + s->pict_type = P_TYPE; + + h->gob_number = 0; + return 0; +} + +static int h261_decode_gob(H261Context *h){ + MpegEncContext * const s = &h->s; + + ff_set_qscale(s, s->qscale); + + /* decode mb's */ + while(h->current_mba <= MBA_STUFFING) + { + int ret; + /* DCT & quantize */ + ret= h261_decode_mb(h); + if(ret<0){ + if(ret==SLICE_END){ + h261_decode_mb_skipped(h, h->current_mba, 33); + return 0; + } + av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", s->mb_x + s->mb_y*s->mb_stride); + return -1; + } + + h261_decode_mb_skipped(h, h->current_mba-h->mba_diff, h->current_mba-1); + } + + return -1; +} + +static int h261_find_frame_end(ParseContext *pc, AVCodecContext* avctx, const uint8_t *buf, int buf_size){ + int vop_found, i, j; + uint32_t state; + + vop_found= pc->frame_start_found; + state= pc->state; + + for(i=0; i>j)&0xFFFFF) == 0x00010){ + i++; + vop_found=1; + break; + } + } + } + if(vop_found){ + for(; i>j)&0xFFFFF) == 0x00010){ + pc->frame_start_found=0; + pc->state= state>>(2*8); + return i-1; + } + } + } + } + + pc->frame_start_found= vop_found; + pc->state= state; + return END_NOT_FOUND; +} + +static int h261_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + int next; + + next= h261_find_frame_end(pc,avctx, buf, buf_size); + if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + *poutbuf = (uint8_t *)buf; + *poutbuf_size = buf_size; + return next; +} + +/** + * returns the number of bytes consumed for building the current frame + */ +static int get_consumed_bytes(MpegEncContext *s, int buf_size){ + int pos= get_bits_count(&s->gb)>>3; + if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) + if(pos+10>buf_size) pos=buf_size; // oops ;) + + return pos; +} + +static int h261_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + H261Context *h= avctx->priv_data; + MpegEncContext *s = &h->s; + int ret; + AVFrame *pict = data; + +#ifdef DEBUG + av_log(avctx, AV_LOG_DEBUG, "*****frame %d size=%d\n", avctx->frame_number, buf_size); + av_log(avctx, AV_LOG_DEBUG, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); +#endif + s->flags= avctx->flags; + s->flags2= avctx->flags2; + + h->gob_start_code_skipped=0; + +retry: + + init_get_bits(&s->gb, buf, buf_size*8); + + if(!s->context_initialized){ + if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix + return -1; + } + + //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there + if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ + int i= ff_find_unused_picture(s, 0); + s->current_picture_ptr= &s->picture[i]; + } + + ret = h261_decode_picture_header(h); + + /* skip if the header was thrashed */ + if (ret < 0){ + av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); + return -1; + } + + if (s->width != avctx->coded_width || s->height != avctx->coded_height){ + ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat + s->parse_context.buffer=0; + MPV_common_end(s); + s->parse_context= pc; + } + if (!s->context_initialized) { + avcodec_set_dimensions(avctx, s->width, s->height); + + goto retry; + } + + // for hurry_up==5 + s->current_picture.pict_type= s->pict_type; + s->current_picture.key_frame= s->pict_type == I_TYPE; + + /* skip everything if we are in a hurry>=5 */ + if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size); + if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) + ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) + || avctx->skip_frame >= AVDISCARD_ALL) + return get_consumed_bytes(s, buf_size); + + if(MPV_frame_start(s, avctx) < 0) + return -1; + + ff_er_frame_start(s); + + /* decode each macroblock */ + s->mb_x=0; + s->mb_y=0; + + while(h->gob_number < (s->mb_height==18 ? 12 : 5)){ + if(ff_h261_resync(h)<0) + break; + h261_decode_gob(h); + } + MPV_frame_end(s); + +assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type); +assert(s->current_picture.pict_type == s->pict_type); + *pict= *(AVFrame*)s->current_picture_ptr; + ff_print_debug_info(s, pict); + + /* Return the Picture timestamp as the frame number */ + /* we substract 1 because it is added on utils.c */ + avctx->frame_number = s->picture_number - 1; + + *data_size = sizeof(AVFrame); + + return get_consumed_bytes(s, buf_size); +} + +static int h261_decode_end(AVCodecContext *avctx) +{ + H261Context *h= avctx->priv_data; + MpegEncContext *s = &h->s; + + MPV_common_end(s); + return 0; +} + +#ifdef CONFIG_ENCODERS +AVCodec h261_encoder = { + "h261", + CODEC_TYPE_VIDEO, + CODEC_ID_H261, + sizeof(H261Context), + MPV_encode_init, + MPV_encode_picture, + MPV_encode_end, +}; +#endif + +AVCodec h261_decoder = { + "h261", + CODEC_TYPE_VIDEO, + CODEC_ID_H261, + sizeof(H261Context), + h261_decode_init, + NULL, + h261_decode_end, + h261_decode_frame, + CODEC_CAP_DR1, +}; + +AVCodecParser h261_parser = { + { CODEC_ID_H261 }, + sizeof(ParseContext), + NULL, + h261_parse, + ff_parse_close, +}; diff --git a/mpeg4/src/libavcodec/h261data.h b/mpeg4/src/libavcodec/h261data.h new file mode 100644 index 00000000..9ea991b2 --- /dev/null +++ b/mpeg4/src/libavcodec/h261data.h @@ -0,0 +1,136 @@ +/** + * @file h261data.h + * H.261 tables. + */ +#define MB_TYPE_H261_FIL 0x800000 + +// H.261 VLC table for macroblock addressing +const uint8_t h261_mba_code[35] = { + 1, 3, 2, 3, + 2, 3, 2, 7, + 6, 11, 10, 9, + 8, 7, 6, 23, + 22, 21, 20, 19, + 18, 35, 34, 33, + 32, 31, 30, 29, + 28, 27, 26, 25, + 24, + 15, //(MBA stuffing) + 1 //(start code) +}; + +const uint8_t h261_mba_bits[35] = { + 1, 3, 3, 4, + 4, 5, 5, 7, + 7, 8, 8, 8, + 8, 8, 8, 10, + 10, 10, 10, 10, + 10, 11, 11, 11, + 11, 11, 11, 11, + 11, 11, 11, 11, + 11, + 11, //(MBA stuffing) + 16 //(start code) +}; + +//H.261 VLC table for macroblock type +const uint8_t h261_mtype_code[10] = { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1 +}; + +const uint8_t h261_mtype_bits[10] = { + 4, 7, 1, 5, + 9, 8, 10, 3, + 2, 6 +}; + +static const int h261_mtype_map[10]= { + MB_TYPE_INTRA4x4, + MB_TYPE_INTRA4x4 | MB_TYPE_QUANT, + MB_TYPE_CBP, + MB_TYPE_QUANT | MB_TYPE_CBP, + MB_TYPE_16x16, + MB_TYPE_CBP | MB_TYPE_16x16, + MB_TYPE_QUANT | MB_TYPE_CBP | MB_TYPE_16x16, + MB_TYPE_16x16 | MB_TYPE_H261_FIL, + MB_TYPE_CBP | MB_TYPE_16x16 | MB_TYPE_H261_FIL, + MB_TYPE_QUANT | MB_TYPE_CBP | MB_TYPE_16x16 | MB_TYPE_H261_FIL +}; + +//H.261 VLC table for motion vectors +const uint8_t h261_mv_tab[17][2] = { + {1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7}, + {11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10}, {12,10} +}; + +static const int mvmap[17] = +{ + 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16 +}; + +//H.261 VLC table for coded block pattern +const uint8_t h261_cbp_tab[63][2] = +{ + {11,5}, {9,5}, {13,6}, {13,4}, {23,7}, {19,7}, {31,8}, {12,4}, + {22,7}, {18,7}, {30,8}, {19,5}, {27,8}, {23,8}, {19,8}, {11,4}, + {21,7}, {17,7}, {29,8}, {17,5}, {25,8}, {21,8}, {17,8}, {15,6}, + {15,8}, {13,8}, {3,9}, {15,5}, {11,8}, {7,8}, {7,9}, {10,4}, + {20,7}, {16,7}, {28,8}, {14,6}, {14,8}, {12,8}, {2,9}, {16,5}, + {24,8}, {20,8}, {16,8}, {14,5}, {10,8}, {6,8}, {6,9}, {18,5}, + {26,8}, {22,8}, {18,8}, {13,5}, {9,8}, {5,8}, {5,9}, {12,5}, + {8,8}, {4,8}, {4,9}, {7,3}, {10,5}, {8,5}, {12,6} +}; + +//H.261 VLC table for transform coefficients +const uint16_t h261_tcoeff_vlc[65][2] = { +{ 0x2, 2 }, { 0x3, 2 },{ 0x4, 4 },{ 0x5, 5 }, +{ 0x6, 7 },{ 0x26, 8 },{ 0x21, 8 },{ 0xa, 10 }, +{ 0x1d, 12 },{ 0x18, 12 },{ 0x13, 12 },{ 0x10 , 12 }, +{ 0x1a, 13},{ 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 }, +{ 0x3, 3 }, { 0x6, 6 }, { 0x25 , 8 }, { 0xc, 10 }, +{ 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x5, 4}, +{ 0x4, 7}, { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 }, +{ 0x7, 5 }, { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 }, +{ 0x6, 5 }, { 0xf, 10 }, { 0x12, 12}, { 0x7, 6}, +{ 0x9 , 10 }, { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 }, +{ 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12}, +{ 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 }, +{ 0x23, 8 }, { 0x22, 8 }, { 0x20, 8 }, { 0xe , 10 }, +{ 0xd, 10 }, { 0x8, 10 },{ 0x1f, 12 }, { 0x1a, 12 }, +{ 0x19, 12 }, { 0x17, 12 }, { 0x16, 12}, { 0x1f, 13}, +{ 0x1e, 13 }, { 0x1d, 13 }, { 0x1c, 13}, { 0x1b, 13}, +{ 0x1, 6 } //escape +}; + +const int8_t h261_tcoeff_level[64] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 1, 2, 3, 4, 5, 6, 7, 1, + 2, 3, 4, 5, 1, 2, 3, 4, + 1, 2, 3, 1, 2, 3, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 +}; + +const int8_t h261_tcoeff_run[64] = { + 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 3, 3, 3, 3, 4, + 4, 4, 5, 5, 5, 6, 6, 7, + 7, 8, 8, 9, 9, 10, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26 +}; + +static RLTable h261_rl_tcoeff = { + 64, + 64, + h261_tcoeff_vlc, + h261_tcoeff_run, + h261_tcoeff_level, +}; diff --git a/mpeg4/src/libavcodec/h263.c b/mpeg4/src/libavcodec/h263.c new file mode 100644 index 00000000..df05cbac --- /dev/null +++ b/mpeg4/src/libavcodec/h263.c @@ -0,0 +1,6276 @@ +/* + * H263/MPEG4 backend for ffmpeg encoder and decoder + * Copyright (c) 2000,2001 Fabrice Bellard. + * H263+ support. + * Copyright (c) 2001 Juan J. Sierralta P. + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * ac prediction encoding, b-frame support, error resilience, optimizations, + * qpel decoding, gmc decoding, interlaced decoding, + * by Michael Niedermayer + */ + +/** + * @file h263.c + * h263/mpeg4 codec. + */ + +//#define DEBUG +#include + +#include "common.h" +#include "dsputil.h" +#include "avcodec.h" +#include "mpegvideo.h" +#include "h263data.h" +#include "mpeg4data.h" + +//#undef NDEBUG +//#include + +#define INTRA_MCBPC_VLC_BITS 6 +#define INTER_MCBPC_VLC_BITS 7 +#define CBPY_VLC_BITS 6 +#define MV_VLC_BITS 9 +#define DC_VLC_BITS 9 +#define SPRITE_TRAJ_VLC_BITS 6 +#define MB_TYPE_B_VLC_BITS 4 +#define TEX_VLC_BITS 9 +#define H263_MBTYPE_B_VLC_BITS 6 +#define CBPC_B_VLC_BITS 3 + +#ifdef CONFIG_ENCODERS +static void h263_encode_block(MpegEncContext * s, DCTELEM * block, + int n); +static void h263p_encode_umotion(MpegEncContext * s, int val); +static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, + int n, int dc, uint8_t *scan_table, + PutBitContext *dc_pb, PutBitContext *ac_pb); +#endif + +static int h263_decode_motion(MpegEncContext * s, int pred, int fcode); +static int h263p_decode_umotion(MpegEncContext * s, int pred); +static int h263_decode_block(MpegEncContext * s, DCTELEM * block, + int n, int coded); +static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); +static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, + int n, int coded, int intra, int rvlc); +static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, + uint8_t *scan_table); +static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr); +#ifdef CONFIG_ENCODERS +static void mpeg4_encode_visual_object_header(MpegEncContext * s); +static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number); +#endif //CONFIG_ENCODERS +static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb); +static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding); + +#ifdef CONFIG_ENCODERS +static uint8_t uni_DCtab_lum_len[512]; +static uint8_t uni_DCtab_chrom_len[512]; +static uint16_t uni_DCtab_lum_bits[512]; +static uint16_t uni_DCtab_chrom_bits[512]; + +static uint8_t (*mv_penalty)[MAX_MV*2+1]= NULL; +static uint8_t fcode_tab[MAX_MV*2+1]; +static uint8_t umv_fcode_tab[MAX_MV*2+1]; + +static uint32_t uni_mpeg4_intra_rl_bits[64*64*2*2]; +static uint8_t uni_mpeg4_intra_rl_len [64*64*2*2]; +static uint32_t uni_mpeg4_inter_rl_bits[64*64*2*2]; +static uint8_t uni_mpeg4_inter_rl_len [64*64*2*2]; +static uint8_t uni_h263_intra_aic_rl_len [64*64*2*2]; +static uint8_t uni_h263_inter_rl_len [64*64*2*2]; +//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level)) +//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64) +#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level)) + +/* mpeg4 +inter +max level: 24/6 +max run: 53/63 + +intra +max level: 53/16 +max run: 29/41 +*/ +#endif + +#if 0 //3IV1 is quite rare and it slows things down a tiny bit +#define IS_3IV1 s->avctx->codec_tag == ff_get_fourcc("3IV1") +#else +#define IS_3IV1 0 +#endif + +int h263_get_picture_format(int width, int height) +{ + int format; + + if (width == 128 && height == 96) + format = 1; + else if (width == 176 && height == 144) + format = 2; + else if (width == 352 && height == 288) + format = 3; + else if (width == 704 && height == 576) + format = 4; + else if (width == 1408 && height == 1152) + format = 5; + else + format = 7; + return format; +} + +#ifdef CONFIG_ENCODERS + +static void aspect_to_info(MpegEncContext * s, AVRational aspect){ + int i; + + if(aspect.num==0) aspect= (AVRational){1,1}; + + for(i=1; i<6; i++){ + if(av_cmp_q(pixel_aspect[i], aspect) == 0){ + s->aspect_ratio_info=i; + return; + } + } + + s->aspect_ratio_info= FF_ASPECT_EXTENDED; +} + +void ff_flv_encode_picture_header(MpegEncContext * s, int picture_number) +{ + int format; + + align_put_bits(&s->pb); + + put_bits(&s->pb, 17, 1); + put_bits(&s->pb, 5, (s->h263_flv-1)); /* 0: h263 escape codes 1: 11-bit escape codes */ + put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * s->avctx->time_base.num) / //FIXME use timestamp + s->avctx->time_base.den) & 0xff); /* TemporalReference */ + if (s->width == 352 && s->height == 288) + format = 2; + else if (s->width == 176 && s->height == 144) + format = 3; + else if (s->width == 128 && s->height == 96) + format = 4; + else if (s->width == 320 && s->height == 240) + format = 5; + else if (s->width == 160 && s->height == 120) + format = 6; + else if (s->width <= 255 && s->height <= 255) + format = 0; /* use 1 byte width & height */ + else + format = 1; /* use 2 bytes width & height */ + put_bits(&s->pb, 3, format); /* PictureSize */ + if (format == 0) { + put_bits(&s->pb, 8, s->width); + put_bits(&s->pb, 8, s->height); + } else if (format == 1) { + put_bits(&s->pb, 16, s->width); + put_bits(&s->pb, 16, s->height); + } + put_bits(&s->pb, 2, s->pict_type == P_TYPE); /* PictureType */ + put_bits(&s->pb, 1, 1); /* DeblockingFlag: on */ + put_bits(&s->pb, 5, s->qscale); /* Quantizer */ + put_bits(&s->pb, 1, 0); /* ExtraInformation */ + + if(s->h263_aic){ + s->y_dc_scale_table= + s->c_dc_scale_table= ff_aic_dc_scale_table; + }else{ + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + } +} + +void h263_encode_picture_header(MpegEncContext * s, int picture_number) +{ + int format, coded_frame_rate, coded_frame_rate_base, i, temp_ref; + int best_clock_code=1; + int best_divisor=60; + int best_error= INT_MAX; + + if(s->h263_plus){ + for(i=0; i<2; i++){ + int div, error; + div= (s->avctx->time_base.num*1800000LL + 500LL*s->avctx->time_base.den) / ((1000LL+i)*s->avctx->time_base.den); + div= clip(1, div, 127); + error= ABS(s->avctx->time_base.num*1800000LL - (1000LL+i)*s->avctx->time_base.den*div); + if(error < best_error){ + best_error= error; + best_divisor= div; + best_clock_code= i; + } + } + } + s->custom_pcf= best_clock_code!=1 || best_divisor!=60; + coded_frame_rate= 1800000; + coded_frame_rate_base= (1000+best_clock_code)*best_divisor; + + align_put_bits(&s->pb); + + /* Update the pointer to last GOB */ + s->ptr_lastgob = pbBufPtr(&s->pb); + put_bits(&s->pb, 22, 0x20); /* PSC */ + temp_ref= s->picture_number * (int64_t)coded_frame_rate * s->avctx->time_base.num / //FIXME use timestamp + (coded_frame_rate_base * (int64_t)s->avctx->time_base.den); + put_bits(&s->pb, 8, temp_ref & 0xff); /* TemporalReference */ + + put_bits(&s->pb, 1, 1); /* marker */ + put_bits(&s->pb, 1, 0); /* h263 id */ + put_bits(&s->pb, 1, 0); /* split screen off */ + put_bits(&s->pb, 1, 0); /* camera off */ + put_bits(&s->pb, 1, 0); /* freeze picture release off */ + + format = h263_get_picture_format(s->width, s->height); + if (!s->h263_plus) { + /* H.263v1 */ + put_bits(&s->pb, 3, format); + put_bits(&s->pb, 1, (s->pict_type == P_TYPE)); + /* By now UMV IS DISABLED ON H.263v1, since the restrictions + of H.263v1 UMV implies to check the predicted MV after + calculation of the current MB to see if we're on the limits */ + put_bits(&s->pb, 1, 0); /* Unrestricted Motion Vector: off */ + put_bits(&s->pb, 1, 0); /* SAC: off */ + put_bits(&s->pb, 1, s->obmc); /* Advanced Prediction */ + put_bits(&s->pb, 1, 0); /* only I/P frames, no PB frame */ + put_bits(&s->pb, 5, s->qscale); + put_bits(&s->pb, 1, 0); /* Continuous Presence Multipoint mode: off */ + } else { + int ufep=1; + /* H.263v2 */ + /* H.263 Plus PTYPE */ + + put_bits(&s->pb, 3, 7); + put_bits(&s->pb,3,ufep); /* Update Full Extended PTYPE */ + if (format == 7) + put_bits(&s->pb,3,6); /* Custom Source Format */ + else + put_bits(&s->pb, 3, format); + + put_bits(&s->pb,1, s->custom_pcf); + put_bits(&s->pb,1, s->umvplus); /* Unrestricted Motion Vector */ + put_bits(&s->pb,1,0); /* SAC: off */ + put_bits(&s->pb,1,s->obmc); /* Advanced Prediction Mode */ + put_bits(&s->pb,1,s->h263_aic); /* Advanced Intra Coding */ + put_bits(&s->pb,1,s->loop_filter); /* Deblocking Filter */ + put_bits(&s->pb,1,s->h263_slice_structured); /* Slice Structured */ + put_bits(&s->pb,1,0); /* Reference Picture Selection: off */ + put_bits(&s->pb,1,0); /* Independent Segment Decoding: off */ + put_bits(&s->pb,1,s->alt_inter_vlc); /* Alternative Inter VLC */ + put_bits(&s->pb,1,s->modified_quant); /* Modified Quantization: */ + put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ + put_bits(&s->pb,3,0); /* Reserved */ + + put_bits(&s->pb, 3, s->pict_type == P_TYPE); + + put_bits(&s->pb,1,0); /* Reference Picture Resampling: off */ + put_bits(&s->pb,1,0); /* Reduced-Resolution Update: off */ + put_bits(&s->pb,1,s->no_rounding); /* Rounding Type */ + put_bits(&s->pb,2,0); /* Reserved */ + put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ + + /* This should be here if PLUSPTYPE */ + put_bits(&s->pb, 1, 0); /* Continuous Presence Multipoint mode: off */ + + if (format == 7) { + /* Custom Picture Format (CPFMT) */ + aspect_to_info(s, s->avctx->sample_aspect_ratio); + + put_bits(&s->pb,4,s->aspect_ratio_info); + put_bits(&s->pb,9,(s->width >> 2) - 1); + put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ + put_bits(&s->pb,9,(s->height >> 2)); + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){ + put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num); + put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den); + } + } + if(s->custom_pcf){ + if(ufep){ + put_bits(&s->pb, 1, best_clock_code); + put_bits(&s->pb, 7, best_divisor); + } + put_bits(&s->pb, 2, (temp_ref>>8)&3); + } + + /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ + if (s->umvplus) +// put_bits(&s->pb,1,1); /* Limited according tables of Annex D */ +//FIXME check actual requested range + put_bits(&s->pb,2,1); /* unlimited */ + if(s->h263_slice_structured) + put_bits(&s->pb,2,0); /* no weird submodes */ + + put_bits(&s->pb, 5, s->qscale); + } + + put_bits(&s->pb, 1, 0); /* no PEI */ + + if(s->h263_slice_structured){ + put_bits(&s->pb, 1, 1); + + assert(s->mb_x == 0 && s->mb_y == 0); + ff_h263_encode_mba(s); + + put_bits(&s->pb, 1, 1); + } + + if(s->h263_aic){ + s->y_dc_scale_table= + s->c_dc_scale_table= ff_aic_dc_scale_table; + }else{ + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + } +} + +/** + * Encodes a group of blocks header. + */ +void h263_encode_gob_header(MpegEncContext * s, int mb_line) +{ + put_bits(&s->pb, 17, 1); /* GBSC */ + + if(s->h263_slice_structured){ + put_bits(&s->pb, 1, 1); + + ff_h263_encode_mba(s); + + if(s->mb_num > 1583) + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 5, s->qscale); /* GQUANT */ + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 2, s->pict_type == I_TYPE); /* GFID */ + }else{ + int gob_number= mb_line / s->gob_index; + + put_bits(&s->pb, 5, gob_number); /* GN */ + put_bits(&s->pb, 2, s->pict_type == I_TYPE); /* GFID */ + put_bits(&s->pb, 5, s->qscale); /* GQUANT */ + } +} + +static inline int get_block_rate(MpegEncContext * s, DCTELEM block[64], int block_last_index, uint8_t scantable[64]){ + int last=0; + int j; + int rate=0; + + for(j=1; j<=block_last_index; j++){ + const int index= scantable[j]; + int level= block[index]; + if(level){ + level+= 64; + if((level&(~127)) == 0){ + if(jintra_ac_vlc_length [UNI_AC_ENC_INDEX(j-last-1, level)]; + else rate+= s->intra_ac_vlc_last_length[UNI_AC_ENC_INDEX(j-last-1, level)]; + }else + rate += s->ac_esc_length; + level-= 64; + + last= j; + } + } + + return rate; +} + +static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int dir[6], uint8_t *st[6], int zigzag_last_index[6]) +{ + int score= 0; + int i, n; + int8_t * const qscale_table= s->current_picture.qscale_table; + + memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6); + + for(n=0; n<6; n++){ + int16_t *ac_val, *ac_val1; + + score -= get_block_rate(s, block[n], s->block_last_index[n], s->intra_scantable.permutated); + + ac_val = s->ac_val[0][0] + s->block_index[n] * 16; + ac_val1= ac_val; + if(dir[n]){ + const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride; + /* top prediction */ + ac_val-= s->block_wrap[n]*16; + if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ + /* same qscale */ + for(i=1; i<8; i++){ + const int level= block[n][s->dsp.idct_permutation[i ]]; + block[n][s->dsp.idct_permutation[i ]] = level - ac_val[i+8]; + ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]]; + ac_val1[i+8]= level; + } + }else{ + /* different qscale, we must rescale */ + for(i=1; i<8; i++){ + const int level= block[n][s->dsp.idct_permutation[i ]]; + block[n][s->dsp.idct_permutation[i ]] = level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale); + ac_val1[i ]= block[n][s->dsp.idct_permutation[i<<3]]; + ac_val1[i+8]= level; + } + } + st[n]= s->intra_h_scantable.permutated; + }else{ + const int xy= s->mb_x-1 + s->mb_y*s->mb_stride; + /* left prediction */ + ac_val-= 16; + if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ + /* same qscale */ + for(i=1; i<8; i++){ + const int level= block[n][s->dsp.idct_permutation[i<<3]]; + block[n][s->dsp.idct_permutation[i<<3]]= level - ac_val[i]; + ac_val1[i ]= level; + ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]]; + } + }else{ + /* different qscale, we must rescale */ + for(i=1; i<8; i++){ + const int level= block[n][s->dsp.idct_permutation[i<<3]]; + block[n][s->dsp.idct_permutation[i<<3]]= level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale); + ac_val1[i ]= level; + ac_val1[i+8]= block[n][s->dsp.idct_permutation[i ]]; + } + } + st[n]= s->intra_v_scantable.permutated; + } + + for(i=63; i>0; i--) //FIXME optimize + if(block[n][ st[n][i] ]) break; + s->block_last_index[n]= i; + + score += get_block_rate(s, block[n], s->block_last_index[n], st[n]); + } + + return score < 0; +} + +static inline void restore_ac_coeffs(MpegEncContext * s, DCTELEM block[6][64], int dir[6], uint8_t *st[6], int zigzag_last_index[6]) +{ + int i, n; + memcpy(s->block_last_index, zigzag_last_index, sizeof(int)*6); + + for(n=0; n<6; n++){ + int16_t *ac_val = s->ac_val[0][0] + s->block_index[n] * 16; + + st[n]= s->intra_scantable.permutated; + if(dir[n]){ + /* top prediction */ + for(i=1; i<8; i++){ + block[n][s->dsp.idct_permutation[i ]] = ac_val[i+8]; + } + }else{ + /* left prediction */ + for(i=1; i<8; i++){ + block[n][s->dsp.idct_permutation[i<<3]]= ac_val[i ]; + } + } + } +} + +/** + * modify qscale so that encoding is acually possible in h263 (limit difference to -2..2) + */ +void ff_clean_h263_qscales(MpegEncContext *s){ + int i; + int8_t * const qscale_table= s->current_picture.qscale_table; + + for(i=1; imb_num; i++){ + if(qscale_table[ s->mb_index2xy[i] ] - qscale_table[ s->mb_index2xy[i-1] ] >2) + qscale_table[ s->mb_index2xy[i] ]= qscale_table[ s->mb_index2xy[i-1] ]+2; + } + for(i=s->mb_num-2; i>=0; i--){ + if(qscale_table[ s->mb_index2xy[i] ] - qscale_table[ s->mb_index2xy[i+1] ] >2) + qscale_table[ s->mb_index2xy[i] ]= qscale_table[ s->mb_index2xy[i+1] ]+2; + } + + if(s->codec_id != CODEC_ID_H263P){ + for(i=1; imb_num; i++){ + int mb_xy= s->mb_index2xy[i]; + + if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_INTER4V)){ + s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_INTER4V; + s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_INTER; + } + } + } +} + +/** + * modify mb_type & qscale so that encoding is acually possible in mpeg4 + */ +void ff_clean_mpeg4_qscales(MpegEncContext *s){ + int i; + int8_t * const qscale_table= s->current_picture.qscale_table; + + ff_clean_h263_qscales(s); + + if(s->pict_type== B_TYPE){ + int odd=0; + /* ok, come on, this isn't funny anymore, there's more code for handling this mpeg4 mess than for the actual adaptive quantization */ + + for(i=0; imb_num; i++){ + int mb_xy= s->mb_index2xy[i]; + odd += qscale_table[mb_xy]&1; + } + + if(2*odd > s->mb_num) odd=1; + else odd=0; + + for(i=0; imb_num; i++){ + int mb_xy= s->mb_index2xy[i]; + if((qscale_table[mb_xy]&1) != odd) + qscale_table[mb_xy]++; + if(qscale_table[mb_xy] > 31) + qscale_table[mb_xy]= 31; + } + + for(i=1; imb_num; i++){ + int mb_xy= s->mb_index2xy[i]; + if(qscale_table[mb_xy] != qscale_table[s->mb_index2xy[i-1]] && (s->mb_type[mb_xy]&CANDIDATE_MB_TYPE_DIRECT)){ + s->mb_type[mb_xy]&= ~CANDIDATE_MB_TYPE_DIRECT; + s->mb_type[mb_xy]|= CANDIDATE_MB_TYPE_BIDIR; + } + } + } +} + +#endif //CONFIG_ENCODERS + +#define tab_size ((signed)(sizeof(s->direct_scale_mv[0])/sizeof(int16_t))) +#define tab_bias (tab_size/2) + +static void ff_mpeg4_init_direct_mv(MpegEncContext *s){ + int i; + for(i=0; idirect_scale_mv[0][i] = (i-tab_bias)*s->pb_time/s->pp_time; + s->direct_scale_mv[1][i] = (i-tab_bias)*(s->pb_time-s->pp_time)/s->pp_time; + } +} + +static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my, int i){ + int xy= s->block_index[i]; + uint16_t time_pp= s->pp_time; + uint16_t time_pb= s->pb_time; + int p_mx, p_my; + + p_mx= s->next_picture.motion_val[0][xy][0]; + if((unsigned)(p_mx + tab_bias) < tab_size){ + s->mv[0][i][0] = s->direct_scale_mv[0][p_mx + tab_bias] + mx; + s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx + : s->direct_scale_mv[1][p_mx + tab_bias]; + }else{ + s->mv[0][i][0] = p_mx*time_pb/time_pp + mx; + s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx + : p_mx*(time_pb - time_pp)/time_pp; + } + p_my= s->next_picture.motion_val[0][xy][1]; + if((unsigned)(p_my + tab_bias) < tab_size){ + s->mv[0][i][1] = s->direct_scale_mv[0][p_my + tab_bias] + my; + s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my + : s->direct_scale_mv[1][p_my + tab_bias]; + }else{ + s->mv[0][i][1] = p_my*time_pb/time_pp + my; + s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my + : p_my*(time_pb - time_pp)/time_pp; + } +} + +#undef tab_size +#undef tab_bias + +/** + * + * @return the mb_type + */ +int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){ + const int mb_index= s->mb_x + s->mb_y*s->mb_stride; + const int colocated_mb_type= s->next_picture.mb_type[mb_index]; + uint16_t time_pp= s->pp_time; + uint16_t time_pb= s->pb_time; + int i; + + //FIXME avoid divides + // try special case with shifts for 1 and 3 B-frames? + + if(IS_8X8(colocated_mb_type)){ + s->mv_type = MV_TYPE_8X8; + for(i=0; i<4; i++){ + ff_mpeg4_set_one_direct_mv(s, mx, my, i); + } + return MB_TYPE_DIRECT2 | MB_TYPE_8x8 | MB_TYPE_L0L1; + } else if(IS_INTERLACED(colocated_mb_type)){ + s->mv_type = MV_TYPE_FIELD; + for(i=0; i<2; i++){ + int field_select= s->next_picture.ref_index[0][s->block_index[2*i]]; + s->field_select[0][i]= field_select; + s->field_select[1][i]= i; + if(s->top_field_first){ + time_pp= s->pp_field_time - field_select + i; + time_pb= s->pb_field_time - field_select + i; + }else{ + time_pp= s->pp_field_time + field_select - i; + time_pb= s->pb_field_time + field_select - i; + } + s->mv[0][i][0] = s->p_field_mv_table[i][0][mb_index][0]*time_pb/time_pp + mx; + s->mv[0][i][1] = s->p_field_mv_table[i][0][mb_index][1]*time_pb/time_pp + my; + s->mv[1][i][0] = mx ? s->mv[0][i][0] - s->p_field_mv_table[i][0][mb_index][0] + : s->p_field_mv_table[i][0][mb_index][0]*(time_pb - time_pp)/time_pp; + s->mv[1][i][1] = my ? s->mv[0][i][1] - s->p_field_mv_table[i][0][mb_index][1] + : s->p_field_mv_table[i][0][mb_index][1]*(time_pb - time_pp)/time_pp; + } + return MB_TYPE_DIRECT2 | MB_TYPE_16x8 | MB_TYPE_L0L1 | MB_TYPE_INTERLACED; + }else{ + ff_mpeg4_set_one_direct_mv(s, mx, my, 0); + s->mv[0][1][0] = s->mv[0][2][0] = s->mv[0][3][0] = s->mv[0][0][0]; + s->mv[0][1][1] = s->mv[0][2][1] = s->mv[0][3][1] = s->mv[0][0][1]; + s->mv[1][1][0] = s->mv[1][2][0] = s->mv[1][3][0] = s->mv[1][0][0]; + s->mv[1][1][1] = s->mv[1][2][1] = s->mv[1][3][1] = s->mv[1][0][1]; + if((s->avctx->workaround_bugs & FF_BUG_DIRECT_BLOCKSIZE) || !s->quarter_sample) + s->mv_type= MV_TYPE_16X16; + else + s->mv_type= MV_TYPE_8X8; + return MB_TYPE_DIRECT2 | MB_TYPE_16x16 | MB_TYPE_L0L1; //Note see prev line + } +} + +void ff_h263_update_motion_val(MpegEncContext * s){ + const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; + //FIXME a lot of that is only needed for !low_delay + const int wrap = s->b8_stride; + const int xy = s->block_index[0]; + + s->current_picture.mbskip_table[mb_xy]= s->mb_skipped; + + if(s->mv_type != MV_TYPE_8X8){ + int motion_x, motion_y; + if (s->mb_intra) { + motion_x = 0; + motion_y = 0; + } else if (s->mv_type == MV_TYPE_16X16) { + motion_x = s->mv[0][0][0]; + motion_y = s->mv[0][0][1]; + } else /*if (s->mv_type == MV_TYPE_FIELD)*/ { + int i; + motion_x = s->mv[0][0][0] + s->mv[0][1][0]; + motion_y = s->mv[0][0][1] + s->mv[0][1][1]; + motion_x = (motion_x>>1) | (motion_x&1); + for(i=0; i<2; i++){ + s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0]; + s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1]; + } + s->current_picture.ref_index[0][xy ]= + s->current_picture.ref_index[0][xy + 1]= s->field_select[0][0]; + s->current_picture.ref_index[0][xy + wrap ]= + s->current_picture.ref_index[0][xy + wrap + 1]= s->field_select[0][1]; + } + + /* no update if 8X8 because it has been done during parsing */ + s->current_picture.motion_val[0][xy][0] = motion_x; + s->current_picture.motion_val[0][xy][1] = motion_y; + s->current_picture.motion_val[0][xy + 1][0] = motion_x; + s->current_picture.motion_val[0][xy + 1][1] = motion_y; + s->current_picture.motion_val[0][xy + wrap][0] = motion_x; + s->current_picture.motion_val[0][xy + wrap][1] = motion_y; + s->current_picture.motion_val[0][xy + 1 + wrap][0] = motion_x; + s->current_picture.motion_val[0][xy + 1 + wrap][1] = motion_y; + } + + if(s->encoding){ //FIXME encoding MUST be cleaned up + if (s->mv_type == MV_TYPE_8X8) + s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_8x8; + else if(s->mb_intra) + s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA; + else + s->current_picture.mb_type[mb_xy]= MB_TYPE_L0 | MB_TYPE_16x16; + } +} + +#ifdef CONFIG_ENCODERS + +static inline int h263_get_motion_length(MpegEncContext * s, int val, int f_code){ + int l, bit_size, code; + + if (val == 0) { + return mvtab[0][1]; + } else { + bit_size = f_code - 1; + /* modulo encoding */ + l= INT_BIT - 6 - bit_size; + val = (val<>l; + val--; + code = (val >> bit_size) + 1; + + return mvtab[code][1] + 1 + bit_size; + } +} + +static inline void ff_h263_encode_motion_vector(MpegEncContext * s, int x, int y, int f_code){ + if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ + skip_put_bits(&s->pb, + h263_get_motion_length(s, x, f_code) + +h263_get_motion_length(s, y, f_code)); + }else{ + ff_h263_encode_motion(s, x, f_code); + ff_h263_encode_motion(s, y, f_code); + } +} + +static inline int get_p_cbp(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y){ + int cbp, i; + + if(s->flags & CODEC_FLAG_CBP_RD){ + int best_cbpy_score= INT_MAX; + int best_cbpc_score= INT_MAX; + int cbpc = (-1), cbpy= (-1); + const int offset= (s->mv_type==MV_TYPE_16X16 ? 0 : 16) + (s->dquant ? 8 : 0); + const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6); + + for(i=0; i<4; i++){ + int score= inter_MCBPC_bits[i + offset] * lambda; + if(i&1) score += s->coded_score[5]; + if(i&2) score += s->coded_score[4]; + + if(score < best_cbpc_score){ + best_cbpc_score= score; + cbpc= i; + } + } + + for(i=0; i<16; i++){ + int score= cbpy_tab[i ^ 0xF][1] * lambda; + if(i&1) score += s->coded_score[3]; + if(i&2) score += s->coded_score[2]; + if(i&4) score += s->coded_score[1]; + if(i&8) score += s->coded_score[0]; + + if(score < best_cbpy_score){ + best_cbpy_score= score; + cbpy= i; + } + } + cbp= cbpc + 4*cbpy; + if ((motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16){ + if(best_cbpy_score + best_cbpc_score + 2*lambda >= 0) + cbp= 0; + } + + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i))&1)==0 ){ + s->block_last_index[i]= -1; + memset(s->block[i], 0, sizeof(DCTELEM)*64); + } + } + }else{ + cbp= 0; + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + } + return cbp; +} + +static inline int get_b_cbp(MpegEncContext * s, DCTELEM block[6][64], + int motion_x, int motion_y, int mb_type){ + int cbp=0, i; + + if(s->flags & CODEC_FLAG_CBP_RD){ + int score=0; + const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6); + + for(i=0; i<6; i++){ + if(s->coded_score[i] < 0){ + score += s->coded_score[i]; + cbp |= 1 << (5 - i); + } + } + + if(cbp){ + int zero_score= -6; + if ((motion_x | motion_y | s->dquant | mb_type) == 0){ + zero_score-= 4; //2*MV + mb_type + cbp bit + } + + zero_score*= lambda; + if(zero_score <= score){ + cbp=0; + } + } + + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0 && ((cbp >> (5 - i))&1)==0 ){ + s->block_last_index[i]= -1; + memset(s->block[i], 0, sizeof(DCTELEM)*64); + } + } + }else{ + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + } + return cbp; +} + +static inline void mpeg4_encode_blocks(MpegEncContext * s, DCTELEM block[6][64], int intra_dc[6], + uint8_t **scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb){ + int i; + + if(scan_table){ + if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ + for (i = 0; i < 6; i++) { + skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, intra_dc[i], scan_table[i])); + } + }else{ + /* encode each block */ + for (i = 0; i < 6; i++) { + mpeg4_encode_block(s, block[i], i, intra_dc[i], scan_table[i], dc_pb, ac_pb); + } + } + }else{ + if(s->flags2 & CODEC_FLAG2_NO_OUTPUT){ + for (i = 0; i < 6; i++) { + skip_put_bits(&s->pb, mpeg4_get_block_length(s, block[i], i, 0, s->intra_scantable.permutated)); + } + }else{ + /* encode each block */ + for (i = 0; i < 6; i++) { + mpeg4_encode_block(s, block[i], i, 0, s->intra_scantable.permutated, dc_pb, ac_pb); + } + } + } +} + +void mpeg4_encode_mb(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y) +{ + int cbpc, cbpy, pred_x, pred_y; + PutBitContext * const pb2 = s->data_partitioning ? &s->pb2 : &s->pb; + PutBitContext * const tex_pb = s->data_partitioning && s->pict_type!=B_TYPE ? &s->tex_pb : &s->pb; + PutBitContext * const dc_pb = s->data_partitioning && s->pict_type!=I_TYPE ? &s->pb2 : &s->pb; + const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0; + const int dquant_code[5]= {1,0,9,2,3}; + + // printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); + if (!s->mb_intra) { + int i, cbp; + + if(s->pict_type==B_TYPE){ + static const int mb_type_table[8]= {-1, 2, 3, 1,-1,-1,-1, 0}; /* convert from mv_dir to type */ + int mb_type= mb_type_table[s->mv_dir]; + + if(s->mb_x==0){ + for(i=0; i<2; i++){ + s->last_mv[i][0][0]= + s->last_mv[i][0][1]= + s->last_mv[i][1][0]= + s->last_mv[i][1][1]= 0; + } + } + + assert(s->dquant>=-2 && s->dquant<=2); + assert((s->dquant&1)==0); + assert(mb_type>=0); + + /* nothing to do if this MB was skipped in the next P Frame */ + if(s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]){ //FIXME avoid DCT & ... + s->skip_count++; + s->mv[0][0][0]= + s->mv[0][0][1]= + s->mv[1][0][0]= + s->mv[1][0][1]= 0; + s->mv_dir= MV_DIR_FORWARD; //doesn't matter + s->qscale -= s->dquant; +// s->mb_skipped=1; + + return; + } + + cbp= get_b_cbp(s, block, motion_x, motion_y, mb_type); + + if ((cbp | motion_x | motion_y | mb_type) ==0) { + /* direct MB with MV={0,0} */ + assert(s->dquant==0); + + put_bits(&s->pb, 1, 1); /* mb not coded modb1=1 */ + + if(interleaved_stats){ + s->misc_bits++; + s->last_bits++; + } + s->skip_count++; + return; + } + + put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */ + put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge + put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we don't need it :) + if(cbp) put_bits(&s->pb, 6, cbp); + + if(cbp && mb_type){ + if(s->dquant) + put_bits(&s->pb, 2, (s->dquant>>2)+3); + else + put_bits(&s->pb, 1, 0); + }else + s->qscale -= s->dquant; + + if(!s->progressive_sequence){ + if(cbp) + put_bits(&s->pb, 1, s->interlaced_dct); + if(mb_type) // not direct mode + put_bits(&s->pb, 1, s->mv_type == MV_TYPE_FIELD); + } + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + + if(mb_type == 0){ + assert(s->mv_dir & MV_DIRECT); + ff_h263_encode_motion_vector(s, motion_x, motion_y, 1); + s->b_count++; + s->f_count++; + }else{ + assert(mb_type > 0 && mb_type < 4); + if(s->mv_type != MV_TYPE_FIELD){ + if(s->mv_dir & MV_DIR_FORWARD){ + ff_h263_encode_motion_vector(s, s->mv[0][0][0] - s->last_mv[0][0][0], + s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); + s->last_mv[0][0][0]= s->last_mv[0][1][0]= s->mv[0][0][0]; + s->last_mv[0][0][1]= s->last_mv[0][1][1]= s->mv[0][0][1]; + s->f_count++; + } + if(s->mv_dir & MV_DIR_BACKWARD){ + ff_h263_encode_motion_vector(s, s->mv[1][0][0] - s->last_mv[1][0][0], + s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); + s->last_mv[1][0][0]= s->last_mv[1][1][0]= s->mv[1][0][0]; + s->last_mv[1][0][1]= s->last_mv[1][1][1]= s->mv[1][0][1]; + s->b_count++; + } + }else{ + if(s->mv_dir & MV_DIR_FORWARD){ + put_bits(&s->pb, 1, s->field_select[0][0]); + put_bits(&s->pb, 1, s->field_select[0][1]); + } + if(s->mv_dir & MV_DIR_BACKWARD){ + put_bits(&s->pb, 1, s->field_select[1][0]); + put_bits(&s->pb, 1, s->field_select[1][1]); + } + if(s->mv_dir & MV_DIR_FORWARD){ + for(i=0; i<2; i++){ + ff_h263_encode_motion_vector(s, s->mv[0][i][0] - s->last_mv[0][i][0] , + s->mv[0][i][1] - s->last_mv[0][i][1]/2, s->f_code); + s->last_mv[0][i][0]= s->mv[0][i][0]; + s->last_mv[0][i][1]= s->mv[0][i][1]*2; + } + s->f_count++; + } + if(s->mv_dir & MV_DIR_BACKWARD){ + for(i=0; i<2; i++){ + ff_h263_encode_motion_vector(s, s->mv[1][i][0] - s->last_mv[1][i][0] , + s->mv[1][i][1] - s->last_mv[1][i][1]/2, s->b_code); + s->last_mv[1][i][0]= s->mv[1][i][0]; + s->last_mv[1][i][1]= s->mv[1][i][1]*2; + } + s->b_count++; + } + } + } + + if(interleaved_stats){ + s->mv_bits+= get_bits_diff(s); + } + + mpeg4_encode_blocks(s, block, NULL, NULL, NULL, &s->pb); + + if(interleaved_stats){ + s->p_tex_bits+= get_bits_diff(s); + } + + }else{ /* s->pict_type==B_TYPE */ + cbp= get_p_cbp(s, block, motion_x, motion_y); + + if ((cbp | motion_x | motion_y | s->dquant) == 0 && s->mv_type==MV_TYPE_16X16) { + /* check if the B frames can skip it too, as we must skip it if we skip here + why didn't they just compress the skip-mb bits instead of reusing them ?! */ + if(s->max_b_frames>0){ + int i; + int x,y, offset; + uint8_t *p_pic; + + x= s->mb_x*16; + y= s->mb_y*16; + if(x+16 > s->width) x= s->width-16; + if(y+16 > s->height) y= s->height-16; + + offset= x + y*s->linesize; + p_pic= s->new_picture.data[0] + offset; + + s->mb_skipped=1; + for(i=0; imax_b_frames; i++){ + uint8_t *b_pic; + int diff; + Picture *pic= s->reordered_input_picture[i+1]; + + if(pic==NULL || pic->pict_type!=B_TYPE) break; + + b_pic= pic->data[0] + offset; + if(pic->type != FF_BUFFER_TYPE_SHARED) + b_pic+= INPLACE_OFFSET; + diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); + if(diff>s->qscale*70){ //FIXME check that 70 is optimal + s->mb_skipped=0; + break; + } + } + }else + s->mb_skipped=1; + + if(s->mb_skipped==1){ + /* skip macroblock */ + put_bits(&s->pb, 1, 1); + + if(interleaved_stats){ + s->misc_bits++; + s->last_bits++; + } + s->skip_count++; + + return; + } + } + + put_bits(&s->pb, 1, 0); /* mb coded */ + cbpc = cbp & 3; + cbpy = cbp >> 2; + cbpy ^= 0xf; + if(s->mv_type==MV_TYPE_16X16){ + if(s->dquant) cbpc+= 8; + put_bits(&s->pb, + inter_MCBPC_bits[cbpc], + inter_MCBPC_code[cbpc]); + + put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); + if(s->dquant) + put_bits(pb2, 2, dquant_code[s->dquant+2]); + + if(!s->progressive_sequence){ + if(cbp) + put_bits(pb2, 1, s->interlaced_dct); + put_bits(pb2, 1, 0); + } + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + + /* motion vectors: 16x16 mode */ + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + + ff_h263_encode_motion_vector(s, motion_x - pred_x, + motion_y - pred_y, s->f_code); + }else if(s->mv_type==MV_TYPE_FIELD){ + if(s->dquant) cbpc+= 8; + put_bits(&s->pb, + inter_MCBPC_bits[cbpc], + inter_MCBPC_code[cbpc]); + + put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); + if(s->dquant) + put_bits(pb2, 2, dquant_code[s->dquant+2]); + + assert(!s->progressive_sequence); + if(cbp) + put_bits(pb2, 1, s->interlaced_dct); + put_bits(pb2, 1, 1); + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + + /* motion vectors: 16x8 interlaced mode */ + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + pred_y /=2; + + put_bits(&s->pb, 1, s->field_select[0][0]); + put_bits(&s->pb, 1, s->field_select[0][1]); + + ff_h263_encode_motion_vector(s, s->mv[0][0][0] - pred_x, + s->mv[0][0][1] - pred_y, s->f_code); + ff_h263_encode_motion_vector(s, s->mv[0][1][0] - pred_x, + s->mv[0][1][1] - pred_y, s->f_code); + }else{ + assert(s->mv_type==MV_TYPE_8X8); + put_bits(&s->pb, + inter_MCBPC_bits[cbpc+16], + inter_MCBPC_code[cbpc+16]); + put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); + + if(!s->progressive_sequence){ + if(cbp) + put_bits(pb2, 1, s->interlaced_dct); + } + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + + for(i=0; i<4; i++){ + /* motion vectors: 8x8 mode*/ + h263_pred_motion(s, i, 0, &pred_x, &pred_y); + + ff_h263_encode_motion_vector(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, + s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); + } + } + + if(interleaved_stats){ + s->mv_bits+= get_bits_diff(s); + } + + mpeg4_encode_blocks(s, block, NULL, NULL, NULL, tex_pb); + + if(interleaved_stats){ + s->p_tex_bits+= get_bits_diff(s); + } + s->f_count++; + } + } else { + int cbp; + int dc_diff[6]; //dc values with the dc prediction subtracted + int dir[6]; //prediction direction + int zigzag_last_index[6]; + uint8_t *scan_table[6]; + int i; + + for(i=0; i<6; i++){ + dc_diff[i]= ff_mpeg4_pred_dc(s, i, block[i][0], &dir[i], 1); + } + + if(s->flags & CODEC_FLAG_AC_PRED){ + s->ac_pred= decide_ac_pred(s, block, dir, scan_table, zigzag_last_index); + if(!s->ac_pred) + restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index); + }else{ + for(i=0; i<6; i++) + scan_table[i]= s->intra_scantable.permutated; + } + + /* compute cbp */ + cbp = 0; + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 1) + cbp |= 1 << (5 - i); + } + + cbpc = cbp & 3; + if (s->pict_type == I_TYPE) { + if(s->dquant) cbpc+=4; + put_bits(&s->pb, + intra_MCBPC_bits[cbpc], + intra_MCBPC_code[cbpc]); + } else { + if(s->dquant) cbpc+=8; + put_bits(&s->pb, 1, 0); /* mb coded */ + put_bits(&s->pb, + inter_MCBPC_bits[cbpc + 4], + inter_MCBPC_code[cbpc + 4]); + } + put_bits(pb2, 1, s->ac_pred); + cbpy = cbp >> 2; + put_bits(pb2, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); + if(s->dquant) + put_bits(dc_pb, 2, dquant_code[s->dquant+2]); + + if(!s->progressive_sequence){ + put_bits(dc_pb, 1, s->interlaced_dct); + } + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + + mpeg4_encode_blocks(s, block, dc_diff, scan_table, dc_pb, tex_pb); + + if(interleaved_stats){ + s->i_tex_bits+= get_bits_diff(s); + } + s->i_count++; + + /* restore ac coeffs & last_index stuff if we messed them up with the prediction */ + if(s->ac_pred) + restore_ac_coeffs(s, block, dir, scan_table, zigzag_last_index); + } +} + +void h263_encode_mb(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y) +{ + int cbpc, cbpy, i, cbp, pred_x, pred_y; + int16_t pred_dc; + int16_t rec_intradc[6]; + uint16_t *dc_ptr[6]; + const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1); + const int dquant_code[5]= {1,0,9,2,3}; + + //printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); + if (!s->mb_intra) { + /* compute cbp */ + cbp= get_p_cbp(s, block, motion_x, motion_y); + + if ((cbp | motion_x | motion_y | s->dquant | (s->mv_type - MV_TYPE_16X16)) == 0) { + /* skip macroblock */ + put_bits(&s->pb, 1, 1); + if(interleaved_stats){ + s->misc_bits++; + s->last_bits++; + } + s->skip_count++; + + return; + } + put_bits(&s->pb, 1, 0); /* mb coded */ + + cbpc = cbp & 3; + cbpy = cbp >> 2; + if(s->alt_inter_vlc==0 || cbpc!=3) + cbpy ^= 0xF; + if(s->dquant) cbpc+= 8; + if(s->mv_type==MV_TYPE_16X16){ + put_bits(&s->pb, + inter_MCBPC_bits[cbpc], + inter_MCBPC_code[cbpc]); + + put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); + if(s->dquant) + put_bits(&s->pb, 2, dquant_code[s->dquant+2]); + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + + /* motion vectors: 16x16 mode */ + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + + if (!s->umvplus) { + ff_h263_encode_motion_vector(s, motion_x - pred_x, + motion_y - pred_y, 1); + } + else { + h263p_encode_umotion(s, motion_x - pred_x); + h263p_encode_umotion(s, motion_y - pred_y); + if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) + /* To prevent Start Code emulation */ + put_bits(&s->pb,1,1); + } + }else{ + put_bits(&s->pb, + inter_MCBPC_bits[cbpc+16], + inter_MCBPC_code[cbpc+16]); + put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); + if(s->dquant) + put_bits(&s->pb, 2, dquant_code[s->dquant+2]); + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + + for(i=0; i<4; i++){ + /* motion vectors: 8x8 mode*/ + h263_pred_motion(s, i, 0, &pred_x, &pred_y); + + motion_x= s->current_picture.motion_val[0][ s->block_index[i] ][0]; + motion_y= s->current_picture.motion_val[0][ s->block_index[i] ][1]; + if (!s->umvplus) { + ff_h263_encode_motion_vector(s, motion_x - pred_x, + motion_y - pred_y, 1); + } + else { + h263p_encode_umotion(s, motion_x - pred_x); + h263p_encode_umotion(s, motion_y - pred_y); + if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) + /* To prevent Start Code emulation */ + put_bits(&s->pb,1,1); + } + } + } + + if(interleaved_stats){ + s->mv_bits+= get_bits_diff(s); + } + } else { + assert(s->mb_intra); + + cbp = 0; + if (s->h263_aic) { + /* Predict DC */ + for(i=0; i<6; i++) { + int16_t level = block[i][0]; + int scale; + + if(i<4) scale= s->y_dc_scale; + else scale= s->c_dc_scale; + + pred_dc = h263_pred_dc(s, i, &dc_ptr[i]); + level -= pred_dc; + /* Quant */ + if (level >= 0) + level = (level + (scale>>1))/scale; + else + level = (level - (scale>>1))/scale; + + /* AIC can change CBP */ + if (level == 0 && s->block_last_index[i] == 0) + s->block_last_index[i] = -1; + + if(!s->modified_quant){ + if (level < -127) + level = -127; + else if (level > 127) + level = 127; + } + + block[i][0] = level; + /* Reconstruction */ + rec_intradc[i] = scale*level + pred_dc; + /* Oddify */ + rec_intradc[i] |= 1; + //if ((rec_intradc[i] % 2) == 0) + // rec_intradc[i]++; + /* Clipping */ + if (rec_intradc[i] < 0) + rec_intradc[i] = 0; + else if (rec_intradc[i] > 2047) + rec_intradc[i] = 2047; + + /* Update AC/DC tables */ + *dc_ptr[i] = rec_intradc[i]; + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + }else{ + for(i=0; i<6; i++) { + /* compute cbp */ + if (s->block_last_index[i] >= 1) + cbp |= 1 << (5 - i); + } + } + + cbpc = cbp & 3; + if (s->pict_type == I_TYPE) { + if(s->dquant) cbpc+=4; + put_bits(&s->pb, + intra_MCBPC_bits[cbpc], + intra_MCBPC_code[cbpc]); + } else { + if(s->dquant) cbpc+=8; + put_bits(&s->pb, 1, 0); /* mb coded */ + put_bits(&s->pb, + inter_MCBPC_bits[cbpc + 4], + inter_MCBPC_code[cbpc + 4]); + } + if (s->h263_aic) { + /* XXX: currently, we do not try to use ac prediction */ + put_bits(&s->pb, 1, 0); /* no AC prediction */ + } + cbpy = cbp >> 2; + put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); + if(s->dquant) + put_bits(&s->pb, 2, dquant_code[s->dquant+2]); + + if(interleaved_stats){ + s->misc_bits+= get_bits_diff(s); + } + } + + for(i=0; i<6; i++) { + /* encode each block */ + h263_encode_block(s, block[i], i); + + /* Update INTRADC for decoding */ + if (s->h263_aic && s->mb_intra) { + block[i][0] = rec_intradc[i]; + + } + } + + if(interleaved_stats){ + if (!s->mb_intra) { + s->p_tex_bits+= get_bits_diff(s); + s->f_count++; + }else{ + s->i_tex_bits+= get_bits_diff(s); + s->i_count++; + } + } +} +#endif + +void ff_h263_loop_filter(MpegEncContext * s){ + int qp_c; + const int linesize = s->linesize; + const int uvlinesize= s->uvlinesize; + const int xy = s->mb_y * s->mb_stride + s->mb_x; + uint8_t *dest_y = s->dest[0]; + uint8_t *dest_cb= s->dest[1]; + uint8_t *dest_cr= s->dest[2]; + +// if(s->pict_type==B_TYPE && !s->readable) return; + + /* + Diag Top + Left Center + */ + if(!IS_SKIP(s->current_picture.mb_type[xy])){ + qp_c= s->qscale; + s->dsp.h263_v_loop_filter(dest_y+8*linesize , linesize, qp_c); + s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c); + }else + qp_c= 0; + + if(s->mb_y){ + int qp_dt, qp_t, qp_tc; + + if(IS_SKIP(s->current_picture.mb_type[xy-s->mb_stride])) + qp_t=0; + else + qp_t= s->current_picture.qscale_table[xy-s->mb_stride]; + + if(qp_c) + qp_tc= qp_c; + else + qp_tc= qp_t; + + if(qp_tc){ + const int chroma_qp= s->chroma_qscale_table[qp_tc]; + s->dsp.h263_v_loop_filter(dest_y , linesize, qp_tc); + s->dsp.h263_v_loop_filter(dest_y+8, linesize, qp_tc); + + s->dsp.h263_v_loop_filter(dest_cb , uvlinesize, chroma_qp); + s->dsp.h263_v_loop_filter(dest_cr , uvlinesize, chroma_qp); + } + + if(qp_t) + s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_t); + + if(s->mb_x){ + if(qp_t || IS_SKIP(s->current_picture.mb_type[xy-1-s->mb_stride])) + qp_dt= qp_t; + else + qp_dt= s->current_picture.qscale_table[xy-1-s->mb_stride]; + + if(qp_dt){ + const int chroma_qp= s->chroma_qscale_table[qp_dt]; + s->dsp.h263_h_loop_filter(dest_y -8*linesize , linesize, qp_dt); + s->dsp.h263_h_loop_filter(dest_cb-8*uvlinesize, uvlinesize, chroma_qp); + s->dsp.h263_h_loop_filter(dest_cr-8*uvlinesize, uvlinesize, chroma_qp); + } + } + } + + if(qp_c){ + s->dsp.h263_h_loop_filter(dest_y +8, linesize, qp_c); + if(s->mb_y + 1 == s->mb_height) + s->dsp.h263_h_loop_filter(dest_y+8*linesize+8, linesize, qp_c); + } + + if(s->mb_x){ + int qp_lc; + if(qp_c || IS_SKIP(s->current_picture.mb_type[xy-1])) + qp_lc= qp_c; + else + qp_lc= s->current_picture.qscale_table[xy-1]; + + if(qp_lc){ + s->dsp.h263_h_loop_filter(dest_y, linesize, qp_lc); + if(s->mb_y + 1 == s->mb_height){ + const int chroma_qp= s->chroma_qscale_table[qp_lc]; + s->dsp.h263_h_loop_filter(dest_y +8* linesize, linesize, qp_lc); + s->dsp.h263_h_loop_filter(dest_cb , uvlinesize, chroma_qp); + s->dsp.h263_h_loop_filter(dest_cr , uvlinesize, chroma_qp); + } + } + } +} + +static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr) +{ + int x, y, wrap, a, c, pred_dc, scale; + int16_t *dc_val; + + /* find prediction */ + if (n < 4) { + x = 2 * s->mb_x + (n & 1); + y = 2 * s->mb_y + ((n & 2) >> 1); + wrap = s->b8_stride; + dc_val = s->dc_val[0]; + scale = s->y_dc_scale; + } else { + x = s->mb_x; + y = s->mb_y; + wrap = s->mb_stride; + dc_val = s->dc_val[n - 4 + 1]; + scale = s->c_dc_scale; + } + /* B C + * A X + */ + a = dc_val[(x - 1) + (y) * wrap]; + c = dc_val[(x) + (y - 1) * wrap]; + + /* No prediction outside GOB boundary */ + if(s->first_slice_line && n!=3){ + if(n!=2) c= 1024; + if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024; + } + pred_dc = 1024; + /* just DC prediction */ + if (a != 1024 && c != 1024) + pred_dc = (a + c) >> 1; + else if (a != 1024) + pred_dc = a; + else + pred_dc = c; + + /* we assume pred is positive */ + //pred_dc = (pred_dc + (scale >> 1)) / scale; + *dc_val_ptr = &dc_val[x + y * wrap]; + return pred_dc; +} + +static void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) +{ + int x, y, wrap, a, c, pred_dc, scale, i; + int16_t *dc_val, *ac_val, *ac_val1; + + /* find prediction */ + if (n < 4) { + x = 2 * s->mb_x + (n & 1); + y = 2 * s->mb_y + (n>> 1); + wrap = s->b8_stride; + dc_val = s->dc_val[0]; + ac_val = s->ac_val[0][0]; + scale = s->y_dc_scale; + } else { + x = s->mb_x; + y = s->mb_y; + wrap = s->mb_stride; + dc_val = s->dc_val[n - 4 + 1]; + ac_val = s->ac_val[n - 4 + 1][0]; + scale = s->c_dc_scale; + } + + ac_val += ((y) * wrap + (x)) * 16; + ac_val1 = ac_val; + + /* B C + * A X + */ + a = dc_val[(x - 1) + (y) * wrap]; + c = dc_val[(x) + (y - 1) * wrap]; + + /* No prediction outside GOB boundary */ + if(s->first_slice_line && n!=3){ + if(n!=2) c= 1024; + if(n!=1 && s->mb_x == s->resync_mb_x) a= 1024; + } + + if (s->ac_pred) { + pred_dc = 1024; + if (s->h263_aic_dir) { + /* left prediction */ + if (a != 1024) { + ac_val -= 16; + for(i=1;i<8;i++) { + block[s->dsp.idct_permutation[i<<3]] += ac_val[i]; + } + pred_dc = a; + } + } else { + /* top prediction */ + if (c != 1024) { + ac_val -= 16 * wrap; + for(i=1;i<8;i++) { + block[s->dsp.idct_permutation[i ]] += ac_val[i + 8]; + } + pred_dc = c; + } + } + } else { + /* just DC prediction */ + if (a != 1024 && c != 1024) + pred_dc = (a + c) >> 1; + else if (a != 1024) + pred_dc = a; + else + pred_dc = c; + } + + /* we assume pred is positive */ + block[0]=block[0]*scale + pred_dc; + + if (block[0] < 0) + block[0] = 0; + else + block[0] |= 1; + + /* Update AC/DC tables */ + dc_val[(x) + (y) * wrap] = block[0]; + + /* left copy */ + for(i=1;i<8;i++) + ac_val1[i ] = block[s->dsp.idct_permutation[i<<3]]; + /* top copy */ + for(i=1;i<8;i++) + ac_val1[8 + i] = block[s->dsp.idct_permutation[i ]]; +} + +int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir, + int *px, int *py) +{ + int wrap; + int16_t *A, *B, *C, (*mot_val)[2]; + static const int off[4]= {2, 1, 1, -1}; + + wrap = s->b8_stride; + mot_val = s->current_picture.motion_val[dir] + s->block_index[block]; + + A = mot_val[ - 1]; + /* special case for first (slice) line */ + if (s->first_slice_line && block<3) { + // we can't just change some MVs to simulate that as we need them for the B frames (and ME) + // and if we ever support non rectangular objects than we need to do a few ifs here anyway :( + if(block==0){ //most common case + if(s->mb_x == s->resync_mb_x){ //rare + *px= *py = 0; + }else if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare + C = mot_val[off[block] - wrap]; + if(s->mb_x==0){ + *px = C[0]; + *py = C[1]; + }else{ + *px = mid_pred(A[0], 0, C[0]); + *py = mid_pred(A[1], 0, C[1]); + } + }else{ + *px = A[0]; + *py = A[1]; + } + }else if(block==1){ + if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare + C = mot_val[off[block] - wrap]; + *px = mid_pred(A[0], 0, C[0]); + *py = mid_pred(A[1], 0, C[1]); + }else{ + *px = A[0]; + *py = A[1]; + } + }else{ /* block==2*/ + B = mot_val[ - wrap]; + C = mot_val[off[block] - wrap]; + if(s->mb_x == s->resync_mb_x) //rare + A[0]=A[1]=0; + + *px = mid_pred(A[0], B[0], C[0]); + *py = mid_pred(A[1], B[1], C[1]); + } + } else { + B = mot_val[ - wrap]; + C = mot_val[off[block] - wrap]; + *px = mid_pred(A[0], B[0], C[0]); + *py = mid_pred(A[1], B[1], C[1]); + } + return *mot_val; +} + +#ifdef CONFIG_ENCODERS +void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code) +{ + int range, l, bit_size, sign, code, bits; + + if (val == 0) { + /* zero vector */ + code = 0; + put_bits(&s->pb, mvtab[code][1], mvtab[code][0]); + } else { + bit_size = f_code - 1; + range = 1 << bit_size; + /* modulo encoding */ + l= INT_BIT - 6 - bit_size; + val = (val<>l; + sign = val>>31; + val= (val^sign)-sign; + sign&=1; + + val--; + code = (val >> bit_size) + 1; + bits = val & (range - 1); + + put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); + if (bit_size > 0) { + put_bits(&s->pb, bit_size, bits); + } + } +} + +/* Encode MV differences on H.263+ with Unrestricted MV mode */ +static void h263p_encode_umotion(MpegEncContext * s, int val) +{ + short sval = 0; + short i = 0; + short n_bits = 0; + short temp_val; + int code = 0; + int tcode; + + if ( val == 0) + put_bits(&s->pb, 1, 1); + else if (val == 1) + put_bits(&s->pb, 3, 0); + else if (val == -1) + put_bits(&s->pb, 3, 2); + else { + + sval = ((val < 0) ? (short)(-val):(short)val); + temp_val = sval; + + while (temp_val != 0) { + temp_val = temp_val >> 1; + n_bits++; + } + + i = n_bits - 1; + while (i > 0) { + tcode = (sval & (1 << (i-1))) >> (i-1); + tcode = (tcode << 1) | 1; + code = (code << 2) | tcode; + i--; + } + code = ((code << 1) | (val < 0)) << 1; + put_bits(&s->pb, (2*n_bits)+1, code); + //printf("\nVal = %d\tCode = %d", sval, code); + } +} + +static void init_mv_penalty_and_fcode(MpegEncContext *s) +{ + int f_code; + int mv; + + if(mv_penalty==NULL) + mv_penalty= av_mallocz( sizeof(uint8_t)*(MAX_FCODE+1)*(2*MAX_MV+1) ); + + for(f_code=1; f_code<=MAX_FCODE; f_code++){ + for(mv=-MAX_MV; mv<=MAX_MV; mv++){ + int len; + + if(mv==0) len= mvtab[0][1]; + else{ + int val, bit_size, range, code; + + bit_size = f_code - 1; + range = 1 << bit_size; + + val=mv; + if (val < 0) + val = -val; + val--; + code = (val >> bit_size) + 1; + if(code<33){ + len= mvtab[code][1] + 1 + bit_size; + }else{ + len= mvtab[32][1] + av_log2(code>>5) + 2 + bit_size; + } + } + + mv_penalty[f_code][mv+MAX_MV]= len; + } + } + + for(f_code=MAX_FCODE; f_code>0; f_code--){ + for(mv=-(16<>= 1; + size++; + } + + if (level < 0) + l= (-level) ^ ((1 << size) - 1); + else + l= level; + + /* luminance */ + uni_code= DCtab_lum[size][0]; + uni_len = DCtab_lum[size][1]; + + if (size > 0) { + uni_code<<=size; uni_code|=l; + uni_len+=size; + if (size > 8){ + uni_code<<=1; uni_code|=1; + uni_len++; + } + } + uni_DCtab_lum_bits[level+256]= uni_code; + uni_DCtab_lum_len [level+256]= uni_len; + + /* chrominance */ + uni_code= DCtab_chrom[size][0]; + uni_len = DCtab_chrom[size][1]; + + if (size > 0) { + uni_code<<=size; uni_code|=l; + uni_len+=size; + if (size > 8){ + uni_code<<=1; uni_code|=1; + uni_len++; + } + } + uni_DCtab_chrom_bits[level+256]= uni_code; + uni_DCtab_chrom_len [level+256]= uni_len; + + } +} + +#endif //CONFIG_ENCODERS + +#ifdef CONFIG_ENCODERS +static void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){ + int slevel, run, last; + + assert(MAX_LEVEL >= 64); + assert(MAX_RUN >= 63); + + for(slevel=-64; slevel<64; slevel++){ + if(slevel==0) continue; + for(run=0; run<64; run++){ + for(last=0; last<=1; last++){ + const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64); + int level= slevel < 0 ? -slevel : slevel; + int sign= slevel < 0 ? 1 : 0; + int bits, len, code; + int level1, run1; + + len_tab[index]= 100; + + /* ESC0 */ + code= get_rl_index(rl, last, run, level); + bits= rl->table_vlc[code][0]; + len= rl->table_vlc[code][1]; + bits=bits*2+sign; len++; + + if(code!=rl->n && len < len_tab[index]){ + bits_tab[index]= bits; + len_tab [index]= len; + } +#if 1 + /* ESC1 */ + bits= rl->table_vlc[rl->n][0]; + len= rl->table_vlc[rl->n][1]; + bits=bits*2; len++; //esc1 + level1= level - rl->max_level[last][run]; + if(level1>0){ + code= get_rl_index(rl, last, run, level1); + bits<<= rl->table_vlc[code][1]; + len += rl->table_vlc[code][1]; + bits += rl->table_vlc[code][0]; + bits=bits*2+sign; len++; + + if(code!=rl->n && len < len_tab[index]){ + bits_tab[index]= bits; + len_tab [index]= len; + } + } +#endif +#if 1 + /* ESC2 */ + bits= rl->table_vlc[rl->n][0]; + len= rl->table_vlc[rl->n][1]; + bits=bits*4+2; len+=2; //esc2 + run1 = run - rl->max_run[last][level] - 1; + if(run1>=0){ + code= get_rl_index(rl, last, run1, level); + bits<<= rl->table_vlc[code][1]; + len += rl->table_vlc[code][1]; + bits += rl->table_vlc[code][0]; + bits=bits*2+sign; len++; + + if(code!=rl->n && len < len_tab[index]){ + bits_tab[index]= bits; + len_tab [index]= len; + } + } +#endif + /* ESC3 */ + bits= rl->table_vlc[rl->n][0]; + len = rl->table_vlc[rl->n][1]; + bits=bits*4+3; len+=2; //esc3 + bits=bits*2+last; len++; + bits=bits*64+run; len+=6; + bits=bits*2+1; len++; //marker + bits=bits*4096+(slevel&0xfff); len+=12; + bits=bits*2+1; len++; //marker + + if(len < len_tab[index]){ + bits_tab[index]= bits; + len_tab [index]= len; + } + } + } + } +} + +static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){ + int slevel, run, last; + + assert(MAX_LEVEL >= 64); + assert(MAX_RUN >= 63); + + for(slevel=-64; slevel<64; slevel++){ + if(slevel==0) continue; + for(run=0; run<64; run++){ + for(last=0; last<=1; last++){ + const int index= UNI_MPEG4_ENC_INDEX(last, run, slevel+64); + int level= slevel < 0 ? -slevel : slevel; + int sign= slevel < 0 ? 1 : 0; + int bits, len, code; + + len_tab[index]= 100; + + /* ESC0 */ + code= get_rl_index(rl, last, run, level); + bits= rl->table_vlc[code][0]; + len= rl->table_vlc[code][1]; + bits=bits*2+sign; len++; + + if(code!=rl->n && len < len_tab[index]){ + if(bits_tab) bits_tab[index]= bits; + len_tab [index]= len; + } + /* ESC */ + bits= rl->table_vlc[rl->n][0]; + len = rl->table_vlc[rl->n][1]; + bits=bits*2+last; len++; + bits=bits*64+run; len+=6; + bits=bits*256+(level&0xff); len+=8; + + if(len < len_tab[index]){ + if(bits_tab) bits_tab[index]= bits; + len_tab [index]= len; + } + } + } + } +} + +void h263_encode_init(MpegEncContext *s) +{ + static int done = 0; + + if (!done) { + done = 1; + + init_uni_dc_tab(); + + init_rl(&rl_inter, 1); + init_rl(&rl_intra, 1); + init_rl(&rl_intra_aic, 1); + + init_uni_mpeg4_rl_tab(&rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len); + init_uni_mpeg4_rl_tab(&rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len); + + init_uni_h263_rl_tab(&rl_intra_aic, NULL, uni_h263_intra_aic_rl_len); + init_uni_h263_rl_tab(&rl_inter , NULL, uni_h263_inter_rl_len); + + init_mv_penalty_and_fcode(s); + } + s->me.mv_penalty= mv_penalty; //FIXME exact table for msmpeg4 & h263p + + s->intra_ac_vlc_length =s->inter_ac_vlc_length = uni_h263_inter_rl_len; + s->intra_ac_vlc_last_length=s->inter_ac_vlc_last_length= uni_h263_inter_rl_len + 128*64; + if(s->h263_aic){ + s->intra_ac_vlc_length = uni_h263_intra_aic_rl_len; + s->intra_ac_vlc_last_length= uni_h263_intra_aic_rl_len + 128*64; + } + s->ac_esc_length= 7+1+6+8; + + // use fcodes >1 only for mpeg4 & h263 & h263p FIXME + switch(s->codec_id){ + case CODEC_ID_MPEG4: + s->fcode_tab= fcode_tab; + s->min_qcoeff= -2048; + s->max_qcoeff= 2047; + s->intra_ac_vlc_length = uni_mpeg4_intra_rl_len; + s->intra_ac_vlc_last_length= uni_mpeg4_intra_rl_len + 128*64; + s->inter_ac_vlc_length = uni_mpeg4_inter_rl_len; + s->inter_ac_vlc_last_length= uni_mpeg4_inter_rl_len + 128*64; + s->luma_dc_vlc_length= uni_DCtab_lum_len; + s->chroma_dc_vlc_length= uni_DCtab_chrom_len; + s->ac_esc_length= 7+2+1+6+1+12+1; + s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; + s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; + + if(s->flags & CODEC_FLAG_GLOBAL_HEADER){ + + s->avctx->extradata= av_malloc(1024); + init_put_bits(&s->pb, s->avctx->extradata, 1024); + + if(!(s->workaround_bugs & FF_BUG_MS)) + mpeg4_encode_visual_object_header(s); + mpeg4_encode_vol_header(s, 0, 0); + +// ff_mpeg4_stuffing(&s->pb); ? + flush_put_bits(&s->pb); + s->avctx->extradata_size= (put_bits_count(&s->pb)+7)>>3; + } + + break; + case CODEC_ID_H263P: + if(s->umvplus) + s->fcode_tab= umv_fcode_tab; + if(s->modified_quant){ + s->min_qcoeff= -2047; + s->max_qcoeff= 2047; + }else{ + s->min_qcoeff= -127; + s->max_qcoeff= 127; + } + break; + //Note for mpeg4 & h263 the dc-scale table will be set per frame as needed later + case CODEC_ID_FLV1: + if (s->h263_flv > 1) { + s->min_qcoeff= -1023; + s->max_qcoeff= 1023; + } else { + s->min_qcoeff= -127; + s->max_qcoeff= 127; + } + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + break; + default: //nothing needed - default table already set in mpegvideo.c + s->min_qcoeff= -127; + s->max_qcoeff= 127; + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + } +} + +/** + * encodes a 8x8 block. + * @param block the 8x8 block + * @param n block index (0-3 are luma, 4-5 are chroma) + */ +static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) +{ + int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code; + RLTable *rl; + + rl = &rl_inter; + if (s->mb_intra && !s->h263_aic) { + /* DC coef */ + level = block[0]; + /* 255 cannot be represented, so we clamp */ + if (level > 254) { + level = 254; + block[0] = 254; + } + /* 0 cannot be represented also */ + else if (level < 1) { + level = 1; + block[0] = 1; + } + if (level == 128) //FIXME check rv10 + put_bits(&s->pb, 8, 0xff); + else + put_bits(&s->pb, 8, level); + i = 1; + } else { + i = 0; + if (s->h263_aic && s->mb_intra) + rl = &rl_intra_aic; + + if(s->alt_inter_vlc && !s->mb_intra){ + int aic_vlc_bits=0; + int inter_vlc_bits=0; + int wrong_pos=-1; + int aic_code; + + last_index = s->block_last_index[n]; + last_non_zero = i - 1; + for (; i <= last_index; i++) { + j = s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + run = i - last_non_zero - 1; + last = (i == last_index); + + if(level<0) level= -level; + + code = get_rl_index(rl, last, run, level); + aic_code = get_rl_index(&rl_intra_aic, last, run, level); + inter_vlc_bits += rl->table_vlc[code][1]+1; + aic_vlc_bits += rl_intra_aic.table_vlc[aic_code][1]+1; + + if (code == rl->n) { + inter_vlc_bits += 1+6+8-1; + } + if (aic_code == rl_intra_aic.n) { + aic_vlc_bits += 1+6+8-1; + wrong_pos += run + 1; + }else + wrong_pos += wrong_run[aic_code]; + last_non_zero = i; + } + } + i = 0; + if(aic_vlc_bits < inter_vlc_bits && wrong_pos > 63) + rl = &rl_intra_aic; + } + } + + /* AC coefs */ + last_index = s->block_last_index[n]; + last_non_zero = i - 1; + for (; i <= last_index; i++) { + j = s->intra_scantable.permutated[i]; + level = block[j]; + if (level) { + run = i - last_non_zero - 1; + last = (i == last_index); + sign = 0; + slevel = level; + if (level < 0) { + sign = 1; + level = -level; + } + code = get_rl_index(rl, last, run, level); + put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + if (code == rl->n) { + if(s->h263_flv <= 1){ + put_bits(&s->pb, 1, last); + put_bits(&s->pb, 6, run); + + assert(slevel != 0); + + if(level < 128) + put_bits(&s->pb, 8, slevel & 0xff); + else{ + put_bits(&s->pb, 8, 128); + put_bits(&s->pb, 5, slevel & 0x1f); + put_bits(&s->pb, 6, (slevel>>5)&0x3f); + } + }else{ + if(level < 64) { // 7-bit level + put_bits(&s->pb, 1, 0); + put_bits(&s->pb, 1, last); + put_bits(&s->pb, 6, run); + + put_bits(&s->pb, 7, slevel & 0x7f); + } else { + /* 11-bit level */ + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 1, last); + put_bits(&s->pb, 6, run); + + put_bits(&s->pb, 11, slevel & 0x7ff); + } + } + } else { + put_bits(&s->pb, 1, sign); + } + last_non_zero = i; + } + } +} +#endif + +#ifdef CONFIG_ENCODERS + +/***************************************************/ +/** + * add mpeg4 stuffing bits (01...1) + */ +void ff_mpeg4_stuffing(PutBitContext * pbc) +{ + int length; + put_bits(pbc, 1, 0); + length= (-put_bits_count(pbc))&7; + if(length) put_bits(pbc, length, (1<current_picture_ptr->pts != AV_NOPTS_VALUE); + s->time= s->current_picture_ptr->pts*s->avctx->time_base.num; + + time_div= s->time/s->avctx->time_base.den; + time_mod= s->time%s->avctx->time_base.den; + + if(s->pict_type==B_TYPE){ + s->pb_time= s->pp_time - (s->last_non_b_time - s->time); + assert(s->pb_time > 0 && s->pb_time < s->pp_time); + ff_mpeg4_init_direct_mv(s); + }else{ + s->last_time_base= s->time_base; + s->time_base= time_div; + s->pp_time= s->time - s->last_non_b_time; + s->last_non_b_time= s->time; + assert(picture_number==0 || s->pp_time > 0); + } +} + +static void mpeg4_encode_gop_header(MpegEncContext * s){ + int hours, minutes, seconds; + int64_t time; + + put_bits(&s->pb, 16, 0); + put_bits(&s->pb, 16, GOP_STARTCODE); + + time= s->current_picture_ptr->pts; + if(s->reordered_input_picture[1]) + time= FFMIN(time, s->reordered_input_picture[1]->pts); + time= time*s->avctx->time_base.num; + + seconds= time/s->avctx->time_base.den; + minutes= seconds/60; seconds %= 60; + hours= minutes/60; minutes %= 60; + hours%=24; + + put_bits(&s->pb, 5, hours); + put_bits(&s->pb, 6, minutes); + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 6, seconds); + + put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP)); + put_bits(&s->pb, 1, 0); //broken link == NO + + s->last_time_base= time / s->avctx->time_base.den; + + ff_mpeg4_stuffing(&s->pb); +} + +static void mpeg4_encode_visual_object_header(MpegEncContext * s){ + int profile_and_level_indication; + int vo_ver_id; + + if(s->avctx->profile != FF_PROFILE_UNKNOWN){ + profile_and_level_indication = s->avctx->profile << 4; + }else if(s->max_b_frames || s->quarter_sample){ + profile_and_level_indication= 0xF0; // adv simple + }else{ + profile_and_level_indication= 0x00; // simple + } + + if(s->avctx->level != FF_LEVEL_UNKNOWN){ + profile_and_level_indication |= s->avctx->level; + }else{ + profile_and_level_indication |= 1; //level 1 + } + + if(profile_and_level_indication>>4 == 0xF){ + vo_ver_id= 5; + }else{ + vo_ver_id= 1; + } + + //FIXME levels + + put_bits(&s->pb, 16, 0); + put_bits(&s->pb, 16, VOS_STARTCODE); + + put_bits(&s->pb, 8, profile_and_level_indication); + + put_bits(&s->pb, 16, 0); + put_bits(&s->pb, 16, VISUAL_OBJ_STARTCODE); + + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 4, vo_ver_id); + put_bits(&s->pb, 3, 1); //priority + + put_bits(&s->pb, 4, 1); //visual obj type== video obj + + put_bits(&s->pb, 1, 0); //video signal type == no clue //FIXME + + ff_mpeg4_stuffing(&s->pb); +} + +static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_number) +{ + int vo_ver_id; + + if(s->max_b_frames || s->quarter_sample){ + vo_ver_id= 5; + s->vo_type= ADV_SIMPLE_VO_TYPE; + }else{ + vo_ver_id= 1; + s->vo_type= SIMPLE_VO_TYPE; + } + + put_bits(&s->pb, 16, 0); + put_bits(&s->pb, 16, 0x100 + vo_number); /* video obj */ + put_bits(&s->pb, 16, 0); + put_bits(&s->pb, 16, 0x120 + vol_number); /* video obj layer */ + + put_bits(&s->pb, 1, 0); /* random access vol */ + put_bits(&s->pb, 8, s->vo_type); /* video obj type indication */ + if(s->workaround_bugs & FF_BUG_MS) { + put_bits(&s->pb, 1, 0); /* is obj layer id= no */ + } else { + put_bits(&s->pb, 1, 1); /* is obj layer id= yes */ + put_bits(&s->pb, 4, vo_ver_id); /* is obj layer ver id */ + put_bits(&s->pb, 3, 1); /* is obj layer priority */ + } + + aspect_to_info(s, s->avctx->sample_aspect_ratio); + + put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */ + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){ + put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num); + put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den); + } + + if(s->workaround_bugs & FF_BUG_MS) { // + put_bits(&s->pb, 1, 0); /* vol control parameters= no @@@ */ + } else { + put_bits(&s->pb, 1, 1); /* vol control parameters= yes */ + put_bits(&s->pb, 2, 1); /* chroma format YUV 420/YV12 */ + put_bits(&s->pb, 1, s->low_delay); + put_bits(&s->pb, 1, 0); /* vbv parameters= no */ + } + + put_bits(&s->pb, 2, RECT_SHAPE); /* vol shape= rectangle */ + put_bits(&s->pb, 1, 1); /* marker bit */ + + put_bits(&s->pb, 16, s->avctx->time_base.den); + if (s->time_increment_bits < 1) + s->time_increment_bits = 1; + put_bits(&s->pb, 1, 1); /* marker bit */ + put_bits(&s->pb, 1, 0); /* fixed vop rate=no */ + put_bits(&s->pb, 1, 1); /* marker bit */ + put_bits(&s->pb, 13, s->width); /* vol width */ + put_bits(&s->pb, 1, 1); /* marker bit */ + put_bits(&s->pb, 13, s->height); /* vol height */ + put_bits(&s->pb, 1, 1); /* marker bit */ + put_bits(&s->pb, 1, s->progressive_sequence ? 0 : 1); + put_bits(&s->pb, 1, 1); /* obmc disable */ + if (vo_ver_id == 1) { + put_bits(&s->pb, 1, s->vol_sprite_usage); /* sprite enable */ + }else{ + put_bits(&s->pb, 2, s->vol_sprite_usage); /* sprite enable */ + } + + put_bits(&s->pb, 1, 0); /* not 8 bit == false */ + put_bits(&s->pb, 1, s->mpeg_quant); /* quant type= (0=h263 style)*/ + + if(s->mpeg_quant){ + ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); + ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); + } + + if (vo_ver_id != 1) + put_bits(&s->pb, 1, s->quarter_sample); + put_bits(&s->pb, 1, 1); /* complexity estimation disable */ + s->resync_marker= s->rtp_mode; + put_bits(&s->pb, 1, s->resync_marker ? 0 : 1);/* resync marker disable */ + put_bits(&s->pb, 1, s->data_partitioning ? 1 : 0); + if(s->data_partitioning){ + put_bits(&s->pb, 1, 0); /* no rvlc */ + } + + if (vo_ver_id != 1){ + put_bits(&s->pb, 1, 0); /* newpred */ + put_bits(&s->pb, 1, 0); /* reduced res vop */ + } + put_bits(&s->pb, 1, 0); /* scalability */ + + ff_mpeg4_stuffing(&s->pb); + + /* user data */ + if(!(s->flags & CODEC_FLAG_BITEXACT)){ + put_bits(&s->pb, 16, 0); + put_bits(&s->pb, 16, 0x1B2); /* user_data */ + ff_put_string(&s->pb, LIBAVCODEC_IDENT, 0); + } +} + +/* write mpeg4 VOP header */ +void mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) +{ + int time_incr; + int time_div, time_mod; + + if(s->pict_type==I_TYPE){ + if(!(s->flags&CODEC_FLAG_GLOBAL_HEADER)){ + if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT) //HACK, the reference sw is buggy + mpeg4_encode_visual_object_header(s); + if(s->strict_std_compliance < FF_COMPLIANCE_VERY_STRICT || picture_number==0) //HACK, the reference sw is buggy + mpeg4_encode_vol_header(s, 0, 0); + } + if(!(s->workaround_bugs & FF_BUG_MS)) + mpeg4_encode_gop_header(s); + } + + s->partitioned_frame= s->data_partitioning && s->pict_type!=B_TYPE; + +//printf("num:%d rate:%d base:%d\n", s->picture_number, s->time_base.den, FRAME_RATE_BASE); + + put_bits(&s->pb, 16, 0); /* vop header */ + put_bits(&s->pb, 16, VOP_STARTCODE); /* vop header */ + put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */ + + assert(s->time>=0); + time_div= s->time/s->avctx->time_base.den; + time_mod= s->time%s->avctx->time_base.den; + time_incr= time_div - s->last_time_base; + assert(time_incr >= 0); + while(time_incr--) + put_bits(&s->pb, 1, 1); + + put_bits(&s->pb, 1, 0); + + put_bits(&s->pb, 1, 1); /* marker */ + put_bits(&s->pb, s->time_increment_bits, time_mod); /* time increment */ + put_bits(&s->pb, 1, 1); /* marker */ + put_bits(&s->pb, 1, 1); /* vop coded */ + if ( s->pict_type == P_TYPE + || (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE)) { + put_bits(&s->pb, 1, s->no_rounding); /* rounding type */ + } + put_bits(&s->pb, 3, 0); /* intra dc VLC threshold */ + if(!s->progressive_sequence){ + put_bits(&s->pb, 1, s->current_picture_ptr->top_field_first); + put_bits(&s->pb, 1, s->alternate_scan); + } + //FIXME sprite stuff + + put_bits(&s->pb, 5, s->qscale); + + if (s->pict_type != I_TYPE) + put_bits(&s->pb, 3, s->f_code); /* fcode_for */ + if (s->pict_type == B_TYPE) + put_bits(&s->pb, 3, s->b_code); /* fcode_back */ + // printf("****frame %d\n", picture_number); +} + +#endif //CONFIG_ENCODERS + +/** + * set qscale and update qscale dependant variables. + */ +void ff_set_qscale(MpegEncContext * s, int qscale) +{ + if (qscale < 1) + qscale = 1; + else if (qscale > 31) + qscale = 31; + + s->qscale = qscale; + s->chroma_qscale= s->chroma_qscale_table[qscale]; + + s->y_dc_scale= s->y_dc_scale_table[ qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ]; +} + +/** + * predicts the dc. + * encoding quantized level -> quantized diff + * decoding quantized diff -> quantized level + * @param n block index (0-3 are luma, 4-5 are chroma) + * @param dir_ptr pointer to an integer where the prediction direction will be stored + */ +static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, int level, int *dir_ptr, int encoding) +{ + int a, b, c, wrap, pred, scale, ret; + uint16_t *dc_val; + + /* find prediction */ + if (n < 4) { + scale = s->y_dc_scale; + } else { + scale = s->c_dc_scale; + } + if(IS_3IV1) + scale= 8; + + wrap= s->block_wrap[n]; + dc_val = s->dc_val[0] + s->block_index[n]; + + /* B C + * A X + */ + a = dc_val[ - 1]; + b = dc_val[ - 1 - wrap]; + c = dc_val[ - wrap]; + + /* outside slice handling (we can't do that by memset as we need the dc for error resilience) */ + if(s->first_slice_line && n!=3){ + if(n!=2) b=c= 1024; + if(n!=1 && s->mb_x == s->resync_mb_x) b=a= 1024; + } + if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1){ + if(n==0 || n==4 || n==5) + b=1024; + } + + if (abs(a - b) < abs(b - c)) { + pred = c; + *dir_ptr = 1; /* top */ + } else { + pred = a; + *dir_ptr = 0; /* left */ + } + /* we assume pred is positive */ + pred = FASTDIV((pred + (scale >> 1)), scale); + + if(encoding){ + ret = level - pred; + }else{ + level += pred; + ret= level; + if(s->error_resilience>=3){ + if(level<0){ + av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y); + return -1; + } + if(level*scale > 2048 + scale){ + av_log(s->avctx, AV_LOG_ERROR, "dc overflow at %dx%d\n", s->mb_x, s->mb_y); + return -1; + } + } + } + level *=scale; + if(level&(~2047)){ + if(level<0) + level=0; + else if(!(s->workaround_bugs&FF_BUG_DC_CLIP)) + level=2047; + } + dc_val[0]= level; + + return ret; +} + +/** + * predicts the ac. + * @param n block index (0-3 are luma, 4-5 are chroma) + * @param dir the ac prediction direction + */ +void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, + int dir) +{ + int i; + int16_t *ac_val, *ac_val1; + int8_t * const qscale_table= s->current_picture.qscale_table; + + /* find prediction */ + ac_val = s->ac_val[0][0] + s->block_index[n] * 16; + ac_val1 = ac_val; + if (s->ac_pred) { + if (dir == 0) { + const int xy= s->mb_x-1 + s->mb_y*s->mb_stride; + /* left prediction */ + ac_val -= 16; + + if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ + /* same qscale */ + for(i=1;i<8;i++) { + block[s->dsp.idct_permutation[i<<3]] += ac_val[i]; + } + }else{ + /* different qscale, we must rescale */ + for(i=1;i<8;i++) { + block[s->dsp.idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale); + } + } + } else { + const int xy= s->mb_x + s->mb_y*s->mb_stride - s->mb_stride; + /* top prediction */ + ac_val -= 16 * s->block_wrap[n]; + + if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ + /* same qscale */ + for(i=1;i<8;i++) { + block[s->dsp.idct_permutation[i]] += ac_val[i + 8]; + } + }else{ + /* different qscale, we must rescale */ + for(i=1;i<8;i++) { + block[s->dsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale); + } + } + } + } + /* left copy */ + for(i=1;i<8;i++) + ac_val1[i ] = block[s->dsp.idct_permutation[i<<3]]; + + /* top copy */ + for(i=1;i<8;i++) + ac_val1[8 + i] = block[s->dsp.idct_permutation[i ]]; + +} + +#ifdef CONFIG_ENCODERS + +/** + * encodes the dc value. + * @param n block index (0-3 are luma, 4-5 are chroma) + */ +static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n) +{ +#if 1 +// if(level<-255 || level>255) printf("dc overflow\n"); + level+=256; + if (n < 4) { + /* luminance */ + put_bits(s, uni_DCtab_lum_len[level], uni_DCtab_lum_bits[level]); + } else { + /* chrominance */ + put_bits(s, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]); + } +#else + int size, v; + /* find number of bits */ + size = 0; + v = abs(level); + while (v) { + v >>= 1; + size++; + } + + if (n < 4) { + /* luminance */ + put_bits(&s->pb, DCtab_lum[size][1], DCtab_lum[size][0]); + } else { + /* chrominance */ + put_bits(&s->pb, DCtab_chrom[size][1], DCtab_chrom[size][0]); + } + + /* encode remaining bits */ + if (size > 0) { + if (level < 0) + level = (-level) ^ ((1 << size) - 1); + put_bits(&s->pb, size, level); + if (size > 8) + put_bits(&s->pb, 1, 1); + } +#endif +} + +static inline int mpeg4_get_dc_length(int level, int n){ + if (n < 4) { + return uni_DCtab_lum_len[level + 256]; + } else { + return uni_DCtab_chrom_len[level + 256]; + } +} + +/** + * encodes a 8x8 block + * @param n block index (0-3 are luma, 4-5 are chroma) + */ +static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, + uint8_t *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb) +{ + int i, last_non_zero; +#if 0 //variables for the outcommented version + int code, sign, last; +#endif + const RLTable *rl; + uint32_t *bits_tab; + uint8_t *len_tab; + const int last_index = s->block_last_index[n]; + + if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away + /* mpeg4 based DC predictor */ + mpeg4_encode_dc(dc_pb, intra_dc, n); + if(last_index<1) return; + i = 1; + rl = &rl_intra; + bits_tab= uni_mpeg4_intra_rl_bits; + len_tab = uni_mpeg4_intra_rl_len; + } else { + if(last_index<0) return; + i = 0; + rl = &rl_inter; + bits_tab= uni_mpeg4_inter_rl_bits; + len_tab = uni_mpeg4_inter_rl_len; + } + + /* AC coefs */ + last_non_zero = i - 1; +#if 1 + for (; i < last_index; i++) { + int level = block[ scan_table[i] ]; + if (level) { + int run = i - last_non_zero - 1; + level+=64; + if((level&(~127)) == 0){ + const int index= UNI_MPEG4_ENC_INDEX(0, run, level); + put_bits(ac_pb, len_tab[index], bits_tab[index]); + }else{ //ESC3 + put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); + } + last_non_zero = i; + } + } + /*if(i<=last_index)*/{ + int level = block[ scan_table[i] ]; + int run = i - last_non_zero - 1; + level+=64; + if((level&(~127)) == 0){ + const int index= UNI_MPEG4_ENC_INDEX(1, run, level); + put_bits(ac_pb, len_tab[index], bits_tab[index]); + }else{ //ESC3 + put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1); + } + } +#else + for (; i <= last_index; i++) { + const int slevel = block[ scan_table[i] ]; + if (slevel) { + int level; + int run = i - last_non_zero - 1; + last = (i == last_index); + sign = 0; + level = slevel; + if (level < 0) { + sign = 1; + level = -level; + } + code = get_rl_index(rl, last, run, level); + put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + if (code == rl->n) { + int level1, run1; + level1 = level - rl->max_level[last][run]; + if (level1 < 1) + goto esc2; + code = get_rl_index(rl, last, run, level1); + if (code == rl->n) { + esc2: + put_bits(ac_pb, 1, 1); + if (level > MAX_LEVEL) + goto esc3; + run1 = run - rl->max_run[last][level] - 1; + if (run1 < 0) + goto esc3; + code = get_rl_index(rl, last, run1, level); + if (code == rl->n) { + esc3: + /* third escape */ + put_bits(ac_pb, 1, 1); + put_bits(ac_pb, 1, last); + put_bits(ac_pb, 6, run); + put_bits(ac_pb, 1, 1); + put_bits(ac_pb, 12, slevel & 0xfff); + put_bits(ac_pb, 1, 1); + } else { + /* second escape */ + put_bits(ac_pb, 1, 0); + put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + put_bits(ac_pb, 1, sign); + } + } else { + /* first escape */ + put_bits(ac_pb, 1, 0); + put_bits(ac_pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + put_bits(ac_pb, 1, sign); + } + } else { + put_bits(ac_pb, 1, sign); + } + last_non_zero = i; + } + } +#endif +} + +static int mpeg4_get_block_length(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, + uint8_t *scan_table) +{ + int i, last_non_zero; + const RLTable *rl; + uint8_t *len_tab; + const int last_index = s->block_last_index[n]; + int len=0; + + if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away + /* mpeg4 based DC predictor */ + len += mpeg4_get_dc_length(intra_dc, n); + if(last_index<1) return len; + i = 1; + rl = &rl_intra; + len_tab = uni_mpeg4_intra_rl_len; + } else { + if(last_index<0) return 0; + i = 0; + rl = &rl_inter; + len_tab = uni_mpeg4_inter_rl_len; + } + + /* AC coefs */ + last_non_zero = i - 1; + for (; i < last_index; i++) { + int level = block[ scan_table[i] ]; + if (level) { + int run = i - last_non_zero - 1; + level+=64; + if((level&(~127)) == 0){ + const int index= UNI_MPEG4_ENC_INDEX(0, run, level); + len += len_tab[index]; + }else{ //ESC3 + len += 7+2+1+6+1+12+1; + } + last_non_zero = i; + } + } + /*if(i<=last_index)*/{ + int level = block[ scan_table[i] ]; + int run = i - last_non_zero - 1; + level+=64; + if((level&(~127)) == 0){ + const int index= UNI_MPEG4_ENC_INDEX(1, run, level); + len += len_tab[index]; + }else{ //ESC3 + len += 7+2+1+6+1+12+1; + } + } + + return len; +} + +#endif + + +/***********************************************/ +/* decoding */ + +static VLC intra_MCBPC_vlc; +static VLC inter_MCBPC_vlc; +static VLC cbpy_vlc; +static VLC mv_vlc; +static VLC dc_lum, dc_chrom; +static VLC sprite_trajectory; +static VLC mb_type_b_vlc; +static VLC h263_mbtype_b_vlc; +static VLC cbpc_b_vlc; + +void init_vlc_rl(RLTable *rl, int use_static) +{ + int i, q; + + /* Return if static table is already initialized */ + if(use_static && rl->rl_vlc[0]) + return; + + init_vlc(&rl->vlc, 9, rl->n + 1, + &rl->table_vlc[0][1], 4, 2, + &rl->table_vlc[0][0], 4, 2, use_static); + + + for(q=0; q<32; q++){ + int qmul= q*2; + int qadd= (q-1)|1; + + if(q==0){ + qmul=1; + qadd=0; + } + if(use_static) + rl->rl_vlc[q]= av_mallocz_static(rl->vlc.table_size*sizeof(RL_VLC_ELEM)); + else + rl->rl_vlc[q]= av_malloc(rl->vlc.table_size*sizeof(RL_VLC_ELEM)); + for(i=0; ivlc.table_size; i++){ + int code= rl->vlc.table[i][0]; + int len = rl->vlc.table[i][1]; + int level, run; + + if(len==0){ // illegal code + run= 66; + level= MAX_LEVEL; + }else if(len<0){ //more bits needed + run= 0; + level= code; + }else{ + if(code==rl->n){ //esc + run= 66; + level= 0; + }else{ + run= rl->table_run [code] + 1; + level= rl->table_level[code] * qmul + qadd; + if(code >= rl->last) run+=192; + } + } + rl->rl_vlc[q][i].len= len; + rl->rl_vlc[q][i].level= level; + rl->rl_vlc[q][i].run= run; + } + } +} + +/* init vlcs */ + +/* XXX: find a better solution to handle static init */ +void h263_decode_init_vlc(MpegEncContext *s) +{ + static int done = 0; + + if (!done) { + done = 1; + + init_vlc(&intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9, + intra_MCBPC_bits, 1, 1, + intra_MCBPC_code, 1, 1, 1); + init_vlc(&inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 28, + inter_MCBPC_bits, 1, 1, + inter_MCBPC_code, 1, 1, 1); + init_vlc(&cbpy_vlc, CBPY_VLC_BITS, 16, + &cbpy_tab[0][1], 2, 1, + &cbpy_tab[0][0], 2, 1, 1); + init_vlc(&mv_vlc, MV_VLC_BITS, 33, + &mvtab[0][1], 2, 1, + &mvtab[0][0], 2, 1, 1); + init_rl(&rl_inter, 1); + init_rl(&rl_intra, 1); + init_rl(&rvlc_rl_inter, 1); + init_rl(&rvlc_rl_intra, 1); + init_rl(&rl_intra_aic, 1); + init_vlc_rl(&rl_inter, 1); + init_vlc_rl(&rl_intra, 1); + init_vlc_rl(&rvlc_rl_inter, 1); + init_vlc_rl(&rvlc_rl_intra, 1); + init_vlc_rl(&rl_intra_aic, 1); + init_vlc(&dc_lum, DC_VLC_BITS, 10 /* 13 */, + &DCtab_lum[0][1], 2, 1, + &DCtab_lum[0][0], 2, 1, 1); + init_vlc(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, + &DCtab_chrom[0][1], 2, 1, + &DCtab_chrom[0][0], 2, 1, 1); + init_vlc(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, + &sprite_trajectory_tab[0][1], 4, 2, + &sprite_trajectory_tab[0][0], 4, 2, 1); + init_vlc(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, + &mb_type_b_tab[0][1], 2, 1, + &mb_type_b_tab[0][0], 2, 1, 1); + init_vlc(&h263_mbtype_b_vlc, H263_MBTYPE_B_VLC_BITS, 15, + &h263_mbtype_b_tab[0][1], 2, 1, + &h263_mbtype_b_tab[0][0], 2, 1, 1); + init_vlc(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4, + &cbpc_b_tab[0][1], 2, 1, + &cbpc_b_tab[0][0], 2, 1, 1); + } +} + +/** + * Get the GOB height based on picture height. + */ +int ff_h263_get_gob_height(MpegEncContext *s){ + if (s->height <= 400) + return 1; + else if (s->height <= 800) + return 2; + else + return 4; +} + +int ff_h263_decode_mba(MpegEncContext *s) +{ + int i, mb_pos; + + for(i=0; i<6; i++){ + if(s->mb_num-1 <= ff_mba_max[i]) break; + } + mb_pos= get_bits(&s->gb, ff_mba_length[i]); + s->mb_x= mb_pos % s->mb_width; + s->mb_y= mb_pos / s->mb_width; + + return mb_pos; +} + +void ff_h263_encode_mba(MpegEncContext *s) +{ + int i, mb_pos; + + for(i=0; i<6; i++){ + if(s->mb_num-1 <= ff_mba_max[i]) break; + } + mb_pos= s->mb_x + s->mb_width*s->mb_y; + put_bits(&s->pb, ff_mba_length[i], mb_pos); +} + +/** + * decodes the group of blocks header or slice header. + * @return <0 if an error occured + */ +static int h263_decode_gob_header(MpegEncContext *s) +{ + unsigned int val, gfid, gob_number; + int left; + + /* Check for GOB Start Code */ + val = show_bits(&s->gb, 16); + if(val) + return -1; + + /* We have a GBSC probably with GSTUFF */ + skip_bits(&s->gb, 16); /* Drop the zeros */ + left= s->gb.size_in_bits - get_bits_count(&s->gb); + //MN: we must check the bits left or we might end in a infinite loop (or segfault) + for(;left>13; left--){ + if(get_bits1(&s->gb)) break; /* Seek the '1' bit */ + } + if(left<=13) + return -1; + + if(s->h263_slice_structured){ + if(get_bits1(&s->gb)==0) + return -1; + + ff_h263_decode_mba(s); + + if(s->mb_num > 1583) + if(get_bits1(&s->gb)==0) + return -1; + + s->qscale = get_bits(&s->gb, 5); /* SQUANT */ + if(get_bits1(&s->gb)==0) + return -1; + gfid = get_bits(&s->gb, 2); /* GFID */ + }else{ + gob_number = get_bits(&s->gb, 5); /* GN */ + s->mb_x= 0; + s->mb_y= s->gob_index* gob_number; + gfid = get_bits(&s->gb, 2); /* GFID */ + s->qscale = get_bits(&s->gb, 5); /* GQUANT */ + } + + if(s->mb_y >= s->mb_height) + return -1; + + if(s->qscale==0) + return -1; + + return 0; +} + +static inline void memsetw(short *tab, int val, int n) +{ + int i; + for(i=0;ipb); + uint8_t *end= s->pb.buf_end; + int size= end - start; + int pb_size = (((long)start + size/3)&(~3)) - (long)start; + int tex_size= (size - 2*pb_size)&(~3); + + set_put_bits_buffer_size(&s->pb, pb_size); + init_put_bits(&s->tex_pb, start + pb_size , tex_size); + init_put_bits(&s->pb2 , start + pb_size + tex_size, pb_size); +} + +void ff_mpeg4_merge_partitions(MpegEncContext *s) +{ + const int pb2_len = put_bits_count(&s->pb2 ); + const int tex_pb_len= put_bits_count(&s->tex_pb); + const int bits= put_bits_count(&s->pb); + + if(s->pict_type==I_TYPE){ + put_bits(&s->pb, 19, DC_MARKER); + s->misc_bits+=19 + pb2_len + bits - s->last_bits; + s->i_tex_bits+= tex_pb_len; + }else{ + put_bits(&s->pb, 17, MOTION_MARKER); + s->misc_bits+=17 + pb2_len; + s->mv_bits+= bits - s->last_bits; + s->p_tex_bits+= tex_pb_len; + } + + flush_put_bits(&s->pb2); + flush_put_bits(&s->tex_pb); + + set_put_bits_buffer_size(&s->pb, s->pb2.buf_end - s->pb.buf); + ff_copy_bits(&s->pb, s->pb2.buf , pb2_len); + ff_copy_bits(&s->pb, s->tex_pb.buf, tex_pb_len); + s->last_bits= put_bits_count(&s->pb); +} + +#endif //CONFIG_ENCODERS + +int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s){ + switch(s->pict_type){ + case I_TYPE: + return 16; + case P_TYPE: + case S_TYPE: + return s->f_code+15; + case B_TYPE: + return FFMAX(FFMAX(s->f_code, s->b_code)+15, 17); + default: + return -1; + } +} + +#ifdef CONFIG_ENCODERS + +void ff_mpeg4_encode_video_packet_header(MpegEncContext *s) +{ + int mb_num_bits= av_log2(s->mb_num - 1) + 1; + + put_bits(&s->pb, ff_mpeg4_get_video_packet_prefix_length(s), 0); + put_bits(&s->pb, 1, 1); + + put_bits(&s->pb, mb_num_bits, s->mb_x + s->mb_y*s->mb_width); + put_bits(&s->pb, s->quant_precision, s->qscale); + put_bits(&s->pb, 1, 0); /* no HEC */ +} + +#endif //CONFIG_ENCODERS + +/** + * check if the next stuff is a resync marker or the end. + * @return 0 if not + */ +static inline int mpeg4_is_resync(MpegEncContext *s){ + const int bits_count= get_bits_count(&s->gb); + + if(s->workaround_bugs&FF_BUG_NO_PADDING){ + return 0; + } + + if(bits_count + 8 >= s->gb.size_in_bits){ + int v= show_bits(&s->gb, 8); + v|= 0x7F >> (7-(bits_count&7)); + + if(v==0x7F) + return 1; + }else{ + if(show_bits(&s->gb, 16) == ff_mpeg4_resync_prefix[bits_count&7]){ + int len; + GetBitContext gb= s->gb; + + skip_bits(&s->gb, 1); + align_get_bits(&s->gb); + + for(len=0; len<32; len++){ + if(get_bits1(&s->gb)) break; + } + + s->gb= gb; + + if(len>=ff_mpeg4_get_video_packet_prefix_length(s)) + return 1; + } + } + return 0; +} + +/** + * decodes the next video packet. + * @return <0 if something went wrong + */ +static int mpeg4_decode_video_packet_header(MpegEncContext *s) +{ + int mb_num_bits= av_log2(s->mb_num - 1) + 1; + int header_extension=0, mb_num, len; + + /* is there enough space left for a video packet + header */ + if( get_bits_count(&s->gb) > s->gb.size_in_bits-20) return -1; + + for(len=0; len<32; len++){ + if(get_bits1(&s->gb)) break; + } + + if(len!=ff_mpeg4_get_video_packet_prefix_length(s)){ + av_log(s->avctx, AV_LOG_ERROR, "marker does not match f_code\n"); + return -1; + } + + if(s->shape != RECT_SHAPE){ + header_extension= get_bits1(&s->gb); + //FIXME more stuff here + } + + mb_num= get_bits(&s->gb, mb_num_bits); + if(mb_num>=s->mb_num){ + av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num); + return -1; + } + if(s->pict_type == B_TYPE){ + while(s->next_picture.mbskip_table[ s->mb_index2xy[ mb_num ] ]) mb_num++; + if(mb_num >= s->mb_num) return -1; // slice contains just skipped MBs which where allready decoded + } + + s->mb_x= mb_num % s->mb_width; + s->mb_y= mb_num / s->mb_width; + + if(s->shape != BIN_ONLY_SHAPE){ + int qscale= get_bits(&s->gb, s->quant_precision); + if(qscale) + s->chroma_qscale=s->qscale= qscale; + } + + if(s->shape == RECT_SHAPE){ + header_extension= get_bits1(&s->gb); + } + if(header_extension){ + int time_increment; + int time_incr=0; + + while (get_bits1(&s->gb) != 0) + time_incr++; + + check_marker(&s->gb, "before time_increment in video packed header"); + time_increment= get_bits(&s->gb, s->time_increment_bits); + check_marker(&s->gb, "before vop_coding_type in video packed header"); + + skip_bits(&s->gb, 2); /* vop coding type */ + //FIXME not rect stuff here + + if(s->shape != BIN_ONLY_SHAPE){ + skip_bits(&s->gb, 3); /* intra dc vlc threshold */ +//FIXME don't just ignore everything + if(s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ + mpeg4_decode_sprite_trajectory(s, &s->gb); + av_log(s->avctx, AV_LOG_ERROR, "untested\n"); + } + + //FIXME reduced res stuff here + + if (s->pict_type != I_TYPE) { + int f_code = get_bits(&s->gb, 3); /* fcode_for */ + if(f_code==0){ + av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (f_code=0)\n"); + } + } + if (s->pict_type == B_TYPE) { + int b_code = get_bits(&s->gb, 3); + if(b_code==0){ + av_log(s->avctx, AV_LOG_ERROR, "Error, video packet header damaged (b_code=0)\n"); + } + } + } + } + //FIXME new-pred stuff + +//printf("parse ok %d %d %d %d\n", mb_num, s->mb_x + s->mb_y*s->mb_width, get_bits_count(gb), get_bits_count(&s->gb)); + + return 0; +} + +void ff_mpeg4_clean_buffers(MpegEncContext *s) +{ + int c_wrap, c_xy, l_wrap, l_xy; + + l_wrap= s->b8_stride; + l_xy= (2*s->mb_y-1)*l_wrap + s->mb_x*2 - 1; + c_wrap= s->mb_stride; + c_xy= (s->mb_y-1)*c_wrap + s->mb_x - 1; + +#if 0 + /* clean DC */ + memsetw(s->dc_val[0] + l_xy, 1024, l_wrap*2+1); + memsetw(s->dc_val[1] + c_xy, 1024, c_wrap+1); + memsetw(s->dc_val[2] + c_xy, 1024, c_wrap+1); +#endif + + /* clean AC */ + memset(s->ac_val[0] + l_xy, 0, (l_wrap*2+1)*16*sizeof(int16_t)); + memset(s->ac_val[1] + c_xy, 0, (c_wrap +1)*16*sizeof(int16_t)); + memset(s->ac_val[2] + c_xy, 0, (c_wrap +1)*16*sizeof(int16_t)); + + /* clean MV */ + // we can't clear the MVs as they might be needed by a b frame +// memset(s->motion_val + l_xy, 0, (l_wrap*2+1)*2*sizeof(int16_t)); +// memset(s->motion_val, 0, 2*sizeof(int16_t)*(2 + s->mb_width*2)*(2 + s->mb_height*2)); + s->last_mv[0][0][0]= + s->last_mv[0][0][1]= + s->last_mv[1][0][0]= + s->last_mv[1][0][1]= 0; +} + +/** + * decodes the group of blocks / video packet header. + * @return <0 if no resync found + */ +int ff_h263_resync(MpegEncContext *s){ + int left, ret; + + if(s->codec_id==CODEC_ID_MPEG4){ + skip_bits1(&s->gb); + align_get_bits(&s->gb); + } + + if(show_bits(&s->gb, 16)==0){ + if(s->codec_id==CODEC_ID_MPEG4) + ret= mpeg4_decode_video_packet_header(s); + else + ret= h263_decode_gob_header(s); + if(ret>=0) + return 0; + } + //ok, it's not where its supposed to be ... + s->gb= s->last_resync_gb; + align_get_bits(&s->gb); + left= s->gb.size_in_bits - get_bits_count(&s->gb); + + for(;left>16+1+5+5; left-=8){ + if(show_bits(&s->gb, 16)==0){ + GetBitContext bak= s->gb; + + if(s->codec_id==CODEC_ID_MPEG4) + ret= mpeg4_decode_video_packet_header(s); + else + ret= h263_decode_gob_header(s); + if(ret>=0) + return 0; + + s->gb= bak; + } + skip_bits(&s->gb, 8); + } + + return -1; +} + +/** + * gets the average motion vector for a GMC MB. + * @param n either 0 for the x component or 1 for y + * @returns the average MV for a GMC MB + */ +static inline int get_amv(MpegEncContext *s, int n){ + int x, y, mb_v, sum, dx, dy, shift; + int len = 1 << (s->f_code + 4); + const int a= s->sprite_warping_accuracy; + + if(s->workaround_bugs & FF_BUG_AMV) + len >>= s->quarter_sample; + + if(s->real_sprite_warping_points==1){ + if(s->divx_version==500 && s->divx_build==413) + sum= s->sprite_offset[0][n] / (1<<(a - s->quarter_sample)); + else + sum= RSHIFT(s->sprite_offset[0][n]<quarter_sample, a); + }else{ + dx= s->sprite_delta[n][0]; + dy= s->sprite_delta[n][1]; + shift= s->sprite_shift[0]; + if(n) dy -= 1<<(shift + a + 1); + else dx -= 1<<(shift + a + 1); + mb_v= s->sprite_offset[0][n] + dx*s->mb_x*16 + dy*s->mb_y*16; + + sum=0; + for(y=0; y<16; y++){ + int v; + + v= mb_v + dy*y; + //XXX FIXME optimize + for(x=0; x<16; x++){ + sum+= v>>shift; + v+= dx; + } + } + sum= RSHIFT(sum, a+8-s->quarter_sample); + } + + if (sum < -len) sum= -len; + else if (sum >= len) sum= len-1; + + return sum; +} + +/** + * decodes first partition. + * @return number of MBs decoded or <0 if an error occured + */ +static int mpeg4_decode_partition_a(MpegEncContext *s){ + int mb_num; + static const int8_t quant_tab[4] = { -1, -2, 1, 2 }; + + /* decode first partition */ + mb_num=0; + s->first_slice_line=1; + for(; s->mb_ymb_height; s->mb_y++){ + ff_init_block_index(s); + for(; s->mb_xmb_width; s->mb_x++){ + const int xy= s->mb_x + s->mb_y*s->mb_stride; + int cbpc; + int dir=0; + + mb_num++; + ff_update_block_index(s); + if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1) + s->first_slice_line=0; + + if(s->pict_type==I_TYPE){ + int i; + + do{ + if(show_bits_long(&s->gb, 19)==DC_MARKER){ + return mb_num-1; + } + + cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); + if (cbpc < 0){ + av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + }while(cbpc == 8); + + s->cbp_table[xy]= cbpc & 3; + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + s->mb_intra = 1; + + if(cbpc & 4) { + ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); + } + s->current_picture.qscale_table[xy]= s->qscale; + + s->mbintra_table[xy]= 1; + for(i=0; i<6; i++){ + int dc_pred_dir; + int dc= mpeg4_decode_dc(s, i, &dc_pred_dir); + if(dc < 0){ + av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + dir<<=1; + if(dc_pred_dir) dir|=1; + } + s->pred_dir_table[xy]= dir; + }else{ /* P/S_TYPE */ + int mx, my, pred_x, pred_y, bits; + int16_t * const mot_val= s->current_picture.motion_val[0][s->block_index[0]]; + const int stride= s->b8_stride*2; + +try_again: + bits= show_bits(&s->gb, 17); + if(bits==MOTION_MARKER){ + return mb_num-1; + } + skip_bits1(&s->gb); + if(bits&0x10000){ + /* skip mb */ + if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; + mx= get_amv(s, 0); + my= get_amv(s, 1); + }else{ + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + mx=my=0; + } + mot_val[0 ]= mot_val[2 ]= + mot_val[0+stride]= mot_val[2+stride]= mx; + mot_val[1 ]= mot_val[3 ]= + mot_val[1+stride]= mot_val[3+stride]= my; + + if(s->mbintra_table[xy]) + ff_clean_intra_table_entries(s); + continue; + } + + cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); + if (cbpc < 0){ + av_log(s->avctx, AV_LOG_ERROR, "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + if(cbpc == 20) + goto try_again; + + s->cbp_table[xy]= cbpc&(8+3); //8 is dquant + + s->mb_intra = ((cbpc & 4) != 0); + + if(s->mb_intra){ + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + s->mbintra_table[xy]= 1; + mot_val[0 ]= mot_val[2 ]= + mot_val[0+stride]= mot_val[2+stride]= 0; + mot_val[1 ]= mot_val[3 ]= + mot_val[1+stride]= mot_val[3+stride]= 0; + }else{ + if(s->mbintra_table[xy]) + ff_clean_intra_table_entries(s); + + if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0) + s->mcsel= get_bits1(&s->gb); + else s->mcsel= 0; + + if ((cbpc & 16) == 0) { + /* 16x16 motion prediction */ + + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + if(!s->mcsel){ + mx = h263_decode_motion(s, pred_x, s->f_code); + if (mx >= 0xffff) + return -1; + + my = h263_decode_motion(s, pred_y, s->f_code); + if (my >= 0xffff) + return -1; + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; + } else { + mx = get_amv(s, 0); + my = get_amv(s, 1); + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0; + } + + mot_val[0 ]= mot_val[2 ] = + mot_val[0+stride]= mot_val[2+stride]= mx; + mot_val[1 ]= mot_val[3 ]= + mot_val[1+stride]= mot_val[3+stride]= my; + } else { + int i; + s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; + for(i=0;i<4;i++) { + int16_t *mot_val= h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mx = h263_decode_motion(s, pred_x, s->f_code); + if (mx >= 0xffff) + return -1; + + my = h263_decode_motion(s, pred_y, s->f_code); + if (my >= 0xffff) + return -1; + mot_val[0] = mx; + mot_val[1] = my; + } + } + } + } + } + s->mb_x= 0; + } + + return mb_num; +} + +/** + * decode second partition. + * @return <0 if an error occured + */ +static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ + int mb_num=0; + static const int8_t quant_tab[4] = { -1, -2, 1, 2 }; + + s->mb_x= s->resync_mb_x; + s->first_slice_line=1; + for(s->mb_y= s->resync_mb_y; mb_num < mb_count; s->mb_y++){ + ff_init_block_index(s); + for(; mb_num < mb_count && s->mb_xmb_width; s->mb_x++){ + const int xy= s->mb_x + s->mb_y*s->mb_stride; + + mb_num++; + ff_update_block_index(s); + if(s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y+1) + s->first_slice_line=0; + + if(s->pict_type==I_TYPE){ + int ac_pred= get_bits1(&s->gb); + int cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); + if(cbpy<0){ + av_log(s->avctx, AV_LOG_ERROR, "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + s->cbp_table[xy]|= cbpy<<2; + s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; + }else{ /* P || S_TYPE */ + if(IS_INTRA(s->current_picture.mb_type[xy])){ + int dir=0,i; + int ac_pred = get_bits1(&s->gb); + int cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); + + if(cbpy<0){ + av_log(s->avctx, AV_LOG_ERROR, "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + if(s->cbp_table[xy] & 8) { + ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); + } + s->current_picture.qscale_table[xy]= s->qscale; + + for(i=0; i<6; i++){ + int dc_pred_dir; + int dc= mpeg4_decode_dc(s, i, &dc_pred_dir); + if(dc < 0){ + av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + dir<<=1; + if(dc_pred_dir) dir|=1; + } + s->cbp_table[xy]&= 3; //remove dquant + s->cbp_table[xy]|= cbpy<<2; + s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED; + s->pred_dir_table[xy]= dir; + }else if(IS_SKIP(s->current_picture.mb_type[xy])){ + s->current_picture.qscale_table[xy]= s->qscale; + s->cbp_table[xy]= 0; + }else{ + int cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); + + if(cbpy<0){ + av_log(s->avctx, AV_LOG_ERROR, "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + if(s->cbp_table[xy] & 8) { + ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); + } + s->current_picture.qscale_table[xy]= s->qscale; + + s->cbp_table[xy]&= 3; //remove dquant + s->cbp_table[xy]|= (cbpy^0xf)<<2; + } + } + } + if(mb_num >= mb_count) return 0; + s->mb_x= 0; + } + return 0; +} + +/** + * decodes the first & second partition + * @return <0 if error (and sets error type in the error_status_table) + */ +int ff_mpeg4_decode_partitions(MpegEncContext *s) +{ + int mb_num; + const int part_a_error= s->pict_type==I_TYPE ? (DC_ERROR|MV_ERROR) : MV_ERROR; + const int part_a_end = s->pict_type==I_TYPE ? (DC_END |MV_END) : MV_END; + + mb_num= mpeg4_decode_partition_a(s); + if(mb_num<0){ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error); + return -1; + } + + if(s->resync_mb_x + s->resync_mb_y*s->mb_width + mb_num > s->mb_num){ + av_log(s->avctx, AV_LOG_ERROR, "slice below monitor ...\n"); + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error); + return -1; + } + + s->mb_num_left= mb_num; + + if(s->pict_type==I_TYPE){ + while(show_bits(&s->gb, 9) == 1) + skip_bits(&s->gb, 9); + if(get_bits_long(&s->gb, 19)!=DC_MARKER){ + av_log(s->avctx, AV_LOG_ERROR, "marker missing after first I partition at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + }else{ + while(show_bits(&s->gb, 10) == 1) + skip_bits(&s->gb, 10); + if(get_bits(&s->gb, 17)!=MOTION_MARKER){ + av_log(s->avctx, AV_LOG_ERROR, "marker missing after first P partition at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + } + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, part_a_end); + + if( mpeg4_decode_partition_b(s, mb_num) < 0){ + if(s->pict_type==P_TYPE) + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, DC_ERROR); + return -1; + }else{ + if(s->pict_type==P_TYPE) + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, DC_END); + } + + return 0; +} + +/** + * decode partition C of one MB. + * @return <0 if an error occured + */ +static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) +{ + int cbp, mb_type; + const int xy= s->mb_x + s->mb_y*s->mb_stride; + + mb_type= s->current_picture.mb_type[xy]; + cbp = s->cbp_table[xy]; + + if(s->current_picture.qscale_table[xy] != s->qscale){ + ff_set_qscale(s, s->current_picture.qscale_table[xy] ); + } + + if (s->pict_type == P_TYPE || s->pict_type==S_TYPE) { + int i; + for(i=0; i<4; i++){ + s->mv[0][i][0] = s->current_picture.motion_val[0][ s->block_index[i] ][0]; + s->mv[0][i][1] = s->current_picture.motion_val[0][ s->block_index[i] ][1]; + } + s->mb_intra = IS_INTRA(mb_type); + + if (IS_SKIP(mb_type)) { + /* skip mb */ + for(i=0;i<6;i++) + s->block_last_index[i] = -1; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ + s->mcsel=1; + s->mb_skipped = 0; + }else{ + s->mcsel=0; + s->mb_skipped = 1; + } + }else if(s->mb_intra){ + s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); + }else if(!s->mb_intra){ +// s->mcsel= 0; //FIXME do we need to init that + + s->mv_dir = MV_DIR_FORWARD; + if (IS_8X8(mb_type)) { + s->mv_type = MV_TYPE_8X8; + } else { + s->mv_type = MV_TYPE_16X16; + } + } + } else { /* I-Frame */ + s->mb_intra = 1; + s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]); + } + + if (!IS_SKIP(mb_type)) { + int i; + s->dsp.clear_blocks(s->block[0]); + /* decode each block */ + for (i = 0; i < 6; i++) { + if(mpeg4_decode_block(s, block[i], i, cbp&32, s->mb_intra, s->rvlc) < 0){ + av_log(s->avctx, AV_LOG_ERROR, "texture corrupted at %d %d %d\n", s->mb_x, s->mb_y, s->mb_intra); + return -1; + } + cbp+=cbp; + } + } + + /* per-MB end of slice check */ + + if(--s->mb_num_left <= 0){ +//printf("%06X %d\n", show_bits(&s->gb, 24), s->gb.size_in_bits - get_bits_count(&s->gb)); + if(mpeg4_is_resync(s)) + return SLICE_END; + else + return SLICE_NOEND; + }else{ + if(mpeg4_is_resync(s)){ + const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; + if(s->cbp_table[xy+delta]) + return SLICE_END; + } + return SLICE_OK; + } +} + +/** + * read the next MVs for OBMC. yes this is a ugly hack, feel free to send a patch :) + */ +static void preview_obmc(MpegEncContext *s){ + GetBitContext gb= s->gb; + + int cbpc, i, pred_x, pred_y, mx, my; + int16_t *mot_val; + const int xy= s->mb_x + 1 + s->mb_y * s->mb_stride; + const int stride= s->b8_stride*2; + + for(i=0; i<4; i++) + s->block_index[i]+= 2; + for(i=4; i<6; i++) + s->block_index[i]+= 1; + s->mb_x++; + + assert(s->pict_type == P_TYPE); + + do{ + if (get_bits1(&s->gb)) { + /* skip mb */ + mot_val = s->current_picture.motion_val[0][ s->block_index[0] ]; + mot_val[0 ]= mot_val[2 ]= + mot_val[0+stride]= mot_val[2+stride]= 0; + mot_val[1 ]= mot_val[3 ]= + mot_val[1+stride]= mot_val[3+stride]= 0; + + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + goto end; + } + cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); + }while(cbpc == 20); + + if(cbpc & 4){ + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + }else{ + get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); + if (cbpc & 8) { + if(s->modified_quant){ + if(get_bits1(&s->gb)) skip_bits(&s->gb, 1); + else skip_bits(&s->gb, 5); + }else + skip_bits(&s->gb, 2); + } + + if ((cbpc & 16) == 0) { + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; + /* 16x16 motion prediction */ + mot_val= h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + if (s->umvplus) + mx = h263p_decode_umotion(s, pred_x); + else + mx = h263_decode_motion(s, pred_x, 1); + + if (s->umvplus) + my = h263p_decode_umotion(s, pred_y); + else + my = h263_decode_motion(s, pred_y, 1); + + mot_val[0 ]= mot_val[2 ]= + mot_val[0+stride]= mot_val[2+stride]= mx; + mot_val[1 ]= mot_val[3 ]= + mot_val[1+stride]= mot_val[3+stride]= my; + } else { + s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; + for(i=0;i<4;i++) { + mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); + if (s->umvplus) + mx = h263p_decode_umotion(s, pred_x); + else + mx = h263_decode_motion(s, pred_x, 1); + + if (s->umvplus) + my = h263p_decode_umotion(s, pred_y); + else + my = h263_decode_motion(s, pred_y, 1); + if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1) + skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ + mot_val[0] = mx; + mot_val[1] = my; + } + } + } +end: + + for(i=0; i<4; i++) + s->block_index[i]-= 2; + for(i=4; i<6; i++) + s->block_index[i]-= 1; + s->mb_x--; + + s->gb= gb; +} + +static void h263_decode_dquant(MpegEncContext *s){ + static const int8_t quant_tab[4] = { -1, -2, 1, 2 }; + + if(s->modified_quant){ + if(get_bits1(&s->gb)) + s->qscale= modified_quant_tab[get_bits1(&s->gb)][ s->qscale ]; + else + s->qscale= get_bits(&s->gb, 5); + }else + s->qscale += quant_tab[get_bits(&s->gb, 2)]; + ff_set_qscale(s, s->qscale); +} + +int ff_h263_decode_mb(MpegEncContext *s, + DCTELEM block[6][64]) +{ + int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; + int16_t *mot_val; + const int xy= s->mb_x + s->mb_y * s->mb_stride; + + assert(!s->h263_pred); + + if (s->pict_type == P_TYPE) { + do{ + if (get_bits1(&s->gb)) { + /* skip mb */ + s->mb_intra = 0; + for(i=0;i<6;i++) + s->block_last_index[i] = -1; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mb_skipped = !(s->obmc | s->loop_filter); + goto end; + } + cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); + //fprintf(stderr, "\tCBPC: %d", cbpc); + if (cbpc < 0){ + av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + }while(cbpc == 20); + + s->dsp.clear_blocks(s->block[0]); + + dquant = cbpc & 8; + s->mb_intra = ((cbpc & 4) != 0); + if (s->mb_intra) goto intra; + + cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); + + if(s->alt_inter_vlc==0 || (cbpc & 3)!=3) + cbpy ^= 0xF; + + cbp = (cbpc & 3) | (cbpy << 2); + if (dquant) { + h263_decode_dquant(s); + } + + s->mv_dir = MV_DIR_FORWARD; + if ((cbpc & 16) == 0) { + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; + /* 16x16 motion prediction */ + s->mv_type = MV_TYPE_16X16; + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + if (s->umvplus) + mx = h263p_decode_umotion(s, pred_x); + else + mx = h263_decode_motion(s, pred_x, 1); + + if (mx >= 0xffff) + return -1; + + if (s->umvplus) + my = h263p_decode_umotion(s, pred_y); + else + my = h263_decode_motion(s, pred_y, 1); + + if (my >= 0xffff) + return -1; + s->mv[0][0][0] = mx; + s->mv[0][0][1] = my; + + if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1) + skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ + } else { + s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; + s->mv_type = MV_TYPE_8X8; + for(i=0;i<4;i++) { + mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); + if (s->umvplus) + mx = h263p_decode_umotion(s, pred_x); + else + mx = h263_decode_motion(s, pred_x, 1); + if (mx >= 0xffff) + return -1; + + if (s->umvplus) + my = h263p_decode_umotion(s, pred_y); + else + my = h263_decode_motion(s, pred_y, 1); + if (my >= 0xffff) + return -1; + s->mv[0][i][0] = mx; + s->mv[0][i][1] = my; + if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1) + skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ + mot_val[0] = mx; + mot_val[1] = my; + } + } + + /* decode each block */ + for (i = 0; i < 6; i++) { + if (h263_decode_block(s, block[i], i, cbp&32) < 0) + return -1; + cbp+=cbp; + } + + if(s->obmc){ + if(s->pict_type == P_TYPE && s->mb_x+1mb_width && s->mb_num_left != 1) + preview_obmc(s); + } + } else if(s->pict_type==B_TYPE) { + int mb_type; + const int stride= s->b8_stride; + int16_t *mot_val0 = s->current_picture.motion_val[0][ 2*(s->mb_x + s->mb_y*stride) ]; + int16_t *mot_val1 = s->current_picture.motion_val[1][ 2*(s->mb_x + s->mb_y*stride) ]; +// const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride; + + //FIXME ugly + mot_val0[0 ]= mot_val0[2 ]= mot_val0[0+2*stride]= mot_val0[2+2*stride]= + mot_val0[1 ]= mot_val0[3 ]= mot_val0[1+2*stride]= mot_val0[3+2*stride]= + mot_val1[0 ]= mot_val1[2 ]= mot_val1[0+2*stride]= mot_val1[2+2*stride]= + mot_val1[1 ]= mot_val1[3 ]= mot_val1[1+2*stride]= mot_val1[3+2*stride]= 0; + + do{ + mb_type= get_vlc2(&s->gb, h263_mbtype_b_vlc.table, H263_MBTYPE_B_VLC_BITS, 2); + if (mb_type < 0){ + av_log(s->avctx, AV_LOG_ERROR, "b mb_type damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + mb_type= h263_mb_type_b_map[ mb_type ]; + }while(!mb_type); + + s->mb_intra = IS_INTRA(mb_type); + if(HAS_CBP(mb_type)){ + s->dsp.clear_blocks(s->block[0]); + cbpc = get_vlc2(&s->gb, cbpc_b_vlc.table, CBPC_B_VLC_BITS, 1); + if(s->mb_intra){ + dquant = IS_QUANT(mb_type); + goto intra; + } + + cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); + + if (cbpy < 0){ + av_log(s->avctx, AV_LOG_ERROR, "b cbpy damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + if(s->alt_inter_vlc==0 || (cbpc & 3)!=3) + cbpy ^= 0xF; + + cbp = (cbpc & 3) | (cbpy << 2); + }else + cbp=0; + + assert(!s->mb_intra); + + if(IS_QUANT(mb_type)){ + h263_decode_dquant(s); + } + + if(IS_DIRECT(mb_type)){ + s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; + mb_type |= ff_mpeg4_set_direct_mv(s, 0, 0); + }else{ + s->mv_dir = 0; + s->mv_type= MV_TYPE_16X16; +//FIXME UMV + + if(USES_LIST(mb_type, 0)){ + int16_t *mot_val= h263_pred_motion(s, 0, 0, &mx, &my); + s->mv_dir = MV_DIR_FORWARD; + + mx = h263_decode_motion(s, mx, 1); + my = h263_decode_motion(s, my, 1); + + s->mv[0][0][0] = mx; + s->mv[0][0][1] = my; + mot_val[0 ]= mot_val[2 ]= mot_val[0+2*stride]= mot_val[2+2*stride]= mx; + mot_val[1 ]= mot_val[3 ]= mot_val[1+2*stride]= mot_val[3+2*stride]= my; + } + + if(USES_LIST(mb_type, 1)){ + int16_t *mot_val= h263_pred_motion(s, 0, 1, &mx, &my); + s->mv_dir |= MV_DIR_BACKWARD; + + mx = h263_decode_motion(s, mx, 1); + my = h263_decode_motion(s, my, 1); + + s->mv[1][0][0] = mx; + s->mv[1][0][1] = my; + mot_val[0 ]= mot_val[2 ]= mot_val[0+2*stride]= mot_val[2+2*stride]= mx; + mot_val[1 ]= mot_val[3 ]= mot_val[1+2*stride]= mot_val[3+2*stride]= my; + } + } + + s->current_picture.mb_type[xy]= mb_type; + + /* decode each block */ + for (i = 0; i < 6; i++) { + if (h263_decode_block(s, block[i], i, cbp&32) < 0) + return -1; + cbp+=cbp; + } + } else { /* I-Frame */ + do{ + cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); + if (cbpc < 0){ + av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + }while(cbpc == 8); + + s->dsp.clear_blocks(s->block[0]); + + dquant = cbpc & 4; + s->mb_intra = 1; +intra: + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + if (s->h263_aic) { + s->ac_pred = get_bits1(&s->gb); + if(s->ac_pred){ + s->current_picture.mb_type[xy]= MB_TYPE_INTRA | MB_TYPE_ACPRED; + + s->h263_aic_dir = get_bits1(&s->gb); + } + }else + s->ac_pred = 0; + + cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); + if(cbpy<0){ + av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + cbp = (cbpc & 3) | (cbpy << 2); + if (dquant) { + h263_decode_dquant(s); + } + + /* decode each block */ + for (i = 0; i < 6; i++) { + if (h263_decode_block(s, block[i], i, cbp&32) < 0) + return -1; + cbp+=cbp; + } + } +end: + + /* per-MB end of slice check */ + { + int v= show_bits(&s->gb, 16); + + if(get_bits_count(&s->gb) + 16 > s->gb.size_in_bits){ + v>>= get_bits_count(&s->gb) + 16 - s->gb.size_in_bits; + } + + if(v==0) + return SLICE_END; + } + + return SLICE_OK; +} + +int ff_mpeg4_decode_mb(MpegEncContext *s, + DCTELEM block[6][64]) +{ + int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; + int16_t *mot_val; + static int8_t quant_tab[4] = { -1, -2, 1, 2 }; + const int xy= s->mb_x + s->mb_y * s->mb_stride; + + assert(s->h263_pred); + + if (s->pict_type == P_TYPE || s->pict_type==S_TYPE) { + do{ + if (get_bits1(&s->gb)) { + /* skip mb */ + s->mb_intra = 0; + for(i=0;i<6;i++) + s->block_last_index[i] = -1; + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE){ + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; + s->mcsel=1; + s->mv[0][0][0]= get_amv(s, 0); + s->mv[0][0][1]= get_amv(s, 1); + + s->mb_skipped = 0; + }else{ + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + s->mcsel=0; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mb_skipped = 1; + } + goto end; + } + cbpc = get_vlc2(&s->gb, inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); + //fprintf(stderr, "\tCBPC: %d", cbpc); + if (cbpc < 0){ + av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + }while(cbpc == 20); + + s->dsp.clear_blocks(s->block[0]); + dquant = cbpc & 8; + s->mb_intra = ((cbpc & 4) != 0); + if (s->mb_intra) goto intra; + + if(s->pict_type==S_TYPE && s->vol_sprite_usage==GMC_SPRITE && (cbpc & 16) == 0) + s->mcsel= get_bits1(&s->gb); + else s->mcsel= 0; + cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1) ^ 0x0F; + + cbp = (cbpc & 3) | (cbpy << 2); + if (dquant) { + ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); + } + if((!s->progressive_sequence) && (cbp || (s->workaround_bugs&FF_BUG_XVID_ILACE))) + s->interlaced_dct= get_bits1(&s->gb); + + s->mv_dir = MV_DIR_FORWARD; + if ((cbpc & 16) == 0) { + if(s->mcsel){ + s->current_picture.mb_type[xy]= MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0; + /* 16x16 global motion prediction */ + s->mv_type = MV_TYPE_16X16; + mx= get_amv(s, 0); + my= get_amv(s, 1); + s->mv[0][0][0] = mx; + s->mv[0][0][1] = my; + }else if((!s->progressive_sequence) && get_bits1(&s->gb)){ + s->current_picture.mb_type[xy]= MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED; + /* 16x8 field motion prediction */ + s->mv_type= MV_TYPE_FIELD; + + s->field_select[0][0]= get_bits1(&s->gb); + s->field_select[0][1]= get_bits1(&s->gb); + + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + + for(i=0; i<2; i++){ + mx = h263_decode_motion(s, pred_x, s->f_code); + if (mx >= 0xffff) + return -1; + + my = h263_decode_motion(s, pred_y/2, s->f_code); + if (my >= 0xffff) + return -1; + + s->mv[0][i][0] = mx; + s->mv[0][i][1] = my; + } + }else{ + s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; + /* 16x16 motion prediction */ + s->mv_type = MV_TYPE_16X16; + h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + mx = h263_decode_motion(s, pred_x, s->f_code); + + if (mx >= 0xffff) + return -1; + + my = h263_decode_motion(s, pred_y, s->f_code); + + if (my >= 0xffff) + return -1; + s->mv[0][0][0] = mx; + s->mv[0][0][1] = my; + } + } else { + s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; + s->mv_type = MV_TYPE_8X8; + for(i=0;i<4;i++) { + mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mx = h263_decode_motion(s, pred_x, s->f_code); + if (mx >= 0xffff) + return -1; + + my = h263_decode_motion(s, pred_y, s->f_code); + if (my >= 0xffff) + return -1; + s->mv[0][i][0] = mx; + s->mv[0][i][1] = my; + mot_val[0] = mx; + mot_val[1] = my; + } + } + } else if(s->pict_type==B_TYPE) { + int modb1; // first bit of modb + int modb2; // second bit of modb + int mb_type; + + s->mb_intra = 0; //B-frames never contain intra blocks + s->mcsel=0; // ... true gmc blocks + + if(s->mb_x==0){ + for(i=0; i<2; i++){ + s->last_mv[i][0][0]= + s->last_mv[i][0][1]= + s->last_mv[i][1][0]= + s->last_mv[i][1][1]= 0; + } + } + + /* if we skipped it in the future P Frame than skip it now too */ + s->mb_skipped= s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC + + if(s->mb_skipped){ + /* skip mb */ + for(i=0;i<6;i++) + s->block_last_index[i] = -1; + + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; + s->mv[0][0][0] = 0; + s->mv[0][0][1] = 0; + s->mv[1][0][0] = 0; + s->mv[1][0][1] = 0; + s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0; + goto end; + } + + modb1= get_bits1(&s->gb); + if(modb1){ + mb_type= MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1; //like MB_TYPE_B_DIRECT but no vectors coded + cbp=0; + }else{ + modb2= get_bits1(&s->gb); + mb_type= get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1); + if(mb_type<0){ + av_log(s->avctx, AV_LOG_ERROR, "illegal MB_type\n"); + return -1; + } + mb_type= mb_type_b_map[ mb_type ]; + if(modb2) cbp= 0; + else{ + s->dsp.clear_blocks(s->block[0]); + cbp= get_bits(&s->gb, 6); + } + + if ((!IS_DIRECT(mb_type)) && cbp) { + if(get_bits1(&s->gb)){ + ff_set_qscale(s, s->qscale + get_bits1(&s->gb)*4 - 2); + } + } + + if(!s->progressive_sequence){ + if(cbp) + s->interlaced_dct= get_bits1(&s->gb); + + if(!IS_DIRECT(mb_type) && get_bits1(&s->gb)){ + mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED; + mb_type &= ~MB_TYPE_16x16; + + if(USES_LIST(mb_type, 0)){ + s->field_select[0][0]= get_bits1(&s->gb); + s->field_select[0][1]= get_bits1(&s->gb); + } + if(USES_LIST(mb_type, 1)){ + s->field_select[1][0]= get_bits1(&s->gb); + s->field_select[1][1]= get_bits1(&s->gb); + } + } + } + + s->mv_dir = 0; + if((mb_type & (MB_TYPE_DIRECT2|MB_TYPE_INTERLACED)) == 0){ + s->mv_type= MV_TYPE_16X16; + + if(USES_LIST(mb_type, 0)){ + s->mv_dir = MV_DIR_FORWARD; + + mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); + my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); + s->last_mv[0][1][0]= s->last_mv[0][0][0]= s->mv[0][0][0] = mx; + s->last_mv[0][1][1]= s->last_mv[0][0][1]= s->mv[0][0][1] = my; + } + + if(USES_LIST(mb_type, 1)){ + s->mv_dir |= MV_DIR_BACKWARD; + + mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); + my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); + s->last_mv[1][1][0]= s->last_mv[1][0][0]= s->mv[1][0][0] = mx; + s->last_mv[1][1][1]= s->last_mv[1][0][1]= s->mv[1][0][1] = my; + } + }else if(!IS_DIRECT(mb_type)){ + s->mv_type= MV_TYPE_FIELD; + + if(USES_LIST(mb_type, 0)){ + s->mv_dir = MV_DIR_FORWARD; + + for(i=0; i<2; i++){ + mx = h263_decode_motion(s, s->last_mv[0][i][0] , s->f_code); + my = h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code); + s->last_mv[0][i][0]= s->mv[0][i][0] = mx; + s->last_mv[0][i][1]= (s->mv[0][i][1] = my)*2; + } + } + + if(USES_LIST(mb_type, 1)){ + s->mv_dir |= MV_DIR_BACKWARD; + + for(i=0; i<2; i++){ + mx = h263_decode_motion(s, s->last_mv[1][i][0] , s->b_code); + my = h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code); + s->last_mv[1][i][0]= s->mv[1][i][0] = mx; + s->last_mv[1][i][1]= (s->mv[1][i][1] = my)*2; + } + } + } + } + + if(IS_DIRECT(mb_type)){ + if(IS_SKIP(mb_type)) + mx=my=0; + else{ + mx = h263_decode_motion(s, 0, 1); + my = h263_decode_motion(s, 0, 1); + } + + s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; + mb_type |= ff_mpeg4_set_direct_mv(s, mx, my); + } + s->current_picture.mb_type[xy]= mb_type; + } else { /* I-Frame */ + do{ + cbpc = get_vlc2(&s->gb, intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); + if (cbpc < 0){ + av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + }while(cbpc == 8); + + dquant = cbpc & 4; + s->mb_intra = 1; +intra: + s->ac_pred = get_bits1(&s->gb); + if(s->ac_pred) + s->current_picture.mb_type[xy]= MB_TYPE_INTRA | MB_TYPE_ACPRED; + else + s->current_picture.mb_type[xy]= MB_TYPE_INTRA; + + cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); + if(cbpy<0){ + av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + cbp = (cbpc & 3) | (cbpy << 2); + if (dquant) { + ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]); + } + + if(!s->progressive_sequence) + s->interlaced_dct= get_bits1(&s->gb); + + s->dsp.clear_blocks(s->block[0]); + /* decode each block */ + for (i = 0; i < 6; i++) { + if (mpeg4_decode_block(s, block[i], i, cbp&32, 1, 0) < 0) + return -1; + cbp+=cbp; + } + goto end; + } + + /* decode each block */ + for (i = 0; i < 6; i++) { + if (mpeg4_decode_block(s, block[i], i, cbp&32, 0, 0) < 0) + return -1; + cbp+=cbp; + } +end: + + /* per-MB end of slice check */ + if(s->codec_id==CODEC_ID_MPEG4){ + if(mpeg4_is_resync(s)){ + const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; + if(s->pict_type==B_TYPE && s->next_picture.mbskip_table[xy + delta]) + return SLICE_OK; + return SLICE_END; + } + } + + return SLICE_OK; +} + +static int h263_decode_motion(MpegEncContext * s, int pred, int f_code) +{ + int code, val, sign, shift, l; + code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); + + if (code == 0) + return pred; + if (code < 0) + return 0xffff; + + sign = get_bits1(&s->gb); + shift = f_code - 1; + val = code; + if (shift) { + val = (val - 1) << shift; + val |= get_bits(&s->gb, shift); + val++; + } + if (sign) + val = -val; + val += pred; + + /* modulo decoding */ + if (!s->h263_long_vectors) { + l = INT_BIT - 5 - f_code; + val = (val<>l; + } else { + /* horrible h263 long vector mode */ + if (pred < -31 && val < -63) + val += 64; + if (pred > 32 && val > 63) + val -= 64; + + } + return val; +} + +/* Decodes RVLC of H.263+ UMV */ +static int h263p_decode_umotion(MpegEncContext * s, int pred) +{ + int code = 0, sign; + + if (get_bits1(&s->gb)) /* Motion difference = 0 */ + return pred; + + code = 2 + get_bits1(&s->gb); + + while (get_bits1(&s->gb)) + { + code <<= 1; + code += get_bits1(&s->gb); + } + sign = code & 1; + code >>= 1; + + code = (sign) ? (pred - code) : (pred + code); +#ifdef DEBUG + av_log( s->avctx, AV_LOG_DEBUG,"H.263+ UMV Motion = %d\n", code); +#endif + return code; + +} + +static int h263_decode_block(MpegEncContext * s, DCTELEM * block, + int n, int coded) +{ + int code, level, i, j, last, run; + RLTable *rl = &rl_inter; + const uint8_t *scan_table; + GetBitContext gb= s->gb; + + scan_table = s->intra_scantable.permutated; + if (s->h263_aic && s->mb_intra) { + rl = &rl_intra_aic; + i = 0; + if (s->ac_pred) { + if (s->h263_aic_dir) + scan_table = s->intra_v_scantable.permutated; /* left */ + else + scan_table = s->intra_h_scantable.permutated; /* top */ + } + } else if (s->mb_intra) { + /* DC coef */ + if(s->codec_id == CODEC_ID_RV10){ +#ifdef CONFIG_RV10_DECODER + if (s->rv10_version == 3 && s->pict_type == I_TYPE) { + int component, diff; + component = (n <= 3 ? 0 : n - 4 + 1); + level = s->last_dc[component]; + if (s->rv10_first_dc_coded[component]) { + diff = rv_decode_dc(s, n); + if (diff == 0xffff) + return -1; + level += diff; + level = level & 0xff; /* handle wrap round */ + s->last_dc[component] = level; + } else { + s->rv10_first_dc_coded[component] = 1; + } + } else { + level = get_bits(&s->gb, 8); + if (level == 255) + level = 128; + } +#endif + }else{ + level = get_bits(&s->gb, 8); + if((level&0x7F) == 0){ + av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y); + if(s->error_resilience >= FF_ER_COMPLIANT) + return -1; + } + if (level == 255) + level = 128; + } + block[0] = level; + i = 1; + } else { + i = 0; + } + if (!coded) { + if (s->mb_intra && s->h263_aic) + goto not_coded; + s->block_last_index[n] = i - 1; + return 0; + } +retry: + for(;;) { + code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2); + if (code < 0){ + av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y); + return -1; + } + if (code == rl->n) { + /* escape */ + if (s->h263_flv > 1) { + int is11 = get_bits1(&s->gb); + last = get_bits1(&s->gb); + run = get_bits(&s->gb, 6); + if(is11){ + level = get_sbits(&s->gb, 11); + } else { + level = get_sbits(&s->gb, 7); + } + } else { + last = get_bits1(&s->gb); + run = get_bits(&s->gb, 6); + level = (int8_t)get_bits(&s->gb, 8); + if(level == -128){ + if (s->codec_id == CODEC_ID_RV10) { + /* XXX: should patch encoder too */ + level = get_sbits(&s->gb, 12); + }else{ + level = get_bits(&s->gb, 5); + level |= get_sbits(&s->gb, 6)<<5; + } + } + } + } else { + run = rl->table_run[code]; + level = rl->table_level[code]; + last = code >= rl->last; + if (get_bits1(&s->gb)) + level = -level; + } + i += run; + if (i >= 64){ + if(s->alt_inter_vlc && rl == &rl_inter && !s->mb_intra){ + //looks like a hack but no, it's the way its supposed to work ... + rl = &rl_intra_aic; + i = 0; + s->gb= gb; + memset(block, 0, sizeof(DCTELEM)*64); + goto retry; + } + av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d i:%d\n", s->mb_x, s->mb_y, s->mb_intra); + return -1; + } + j = scan_table[i]; + block[j] = level; + if (last) + break; + i++; + } +not_coded: + if (s->mb_intra && s->h263_aic) { + h263_pred_acdc(s, block, n); + i = 63; + } + s->block_last_index[n] = i; + return 0; +} + +/** + * decodes the dc value. + * @param n block index (0-3 are luma, 4-5 are chroma) + * @param dir_ptr the prediction direction will be stored here + * @return the quantized dc + */ +static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) +{ + int level, code; + + if (n < 4) + code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1); + else + code = get_vlc2(&s->gb, dc_chrom.table, DC_VLC_BITS, 1); + if (code < 0 || code > 9 /* && s->nbit<9 */){ + av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n"); + return -1; + } + if (code == 0) { + level = 0; + } else { + if(IS_3IV1){ + if(code==1) + level= 2*get_bits1(&s->gb)-1; + else{ + if(get_bits1(&s->gb)) + level = get_bits(&s->gb, code-1) + (1<<(code-1)); + else + level = -get_bits(&s->gb, code-1) - (1<<(code-1)); + } + }else{ + level = get_xbits(&s->gb, code); + } + + if (code > 8){ + if(get_bits1(&s->gb)==0){ /* marker */ + if(s->error_resilience>=2){ + av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n"); + return -1; + } + } + } + } + + return ff_mpeg4_pred_dc(s, n, level, dir_ptr, 0); +} + +/** + * decodes a block. + * @return <0 if an error occured + */ +static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, + int n, int coded, int intra, int rvlc) +{ + int level, i, last, run; + int dc_pred_dir; + RLTable * rl; + RL_VLC_ELEM * rl_vlc; + const uint8_t * scan_table; + int qmul, qadd; + + //Note intra & rvlc should be optimized away if this is inlined + + if(intra) { + if(s->qscale < s->intra_dc_threshold){ + /* DC coef */ + if(s->partitioned_frame){ + level = s->dc_val[0][ s->block_index[n] ]; + if(n<4) level= FASTDIV((level + (s->y_dc_scale>>1)), s->y_dc_scale); + else level= FASTDIV((level + (s->c_dc_scale>>1)), s->c_dc_scale); + dc_pred_dir= (s->pred_dir_table[s->mb_x + s->mb_y*s->mb_stride]<ac_pred) { + if (dc_pred_dir == 0) + scan_table = s->intra_v_scantable.permutated; /* left */ + else + scan_table = s->intra_h_scantable.permutated; /* top */ + } else { + scan_table = s->intra_scantable.permutated; + } + qmul=1; + qadd=0; + } else { + i = -1; + if (!coded) { + s->block_last_index[n] = i; + return 0; + } + if(rvlc) rl = &rvlc_rl_inter; + else rl = &rl_inter; + + scan_table = s->intra_scantable.permutated; + + if(s->mpeg_quant){ + qmul=1; + qadd=0; + if(rvlc){ + rl_vlc = rvlc_rl_inter.rl_vlc[0]; + }else{ + rl_vlc = rl_inter.rl_vlc[0]; + } + }else{ + qmul = s->qscale << 1; + qadd = (s->qscale - 1) | 1; + if(rvlc){ + rl_vlc = rvlc_rl_inter.rl_vlc[s->qscale]; + }else{ + rl_vlc = rl_inter.rl_vlc[s->qscale]; + } + } + } + { + OPEN_READER(re, &s->gb); + for(;;) { + UPDATE_CACHE(re, &s->gb); + GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0); + if (level==0) { + /* escape */ + if(rvlc){ + if(SHOW_UBITS(re, &s->gb, 1)==0){ + av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in rvlc esc\n"); + return -1; + }; SKIP_CACHE(re, &s->gb, 1); + + last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); + run= SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6); + SKIP_COUNTER(re, &s->gb, 1+1+6); + UPDATE_CACHE(re, &s->gb); + + if(SHOW_UBITS(re, &s->gb, 1)==0){ + av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in rvlc esc\n"); + return -1; + }; SKIP_CACHE(re, &s->gb, 1); + + level= SHOW_UBITS(re, &s->gb, 11); SKIP_CACHE(re, &s->gb, 11); + + if(SHOW_UBITS(re, &s->gb, 5)!=0x10){ + av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n"); + return -1; + }; SKIP_CACHE(re, &s->gb, 5); + + level= level * qmul + qadd; + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_CACHE(re, &s->gb, 1); + SKIP_COUNTER(re, &s->gb, 1+11+5+1); + + i+= run + 1; + if(last) i+=192; + }else{ + int cache; + cache= GET_CACHE(re, &s->gb); + + if(IS_3IV1) + cache ^= 0xC0000000; + + if (cache&0x80000000) { + if (cache&0x40000000) { + /* third escape */ + SKIP_CACHE(re, &s->gb, 2); + last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); + run= SHOW_UBITS(re, &s->gb, 6); LAST_SKIP_CACHE(re, &s->gb, 6); + SKIP_COUNTER(re, &s->gb, 2+1+6); + UPDATE_CACHE(re, &s->gb); + + if(IS_3IV1){ + level= SHOW_SBITS(re, &s->gb, 12); LAST_SKIP_BITS(re, &s->gb, 12); + }else{ + if(SHOW_UBITS(re, &s->gb, 1)==0){ + av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in 3. esc\n"); + return -1; + }; SKIP_CACHE(re, &s->gb, 1); + + level= SHOW_SBITS(re, &s->gb, 12); SKIP_CACHE(re, &s->gb, 12); + + if(SHOW_UBITS(re, &s->gb, 1)==0){ + av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in 3. esc\n"); + return -1; + }; LAST_SKIP_CACHE(re, &s->gb, 1); + + SKIP_COUNTER(re, &s->gb, 1+12+1); + } + +#if 0 + if(s->error_resilience >= FF_ER_COMPLIANT){ + const int abs_level= ABS(level); + if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ + const int run1= run - rl->max_run[last][abs_level] - 1; + if(abs_level <= rl->max_level[last][run]){ + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); + return -1; + } + if(s->error_resilience > FF_ER_COMPLIANT){ + if(abs_level <= rl->max_level[last][run]*2){ + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n"); + return -1; + } + if(run1 >= 0 && abs_level <= rl->max_level[last][run1]){ + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n"); + return -1; + } + } + } + } +#endif + if (level>0) level= level * qmul + qadd; + else level= level * qmul - qadd; + + if((unsigned)(level + 2048) > 4095){ + if(s->error_resilience > FF_ER_COMPLIANT){ + if(level > 2560 || level<-2560){ + av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale); + return -1; + } + } + level= level<0 ? -2048 : 2047; + } + + i+= run + 1; + if(last) i+=192; + } else { + /* second escape */ +#if MIN_CACHE_BITS < 20 + LAST_SKIP_BITS(re, &s->gb, 2); + UPDATE_CACHE(re, &s->gb); +#else + SKIP_BITS(re, &s->gb, 2); +#endif + GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); + i+= run + rl->max_run[run>>7][level/qmul] +1; //FIXME opt indexing + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); + } + } else { + /* first escape */ +#if MIN_CACHE_BITS < 19 + LAST_SKIP_BITS(re, &s->gb, 1); + UPDATE_CACHE(re, &s->gb); +#else + SKIP_BITS(re, &s->gb, 1); +#endif + GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1); + i+= run; + level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); + } + } + } else { + i+= run; + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); + } + if (i > 62){ + i-= 192; + if(i&(~63)){ + av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + block[scan_table[i]] = level; + break; + } + + block[scan_table[i]] = level; + } + CLOSE_READER(re, &s->gb); + } + not_coded: + if (intra) { + if(s->qscale >= s->intra_dc_threshold){ + block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0); + + i -= i>>31; //if(i == -1) i=0; + } + + mpeg4_pred_ac(s, block, n, dc_pred_dir); + if (s->ac_pred) { + i = 63; /* XXX: not optimal */ + } + } + s->block_last_index[n] = i; + return 0; +} + +/* most is hardcoded. should extend to handle all h263 streams */ +int h263_decode_picture_header(MpegEncContext *s) +{ + int format, width, height, i; + uint32_t startcode; + + align_get_bits(&s->gb); + + startcode= get_bits(&s->gb, 22-8); + + for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>24; i-=8) { + startcode = ((startcode << 8) | get_bits(&s->gb, 8)) & 0x003FFFFF; + + if(startcode == 0x20) + break; + } + + if (startcode != 0x20) { + av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n"); + return -1; + } + /* temporal reference */ + i = get_bits(&s->gb, 8); /* picture timestamp */ + if( (s->picture_number&~0xFF)+i < s->picture_number) + i+= 256; + s->current_picture_ptr->pts= + s->picture_number= (s->picture_number&~0xFF) + i; + + /* PTYPE starts here */ + if (get_bits1(&s->gb) != 1) { + /* marker */ + av_log(s->avctx, AV_LOG_ERROR, "Bad marker\n"); + return -1; + } + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "Bad H263 id\n"); + return -1; /* h263 id */ + } + skip_bits1(&s->gb); /* split screen off */ + skip_bits1(&s->gb); /* camera off */ + skip_bits1(&s->gb); /* freeze picture release off */ + + format = get_bits(&s->gb, 3); + /* + 0 forbidden + 1 sub-QCIF + 10 QCIF + 7 extended PTYPE (PLUSPTYPE) + */ + + if (format != 7 && format != 6) { + s->h263_plus = 0; + /* H.263v1 */ + width = h263_format[format][0]; + height = h263_format[format][1]; + if (!width) + return -1; + + s->pict_type = I_TYPE + get_bits1(&s->gb); + + s->h263_long_vectors = get_bits1(&s->gb); + + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "H263 SAC not supported\n"); + return -1; /* SAC: off */ + } + s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */ + s->unrestricted_mv = s->h263_long_vectors || s->obmc; + + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "H263 PB frame not supported\n"); + return -1; /* not PB frame */ + } + s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); + skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ + + s->width = width; + s->height = height; + s->avctx->sample_aspect_ratio= (AVRational){12,11}; + s->avctx->time_base= (AVRational){1001, 30000}; + } else { + int ufep; + + /* H.263v2 */ + s->h263_plus = 1; + ufep = get_bits(&s->gb, 3); /* Update Full Extended PTYPE */ + + /* ufep other than 0 and 1 are reserved */ + if (ufep == 1) { + /* OPPTYPE */ + format = get_bits(&s->gb, 3); + dprintf("ufep=1, format: %d\n", format); + s->custom_pcf= get_bits1(&s->gb); + s->umvplus = get_bits(&s->gb, 1); /* Unrestricted Motion Vector */ + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "Syntax-based Arithmetic Coding (SAC) not supported\n"); + } + s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */ + s->h263_aic = get_bits1(&s->gb); /* Advanced Intra Coding (AIC) */ + s->loop_filter= get_bits1(&s->gb); + s->unrestricted_mv = s->umvplus || s->obmc || s->loop_filter; + + s->h263_slice_structured= get_bits1(&s->gb); + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "Reference Picture Selection not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "Independent Segment Decoding not supported\n"); + } + s->alt_inter_vlc= get_bits1(&s->gb); + s->modified_quant= get_bits1(&s->gb); + if(s->modified_quant) + s->chroma_qscale_table= ff_h263_chroma_qscale_table; + + skip_bits(&s->gb, 1); /* Prevent start code emulation */ + + skip_bits(&s->gb, 3); /* Reserved */ + } else if (ufep != 0) { + av_log(s->avctx, AV_LOG_ERROR, "Bad UFEP type (%d)\n", ufep); + return -1; + } + + /* MPPTYPE */ + s->pict_type = get_bits(&s->gb, 3); + switch(s->pict_type){ + case 0: s->pict_type= I_TYPE;break; + case 1: s->pict_type= P_TYPE;break; + case 3: s->pict_type= B_TYPE;break; + case 7: s->pict_type= I_TYPE;break; //ZYGO + default: + return -1; + } + skip_bits(&s->gb, 2); + s->no_rounding = get_bits1(&s->gb); + skip_bits(&s->gb, 4); + + /* Get the picture dimensions */ + if (ufep) { + if (format == 6) { + /* Custom Picture Format (CPFMT) */ + s->aspect_ratio_info = get_bits(&s->gb, 4); + dprintf("aspect: %d\n", s->aspect_ratio_info); + /* aspect ratios: + 0 - forbidden + 1 - 1:1 + 2 - 12:11 (CIF 4:3) + 3 - 10:11 (525-type 4:3) + 4 - 16:11 (CIF 16:9) + 5 - 40:33 (525-type 16:9) + 6-14 - reserved + */ + width = (get_bits(&s->gb, 9) + 1) * 4; + skip_bits1(&s->gb); + height = get_bits(&s->gb, 9) * 4; + dprintf("\nH.263+ Custom picture: %dx%d\n",width,height); + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) { + /* aspected dimensions */ + s->avctx->sample_aspect_ratio.num= get_bits(&s->gb, 8); + s->avctx->sample_aspect_ratio.den= get_bits(&s->gb, 8); + }else{ + s->avctx->sample_aspect_ratio= pixel_aspect[s->aspect_ratio_info]; + } + } else { + width = h263_format[format][0]; + height = h263_format[format][1]; + s->avctx->sample_aspect_ratio= (AVRational){12,11}; + } + if ((width == 0) || (height == 0)) + return -1; + s->width = width; + s->height = height; + + if(s->custom_pcf){ + int gcd; + s->avctx->time_base.den= 1800000; + s->avctx->time_base.num= 1000 + get_bits1(&s->gb); + s->avctx->time_base.num*= get_bits(&s->gb, 7); + if(s->avctx->time_base.num == 0){ + av_log(s, AV_LOG_ERROR, "zero framerate\n"); + return -1; + } + gcd= ff_gcd(s->avctx->time_base.den, s->avctx->time_base.num); + s->avctx->time_base.den /= gcd; + s->avctx->time_base.num /= gcd; +// av_log(s->avctx, AV_LOG_DEBUG, "%d/%d\n", s->avctx->time_base.den, s->avctx->time_base.num); + }else{ + s->avctx->time_base= (AVRational){1001, 30000}; + } + } + + if(s->custom_pcf){ + skip_bits(&s->gb, 2); //extended Temporal reference + } + + if (ufep) { + if (s->umvplus) { + if(get_bits1(&s->gb)==0) /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ + skip_bits1(&s->gb); + } + if(s->h263_slice_structured){ + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "rectangular slices not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "unordered slices not supported\n"); + } + } + } + + s->qscale = get_bits(&s->gb, 5); + } + + s->mb_width = (s->width + 15) / 16; + s->mb_height = (s->height + 15) / 16; + s->mb_num = s->mb_width * s->mb_height; + + /* PEI */ + while (get_bits1(&s->gb) != 0) { + skip_bits(&s->gb, 8); + } + + if(s->h263_slice_structured){ + if (get_bits1(&s->gb) != 1) { + av_log(s->avctx, AV_LOG_ERROR, "SEPB1 marker missing\n"); + return -1; + } + + ff_h263_decode_mba(s); + + if (get_bits1(&s->gb) != 1) { + av_log(s->avctx, AV_LOG_ERROR, "SEPB2 marker missing\n"); + return -1; + } + } + s->f_code = 1; + + if(s->h263_aic){ + s->y_dc_scale_table= + s->c_dc_scale_table= ff_aic_dc_scale_table; + }else{ + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + } + + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s %d/%d\n", + s->qscale, av_get_pict_type_char(s->pict_type), + s->gb.size_in_bits, 1-s->no_rounding, + s->obmc ? " AP" : "", + s->umvplus ? " UMV" : "", + s->h263_long_vectors ? " LONG" : "", + s->h263_plus ? " +" : "", + s->h263_aic ? " AIC" : "", + s->alt_inter_vlc ? " AIV" : "", + s->modified_quant ? " MQ" : "", + s->loop_filter ? " LOOP" : "", + s->h263_slice_structured ? " SS" : "", + s->avctx->time_base.den, s->avctx->time_base.num + ); + } +#if 1 + if (s->pict_type == I_TYPE && s->avctx->codec_tag == ff_get_fourcc("ZYGO")){ + int i,j; + for(i=0; i<85; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb)); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + for(i=0; i<13; i++){ + for(j=0; j<3; j++){ + int v= get_bits(&s->gb, 8); + v |= get_sbits(&s->gb, 8)<<8; + av_log(s->avctx, AV_LOG_DEBUG, " %5d", v); + } + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } + for(i=0; i<50; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb)); + } +#endif + + return 0; +} + +static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb) +{ + int i; + int a= 2<sprite_warping_accuracy; + int rho= 3-s->sprite_warping_accuracy; + int r=16/a; + const int vop_ref[4][2]= {{0,0}, {s->width,0}, {0, s->height}, {s->width, s->height}}; // only true for rectangle shapes + int d[4][2]={{0,0}, {0,0}, {0,0}, {0,0}}; + int sprite_ref[4][2]; + int virtual_ref[2][2]; + int w2, h2, w3, h3; + int alpha=0, beta=0; + int w= s->width; + int h= s->height; + int min_ab; + + for(i=0; inum_sprite_warping_points; i++){ + int length; + int x=0, y=0; + + length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); + if(length){ + x= get_xbits(gb, length); + } + if(!(s->divx_version==500 && s->divx_build==413)) skip_bits1(gb); /* marker bit */ + + length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); + if(length){ + y=get_xbits(gb, length); + } + skip_bits1(gb); /* marker bit */ +//printf("%d %d %d %d\n", x, y, i, s->sprite_warping_accuracy); + d[i][0]= x; + d[i][1]= y; + } + + while((1<divx_version==500 && s->divx_build==413){ + sprite_ref[0][0]= a*vop_ref[0][0] + d[0][0]; + sprite_ref[0][1]= a*vop_ref[0][1] + d[0][1]; + sprite_ref[1][0]= a*vop_ref[1][0] + d[0][0] + d[1][0]; + sprite_ref[1][1]= a*vop_ref[1][1] + d[0][1] + d[1][1]; + sprite_ref[2][0]= a*vop_ref[2][0] + d[0][0] + d[2][0]; + sprite_ref[2][1]= a*vop_ref[2][1] + d[0][1] + d[2][1]; + } else { + sprite_ref[0][0]= (a>>1)*(2*vop_ref[0][0] + d[0][0]); + sprite_ref[0][1]= (a>>1)*(2*vop_ref[0][1] + d[0][1]); + sprite_ref[1][0]= (a>>1)*(2*vop_ref[1][0] + d[0][0] + d[1][0]); + sprite_ref[1][1]= (a>>1)*(2*vop_ref[1][1] + d[0][1] + d[1][1]); + sprite_ref[2][0]= (a>>1)*(2*vop_ref[2][0] + d[0][0] + d[2][0]); + sprite_ref[2][1]= (a>>1)*(2*vop_ref[2][1] + d[0][1] + d[2][1]); + } +/* sprite_ref[3][0]= (a>>1)*(2*vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]); + sprite_ref[3][1]= (a>>1)*(2*vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */ + +// this is mostly identical to the mpeg4 std (and is totally unreadable because of that ...) +// perhaps it should be reordered to be more readable ... +// the idea behind this virtual_ref mess is to be able to use shifts later per pixel instead of divides +// so the distance between points is converted from w&h based to w2&h2 based which are of the 2^x form + virtual_ref[0][0]= 16*(vop_ref[0][0] + w2) + + ROUNDED_DIV(((w - w2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + w2*(r*sprite_ref[1][0] - 16*vop_ref[1][0])),w); + virtual_ref[0][1]= 16*vop_ref[0][1] + + ROUNDED_DIV(((w - w2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + w2*(r*sprite_ref[1][1] - 16*vop_ref[1][1])),w); + virtual_ref[1][0]= 16*vop_ref[0][0] + + ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][0] - 16*vop_ref[0][0]) + h2*(r*sprite_ref[2][0] - 16*vop_ref[2][0])),h); + virtual_ref[1][1]= 16*(vop_ref[0][1] + h2) + + ROUNDED_DIV(((h - h2)*(r*sprite_ref[0][1] - 16*vop_ref[0][1]) + h2*(r*sprite_ref[2][1] - 16*vop_ref[2][1])),h); + + switch(s->num_sprite_warping_points) + { + case 0: + s->sprite_offset[0][0]= 0; + s->sprite_offset[0][1]= 0; + s->sprite_offset[1][0]= 0; + s->sprite_offset[1][1]= 0; + s->sprite_delta[0][0]= a; + s->sprite_delta[0][1]= 0; + s->sprite_delta[1][0]= 0; + s->sprite_delta[1][1]= a; + s->sprite_shift[0]= 0; + s->sprite_shift[1]= 0; + break; + case 1: //GMC only + s->sprite_offset[0][0]= sprite_ref[0][0] - a*vop_ref[0][0]; + s->sprite_offset[0][1]= sprite_ref[0][1] - a*vop_ref[0][1]; + s->sprite_offset[1][0]= ((sprite_ref[0][0]>>1)|(sprite_ref[0][0]&1)) - a*(vop_ref[0][0]/2); + s->sprite_offset[1][1]= ((sprite_ref[0][1]>>1)|(sprite_ref[0][1]&1)) - a*(vop_ref[0][1]/2); + s->sprite_delta[0][0]= a; + s->sprite_delta[0][1]= 0; + s->sprite_delta[1][0]= 0; + s->sprite_delta[1][1]= a; + s->sprite_shift[0]= 0; + s->sprite_shift[1]= 0; + break; + case 2: + s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+rho)) + + (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][0]) + + ( r*sprite_ref[0][1] - virtual_ref[0][1])*(-vop_ref[0][1]) + + (1<<(alpha+rho-1)); + s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+rho)) + + (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-vop_ref[0][0]) + + (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-vop_ref[0][1]) + + (1<<(alpha+rho-1)); + s->sprite_offset[1][0]= ( (-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][0] + 1) + +( r*sprite_ref[0][1] - virtual_ref[0][1])*(-2*vop_ref[0][1] + 1) + +2*w2*r*sprite_ref[0][0] + - 16*w2 + + (1<<(alpha+rho+1))); + s->sprite_offset[1][1]= ( (-r*sprite_ref[0][1] + virtual_ref[0][1])*(-2*vop_ref[0][0] + 1) + +(-r*sprite_ref[0][0] + virtual_ref[0][0])*(-2*vop_ref[0][1] + 1) + +2*w2*r*sprite_ref[0][1] + - 16*w2 + + (1<<(alpha+rho+1))); + s->sprite_delta[0][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0]); + s->sprite_delta[0][1]= (+r*sprite_ref[0][1] - virtual_ref[0][1]); + s->sprite_delta[1][0]= (-r*sprite_ref[0][1] + virtual_ref[0][1]); + s->sprite_delta[1][1]= (-r*sprite_ref[0][0] + virtual_ref[0][0]); + + s->sprite_shift[0]= alpha+rho; + s->sprite_shift[1]= alpha+rho+2; + break; + case 3: + min_ab= FFMIN(alpha, beta); + w3= w2>>min_ab; + h3= h2>>min_ab; + s->sprite_offset[0][0]= (sprite_ref[0][0]<<(alpha+beta+rho-min_ab)) + + (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-vop_ref[0][0]) + + (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-vop_ref[0][1]) + + (1<<(alpha+beta+rho-min_ab-1)); + s->sprite_offset[0][1]= (sprite_ref[0][1]<<(alpha+beta+rho-min_ab)) + + (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-vop_ref[0][0]) + + (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-vop_ref[0][1]) + + (1<<(alpha+beta+rho-min_ab-1)); + s->sprite_offset[1][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3*(-2*vop_ref[0][0] + 1) + + (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3*(-2*vop_ref[0][1] + 1) + + 2*w2*h3*r*sprite_ref[0][0] + - 16*w2*h3 + + (1<<(alpha+beta+rho-min_ab+1)); + s->sprite_offset[1][1]= (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3*(-2*vop_ref[0][0] + 1) + + (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3*(-2*vop_ref[0][1] + 1) + + 2*w2*h3*r*sprite_ref[0][1] + - 16*w2*h3 + + (1<<(alpha+beta+rho-min_ab+1)); + s->sprite_delta[0][0]= (-r*sprite_ref[0][0] + virtual_ref[0][0])*h3; + s->sprite_delta[0][1]= (-r*sprite_ref[0][0] + virtual_ref[1][0])*w3; + s->sprite_delta[1][0]= (-r*sprite_ref[0][1] + virtual_ref[0][1])*h3; + s->sprite_delta[1][1]= (-r*sprite_ref[0][1] + virtual_ref[1][1])*w3; + + s->sprite_shift[0]= alpha + beta + rho - min_ab; + s->sprite_shift[1]= alpha + beta + rho - min_ab + 2; + break; + } + /* try to simplify the situation */ + if( s->sprite_delta[0][0] == a<sprite_shift[0] + && s->sprite_delta[0][1] == 0 + && s->sprite_delta[1][0] == 0 + && s->sprite_delta[1][1] == a<sprite_shift[0]) + { + s->sprite_offset[0][0]>>=s->sprite_shift[0]; + s->sprite_offset[0][1]>>=s->sprite_shift[0]; + s->sprite_offset[1][0]>>=s->sprite_shift[1]; + s->sprite_offset[1][1]>>=s->sprite_shift[1]; + s->sprite_delta[0][0]= a; + s->sprite_delta[0][1]= 0; + s->sprite_delta[1][0]= 0; + s->sprite_delta[1][1]= a; + s->sprite_shift[0]= 0; + s->sprite_shift[1]= 0; + s->real_sprite_warping_points=1; + } + else{ + int shift_y= 16 - s->sprite_shift[0]; + int shift_c= 16 - s->sprite_shift[1]; +//printf("shifts %d %d\n", shift_y, shift_c); + for(i=0; i<2; i++){ + s->sprite_offset[0][i]<<= shift_y; + s->sprite_offset[1][i]<<= shift_c; + s->sprite_delta[0][i]<<= shift_y; + s->sprite_delta[1][i]<<= shift_y; + s->sprite_shift[i]= 16; + } + s->real_sprite_warping_points= s->num_sprite_warping_points; + } +#if 0 +printf("vop:%d:%d %d:%d %d:%d, sprite:%d:%d %d:%d %d:%d, virtual: %d:%d %d:%d\n", + vop_ref[0][0], vop_ref[0][1], + vop_ref[1][0], vop_ref[1][1], + vop_ref[2][0], vop_ref[2][1], + sprite_ref[0][0], sprite_ref[0][1], + sprite_ref[1][0], sprite_ref[1][1], + sprite_ref[2][0], sprite_ref[2][1], + virtual_ref[0][0], virtual_ref[0][1], + virtual_ref[1][0], virtual_ref[1][1] + ); + +printf("offset: %d:%d , delta: %d %d %d %d, shift %d\n", + s->sprite_offset[0][0], s->sprite_offset[0][1], + s->sprite_delta[0][0], s->sprite_delta[0][1], + s->sprite_delta[1][0], s->sprite_delta[1][1], + s->sprite_shift[0] + ); +#endif +} + +static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){ + int hours, minutes, seconds; + + hours= get_bits(gb, 5); + minutes= get_bits(gb, 6); + skip_bits1(gb); + seconds= get_bits(gb, 6); + + s->time_base= seconds + 60*(minutes + 60*hours); + + skip_bits1(gb); + skip_bits1(gb); + + return 0; +} + +static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ + int width, height, vo_ver_id; + + /* vol header */ + skip_bits(gb, 1); /* random access */ + s->vo_type= get_bits(gb, 8); + if (get_bits1(gb) != 0) { /* is_ol_id */ + vo_ver_id = get_bits(gb, 4); /* vo_ver_id */ + skip_bits(gb, 3); /* vo_priority */ + } else { + vo_ver_id = 1; + } +//printf("vo type:%d\n",s->vo_type); + s->aspect_ratio_info= get_bits(gb, 4); + if(s->aspect_ratio_info == FF_ASPECT_EXTENDED){ + s->avctx->sample_aspect_ratio.num= get_bits(gb, 8); // par_width + s->avctx->sample_aspect_ratio.den= get_bits(gb, 8); // par_height + }else{ + s->avctx->sample_aspect_ratio= pixel_aspect[s->aspect_ratio_info]; + } + + if ((s->vol_control_parameters=get_bits1(gb))) { /* vol control parameter */ + int chroma_format= get_bits(gb, 2); + if(chroma_format!=1){ + av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n"); + } + s->low_delay= get_bits1(gb); + if(get_bits1(gb)){ /* vbv parameters */ + get_bits(gb, 15); /* first_half_bitrate */ + skip_bits1(gb); /* marker */ + get_bits(gb, 15); /* latter_half_bitrate */ + skip_bits1(gb); /* marker */ + get_bits(gb, 15); /* first_half_vbv_buffer_size */ + skip_bits1(gb); /* marker */ + get_bits(gb, 3); /* latter_half_vbv_buffer_size */ + get_bits(gb, 11); /* first_half_vbv_occupancy */ + skip_bits1(gb); /* marker */ + get_bits(gb, 15); /* latter_half_vbv_occupancy */ + skip_bits1(gb); /* marker */ + } + }else{ + // set low delay flag only once the smartest? low delay detection won't be overriden + if(s->picture_number==0) + s->low_delay=0; + } + + s->shape = get_bits(gb, 2); /* vol shape */ + if(s->shape != RECT_SHAPE) av_log(s->avctx, AV_LOG_ERROR, "only rectangular vol supported\n"); + if(s->shape == GRAY_SHAPE && vo_ver_id != 1){ + av_log(s->avctx, AV_LOG_ERROR, "Gray shape not supported\n"); + skip_bits(gb, 4); //video_object_layer_shape_extension + } + + check_marker(gb, "before time_increment_resolution"); + + s->avctx->time_base.den = get_bits(gb, 16); + if(!s->avctx->time_base.den){ + av_log(s->avctx, AV_LOG_ERROR, "time_base.den==0\n"); + return -1; + } + + s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1; + if (s->time_increment_bits < 1) + s->time_increment_bits = 1; + + check_marker(gb, "before fixed_vop_rate"); + + if (get_bits1(gb) != 0) { /* fixed_vop_rate */ + s->avctx->time_base.num = get_bits(gb, s->time_increment_bits); + }else + s->avctx->time_base.num = 1; + + s->t_frame=0; + + if (s->shape != BIN_ONLY_SHAPE) { + if (s->shape == RECT_SHAPE) { + skip_bits1(gb); /* marker */ + width = get_bits(gb, 13); + skip_bits1(gb); /* marker */ + height = get_bits(gb, 13); + skip_bits1(gb); /* marker */ + if(width && height && !(s->width && s->avctx->codec_tag == ff_get_fourcc("MP4S"))){ /* they should be non zero but who knows ... */ + s->width = width; + s->height = height; +// printf("width/height: %d %d\n", width, height); + } + } + + s->progressive_sequence= + s->progressive_frame= get_bits1(gb)^1; + s->interlaced_dct=0; + if(!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO)) + av_log(s->avctx, AV_LOG_INFO, "MPEG4 OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */ + if (vo_ver_id == 1) { + s->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */ + } else { + s->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */ + } + if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "Static Sprites not supported\n"); + if(s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE){ + if(s->vol_sprite_usage==STATIC_SPRITE){ + s->sprite_width = get_bits(gb, 13); + skip_bits1(gb); /* marker */ + s->sprite_height= get_bits(gb, 13); + skip_bits1(gb); /* marker */ + s->sprite_left = get_bits(gb, 13); + skip_bits1(gb); /* marker */ + s->sprite_top = get_bits(gb, 13); + skip_bits1(gb); /* marker */ + } + s->num_sprite_warping_points= get_bits(gb, 6); + s->sprite_warping_accuracy = get_bits(gb, 2); + s->sprite_brightness_change= get_bits1(gb); + if(s->vol_sprite_usage==STATIC_SPRITE) + s->low_latency_sprite= get_bits1(gb); + } + // FIXME sadct disable bit if verid!=1 && shape not rect + + if (get_bits1(gb) == 1) { /* not_8_bit */ + s->quant_precision = get_bits(gb, 4); /* quant_precision */ + if(get_bits(gb, 4)!=8) av_log(s->avctx, AV_LOG_ERROR, "N-bit not supported\n"); /* bits_per_pixel */ + if(s->quant_precision!=5) av_log(s->avctx, AV_LOG_ERROR, "quant precision %d\n", s->quant_precision); + } else { + s->quant_precision = 5; + } + + // FIXME a bunch of grayscale shape things + + if((s->mpeg_quant=get_bits1(gb))){ /* vol_quant_type */ + int i, v; + + /* load default matrixes */ + for(i=0; i<64; i++){ + int j= s->dsp.idct_permutation[i]; + v= ff_mpeg4_default_intra_matrix[i]; + s->intra_matrix[j]= v; + s->chroma_intra_matrix[j]= v; + + v= ff_mpeg4_default_non_intra_matrix[i]; + s->inter_matrix[j]= v; + s->chroma_inter_matrix[j]= v; + } + + /* load custom intra matrix */ + if(get_bits1(gb)){ + int last=0; + for(i=0; i<64; i++){ + int j; + v= get_bits(gb, 8); + if(v==0) break; + + last= v; + j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; + s->intra_matrix[j]= v; + s->chroma_intra_matrix[j]= v; + } + + /* replicate last value */ + for(; i<64; i++){ + int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; + s->intra_matrix[j]= last; + s->chroma_intra_matrix[j]= last; + } + } + + /* load custom non intra matrix */ + if(get_bits1(gb)){ + int last=0; + for(i=0; i<64; i++){ + int j; + v= get_bits(gb, 8); + if(v==0) break; + + last= v; + j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; + s->inter_matrix[j]= v; + s->chroma_inter_matrix[j]= v; + } + + /* replicate last value */ + for(; i<64; i++){ + int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; + s->inter_matrix[j]= last; + s->chroma_inter_matrix[j]= last; + } + } + + // FIXME a bunch of grayscale shape things + } + + if(vo_ver_id != 1) + s->quarter_sample= get_bits1(gb); + else s->quarter_sample=0; + + if(!get_bits1(gb)) av_log(s->avctx, AV_LOG_ERROR, "Complexity estimation not supported\n"); + + s->resync_marker= !get_bits1(gb); /* resync_marker_disabled */ + + s->data_partitioning= get_bits1(gb); + if(s->data_partitioning){ + s->rvlc= get_bits1(gb); + } + + if(vo_ver_id != 1) { + s->new_pred= get_bits1(gb); + if(s->new_pred){ + av_log(s->avctx, AV_LOG_ERROR, "new pred not supported\n"); + skip_bits(gb, 2); /* requested upstream message type */ + skip_bits1(gb); /* newpred segment type */ + } + s->reduced_res_vop= get_bits1(gb); + if(s->reduced_res_vop) av_log(s->avctx, AV_LOG_ERROR, "reduced resolution VOP not supported\n"); + } + else{ + s->new_pred=0; + s->reduced_res_vop= 0; + } + + s->scalability= get_bits1(gb); + + if (s->scalability) { + GetBitContext bak= *gb; + int ref_layer_id; + int ref_layer_sampling_dir; + int h_sampling_factor_n; + int h_sampling_factor_m; + int v_sampling_factor_n; + int v_sampling_factor_m; + + s->hierachy_type= get_bits1(gb); + ref_layer_id= get_bits(gb, 4); + ref_layer_sampling_dir= get_bits1(gb); + h_sampling_factor_n= get_bits(gb, 5); + h_sampling_factor_m= get_bits(gb, 5); + v_sampling_factor_n= get_bits(gb, 5); + v_sampling_factor_m= get_bits(gb, 5); + s->enhancement_type= get_bits1(gb); + + if( h_sampling_factor_n==0 || h_sampling_factor_m==0 + || v_sampling_factor_n==0 || v_sampling_factor_m==0){ + +// fprintf(stderr, "illegal scalability header (VERY broken encoder), trying to workaround\n"); + s->scalability=0; + + *gb= bak; + }else + av_log(s->avctx, AV_LOG_ERROR, "scalability not supported\n"); + + // bin shape stuff FIXME + } + } + return 0; +} + +/** + * decodes the user data stuff in the header. + * allso inits divx/xvid/lavc_version/build + */ +static int decode_user_data(MpegEncContext *s, GetBitContext *gb){ + char buf[256]; + int i; + int e; + int ver = 0, build = 0, ver2 = 0, ver3 = 0; + char last; + + for(i=0; i<255 && gb->index < gb->size_in_bits; i++){ + if(show_bits(gb, 23) == 0) break; + buf[i]= get_bits(gb, 8); + } + buf[i]=0; + + /* divx detection */ + e=sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last); + if(e<2) + e=sscanf(buf, "DivX%db%d%c", &ver, &build, &last); + if(e>=2){ + s->divx_version= ver; + s->divx_build= build; + s->divx_packed= e==3 && last=='p'; + } + + /* ffmpeg detection */ + e=sscanf(buf, "FFmpe%*[^b]b%d", &build)+3; + if(e!=4) + e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build); + if(e!=4){ + e=sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3)+1; + if (e>1) + build= (ver<<16) + (ver2<<8) + ver3; + } + if(e!=4){ + if(strcmp(buf, "ffmpeg")==0){ + s->lavc_build= 4600; + } + } + if(e==4){ + s->lavc_build= build; + } + + /* xvid detection */ + e=sscanf(buf, "XviD%d", &build); + if(e==1){ + s->xvid_build= build; + } + +//printf("User Data: %s\n", buf); + return 0; +} + +static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ + int time_incr, time_increment; + + s->pict_type = get_bits(gb, 2) + I_TYPE; /* pict type: I = 0 , P = 1 */ + if(s->pict_type==B_TYPE && s->low_delay && s->vol_control_parameters==0 && !(s->flags & CODEC_FLAG_LOW_DELAY)){ + av_log(s->avctx, AV_LOG_ERROR, "low_delay flag incorrectly, clearing it\n"); + s->low_delay=0; + } + + s->partitioned_frame= s->data_partitioning && s->pict_type!=B_TYPE; + if(s->partitioned_frame) + s->decode_mb= mpeg4_decode_partitioned_mb; + else + s->decode_mb= ff_mpeg4_decode_mb; + + time_incr=0; + while (get_bits1(gb) != 0) + time_incr++; + + check_marker(gb, "before time_increment"); + + if(s->time_increment_bits==0 || !(show_bits(gb, s->time_increment_bits+1)&1)){ + av_log(s->avctx, AV_LOG_ERROR, "hmm, seems the headers are not complete, trying to guess time_increment_bits\n"); + + for(s->time_increment_bits=1 ;s->time_increment_bits<16; s->time_increment_bits++){ + if(show_bits(gb, s->time_increment_bits+1)&1) break; + } + + av_log(s->avctx, AV_LOG_ERROR, "my guess is %d bits ;)\n",s->time_increment_bits); + } + + if(IS_3IV1) time_increment= get_bits1(gb); //FIXME investigate further + else time_increment= get_bits(gb, s->time_increment_bits); + +// printf("%d %X\n", s->time_increment_bits, time_increment); +//av_log(s->avctx, AV_LOG_DEBUG, " type:%d modulo_time_base:%d increment:%d t_frame %d\n", s->pict_type, time_incr, time_increment, s->t_frame); + if(s->pict_type!=B_TYPE){ + s->last_time_base= s->time_base; + s->time_base+= time_incr; + s->time= s->time_base*s->avctx->time_base.den + time_increment; + if(s->workaround_bugs&FF_BUG_UMP4){ + if(s->time < s->last_non_b_time){ +// fprintf(stderr, "header is not mpeg4 compatible, broken encoder, trying to workaround\n"); + s->time_base++; + s->time+= s->avctx->time_base.den; + } + } + s->pp_time= s->time - s->last_non_b_time; + s->last_non_b_time= s->time; + }else{ + s->time= (s->last_time_base + time_incr)*s->avctx->time_base.den + time_increment; + s->pb_time= s->pp_time - (s->last_non_b_time - s->time); + if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){ +// printf("messed up order, maybe after seeking? skipping current b frame\n"); + return FRAME_SKIPPED; + } + ff_mpeg4_init_direct_mv(s); + + if(s->t_frame==0) s->t_frame= s->pb_time; + if(s->t_frame==0) s->t_frame=1; // 1/0 protection + s->pp_field_time= ( ROUNDED_DIV(s->last_non_b_time, s->t_frame) + - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2; + s->pb_field_time= ( ROUNDED_DIV(s->time, s->t_frame) + - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2; + } +//av_log(s->avctx, AV_LOG_DEBUG, "last nonb %Ld last_base %d time %Ld pp %d pb %d t %d ppf %d pbf %d\n", s->last_non_b_time, s->last_time_base, s->time, s->pp_time, s->pb_time, s->t_frame, s->pp_field_time, s->pb_field_time); + + if(s->avctx->time_base.num) + s->current_picture_ptr->pts= (s->time + s->avctx->time_base.num/2) / s->avctx->time_base.num; + else + s->current_picture_ptr->pts= AV_NOPTS_VALUE; + if(s->avctx->debug&FF_DEBUG_PTS) + av_log(s->avctx, AV_LOG_DEBUG, "MPEG4 PTS: %"PRId64"\n", s->current_picture_ptr->pts); + + check_marker(gb, "before vop_coded"); + + /* vop coded */ + if (get_bits1(gb) != 1){ + if(s->avctx->debug&FF_DEBUG_PICT_INFO) + av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n"); + return FRAME_SKIPPED; + } +//printf("time %d %d %d || %Ld %Ld %Ld\n", s->time_increment_bits, s->avctx->time_base.den, s->time_base, +//s->time, s->last_non_b_time, s->last_non_b_time - s->pp_time); + if (s->shape != BIN_ONLY_SHAPE && ( s->pict_type == P_TYPE + || (s->pict_type == S_TYPE && s->vol_sprite_usage==GMC_SPRITE))) { + /* rounding type for motion estimation */ + s->no_rounding = get_bits1(gb); + } else { + s->no_rounding = 0; + } +//FIXME reduced res stuff + + if (s->shape != RECT_SHAPE) { + if (s->vol_sprite_usage != 1 || s->pict_type != I_TYPE) { + int width, height, hor_spat_ref, ver_spat_ref; + + width = get_bits(gb, 13); + skip_bits1(gb); /* marker */ + height = get_bits(gb, 13); + skip_bits1(gb); /* marker */ + hor_spat_ref = get_bits(gb, 13); /* hor_spat_ref */ + skip_bits1(gb); /* marker */ + ver_spat_ref = get_bits(gb, 13); /* ver_spat_ref */ + } + skip_bits1(gb); /* change_CR_disable */ + + if (get_bits1(gb) != 0) { + skip_bits(gb, 8); /* constant_alpha_value */ + } + } +//FIXME complexity estimation stuff + + if (s->shape != BIN_ONLY_SHAPE) { + s->intra_dc_threshold= mpeg4_dc_threshold[ get_bits(gb, 3) ]; + if(!s->progressive_sequence){ + s->top_field_first= get_bits1(gb); + s->alternate_scan= get_bits1(gb); + }else + s->alternate_scan= 0; + } + + if(s->alternate_scan){ + ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); + } else{ + ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , ff_zigzag_direct); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , ff_zigzag_direct); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); + } + + if(s->pict_type == S_TYPE && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){ + mpeg4_decode_sprite_trajectory(s, gb); + if(s->sprite_brightness_change) av_log(s->avctx, AV_LOG_ERROR, "sprite_brightness_change not supported\n"); + if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n"); + } + + if (s->shape != BIN_ONLY_SHAPE) { + s->chroma_qscale= s->qscale = get_bits(gb, s->quant_precision); + if(s->qscale==0){ + av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (qscale=0)\n"); + return -1; // makes no sense to continue, as there is nothing left from the image then + } + + if (s->pict_type != I_TYPE) { + s->f_code = get_bits(gb, 3); /* fcode_for */ + if(s->f_code==0){ + av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (f_code=0)\n"); + return -1; // makes no sense to continue, as the MV decoding will break very quickly + } + }else + s->f_code=1; + + if (s->pict_type == B_TYPE) { + s->b_code = get_bits(gb, 3); + }else + s->b_code=1; + + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d\n", + s->qscale, s->f_code, s->b_code, + s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")), + gb->size_in_bits,s->progressive_sequence, s->alternate_scan, s->top_field_first, + s->quarter_sample ? "q" : "h", s->data_partitioning, s->resync_marker, s->num_sprite_warping_points, + s->sprite_warping_accuracy, 1-s->no_rounding, s->vo_type, s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold); + } + + if(!s->scalability){ + if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) { + skip_bits1(gb); // vop shape coding type + } + }else{ + if(s->enhancement_type){ + int load_backward_shape= get_bits1(gb); + if(load_backward_shape){ + av_log(s->avctx, AV_LOG_ERROR, "load backward shape isn't supported\n"); + } + } + skip_bits(gb, 2); //ref_select_code + } + } + /* detect buggy encoders which don't set the low_delay flag (divx4/xvid/opendivx)*/ + // note we cannot detect divx5 without b-frames easily (although it's buggy too) + if(s->vo_type==0 && s->vol_control_parameters==0 && s->divx_version==0 && s->picture_number==0){ + av_log(s->avctx, AV_LOG_ERROR, "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n"); + s->low_delay=1; + } + + s->picture_number++; // better than pic number==0 always ;) + + s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support + s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; + + if(s->workaround_bugs&FF_BUG_EDGE){ + s->h_edge_pos= s->width; + s->v_edge_pos= s->height; + } + return 0; +} + +/** + * decode mpeg4 headers + * @return <0 if no VOP found (or a damaged one) + * FRAME_SKIPPED if a not coded VOP is found + * 0 if a VOP is found + */ +int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb) +{ + int startcode, v; + + /* search next start code */ + align_get_bits(gb); + + if(s->avctx->codec_tag == ff_get_fourcc("WV1F") && show_bits(gb, 24) == 0x575630){ + skip_bits(gb, 24); + if(get_bits(gb, 8) == 0xF0) + return decode_vop_header(s, gb); + } + + startcode = 0xff; + for(;;) { + if(get_bits_count(gb) >= gb->size_in_bits){ + if(gb->size_in_bits==8 && (s->divx_version || s->xvid_build)){ + av_log(s->avctx, AV_LOG_ERROR, "frame skip %d\n", gb->size_in_bits); + return FRAME_SKIPPED; //divx bug + }else + return -1; //end of stream + } + + /* use the bits after the test */ + v = get_bits(gb, 8); + startcode = ((startcode << 8) | v) & 0xffffffff; + + if((startcode&0xFFFFFF00) != 0x100) + continue; //no startcode + + if(s->avctx->debug&FF_DEBUG_STARTCODE){ + av_log(s->avctx, AV_LOG_DEBUG, "startcode: %3X ", startcode); + if (startcode<=0x11F) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Start"); + else if(startcode<=0x12F) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Layer Start"); + else if(startcode<=0x13F) av_log(s->avctx, AV_LOG_DEBUG, "Reserved"); + else if(startcode<=0x15F) av_log(s->avctx, AV_LOG_DEBUG, "FGS bp start"); + else if(startcode<=0x1AF) av_log(s->avctx, AV_LOG_DEBUG, "Reserved"); + else if(startcode==0x1B0) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq Start"); + else if(startcode==0x1B1) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq End"); + else if(startcode==0x1B2) av_log(s->avctx, AV_LOG_DEBUG, "User Data"); + else if(startcode==0x1B3) av_log(s->avctx, AV_LOG_DEBUG, "Group of VOP start"); + else if(startcode==0x1B4) av_log(s->avctx, AV_LOG_DEBUG, "Video Session Error"); + else if(startcode==0x1B5) av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Start"); + else if(startcode==0x1B6) av_log(s->avctx, AV_LOG_DEBUG, "Video Object Plane start"); + else if(startcode==0x1B7) av_log(s->avctx, AV_LOG_DEBUG, "slice start"); + else if(startcode==0x1B8) av_log(s->avctx, AV_LOG_DEBUG, "extension start"); + else if(startcode==0x1B9) av_log(s->avctx, AV_LOG_DEBUG, "fgs start"); + else if(startcode==0x1BA) av_log(s->avctx, AV_LOG_DEBUG, "FBA Object start"); + else if(startcode==0x1BB) av_log(s->avctx, AV_LOG_DEBUG, "FBA Object Plane start"); + else if(startcode==0x1BC) av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object start"); + else if(startcode==0x1BD) av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object Plane start"); + else if(startcode==0x1BE) av_log(s->avctx, AV_LOG_DEBUG, "Still Texture Object start"); + else if(startcode==0x1BF) av_log(s->avctx, AV_LOG_DEBUG, "Texture Spatial Layer start"); + else if(startcode==0x1C0) av_log(s->avctx, AV_LOG_DEBUG, "Texture SNR Layer start"); + else if(startcode==0x1C1) av_log(s->avctx, AV_LOG_DEBUG, "Texture Tile start"); + else if(startcode==0x1C2) av_log(s->avctx, AV_LOG_DEBUG, "Texture Shape Layer start"); + else if(startcode==0x1C3) av_log(s->avctx, AV_LOG_DEBUG, "stuffing start"); + else if(startcode<=0x1C5) av_log(s->avctx, AV_LOG_DEBUG, "reserved"); + else if(startcode<=0x1FF) av_log(s->avctx, AV_LOG_DEBUG, "System start"); + av_log(s->avctx, AV_LOG_DEBUG, " at %d\n", get_bits_count(gb)); + } + + if(startcode >= 0x120 && startcode <= 0x12F){ + if(decode_vol_header(s, gb) < 0) + return -1; + } + else if(startcode == USER_DATA_STARTCODE){ + decode_user_data(s, gb); + } + else if(startcode == GOP_STARTCODE){ + mpeg4_decode_gop_header(s, gb); + } + else if(startcode == VOP_STARTCODE){ + return decode_vop_header(s, gb); + } + + align_get_bits(gb); + startcode = 0xff; + } +} + +/* don't understand why they choose a different header ! */ +int intel_h263_decode_picture_header(MpegEncContext *s) +{ + int format; + + /* picture header */ + if (get_bits_long(&s->gb, 22) != 0x20) { + av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n"); + return -1; + } + s->picture_number = get_bits(&s->gb, 8); /* picture timestamp */ + + if (get_bits1(&s->gb) != 1) { + av_log(s->avctx, AV_LOG_ERROR, "Bad marker\n"); + return -1; /* marker */ + } + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "Bad H263 id\n"); + return -1; /* h263 id */ + } + skip_bits1(&s->gb); /* split screen off */ + skip_bits1(&s->gb); /* camera off */ + skip_bits1(&s->gb); /* freeze picture release off */ + + format = get_bits(&s->gb, 3); + if (format != 7) { + av_log(s->avctx, AV_LOG_ERROR, "Intel H263 free format not supported\n"); + return -1; + } + s->h263_plus = 0; + + s->pict_type = I_TYPE + get_bits1(&s->gb); + + s->unrestricted_mv = get_bits1(&s->gb); + s->h263_long_vectors = s->unrestricted_mv; + + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "SAC not supported\n"); + return -1; /* SAC: off */ + } + if (get_bits1(&s->gb) != 0) { + s->obmc= 1; + av_log(s->avctx, AV_LOG_ERROR, "Advanced Prediction Mode not supported\n"); +// return -1; /* advanced prediction mode: off */ + } + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "PB frame mode no supported\n"); + return -1; /* PB frame mode */ + } + + /* skip unknown header garbage */ + skip_bits(&s->gb, 41); + + s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); + skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ + + /* PEI */ + while (get_bits1(&s->gb) != 0) { + skip_bits(&s->gb, 8); + } + s->f_code = 1; + + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + + return 0; +} + +int flv_h263_decode_picture_header(MpegEncContext *s) +{ + int format, width, height; + + /* picture header */ + if (get_bits_long(&s->gb, 17) != 1) { + av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n"); + return -1; + } + format = get_bits(&s->gb, 5); + if (format != 0 && format != 1) { + av_log(s->avctx, AV_LOG_ERROR, "Bad picture format\n"); + return -1; + } + s->h263_flv = format+1; + s->picture_number = get_bits(&s->gb, 8); /* picture timestamp */ + format = get_bits(&s->gb, 3); + switch (format) { + case 0: + width = get_bits(&s->gb, 8); + height = get_bits(&s->gb, 8); + break; + case 1: + width = get_bits(&s->gb, 16); + height = get_bits(&s->gb, 16); + break; + case 2: + width = 352; + height = 288; + break; + case 3: + width = 176; + height = 144; + break; + case 4: + width = 128; + height = 96; + break; + case 5: + width = 320; + height = 240; + break; + case 6: + width = 160; + height = 120; + break; + default: + width = height = 0; + break; + } + if(avcodec_check_dimensions(s->avctx, width, height)) + return -1; + s->width = width; + s->height = height; + + s->pict_type = I_TYPE + get_bits(&s->gb, 2); + s->dropable= s->pict_type > P_TYPE; + if (s->dropable) + s->pict_type = P_TYPE; + + skip_bits1(&s->gb); /* deblocking flag */ + s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); + + s->h263_plus = 0; + + s->unrestricted_mv = 1; + s->h263_long_vectors = 0; + + /* PEI */ + while (get_bits1(&s->gb) != 0) { + skip_bits(&s->gb, 8); + } + s->f_code = 1; + + if(s->avctx->debug & FF_DEBUG_PICT_INFO){ + av_log(s->avctx, AV_LOG_DEBUG, "%c esc_type:%d, qp:%d num:%d\n", + s->dropable ? 'D' : av_get_pict_type_char(s->pict_type), s->h263_flv-1, s->qscale, s->picture_number); + } + + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + + return 0; +} diff --git a/mpeg4/src/libavcodec/h263data.h b/mpeg4/src/libavcodec/h263data.h new file mode 100644 index 00000000..01bcaedb --- /dev/null +++ b/mpeg4/src/libavcodec/h263data.h @@ -0,0 +1,285 @@ +/** + * @file h263data.h + * H.263 tables. + */ + + +/* intra MCBPC, mb_type = (intra), then (intraq) */ +const uint8_t intra_MCBPC_code[9] = { 1, 1, 2, 3, 1, 1, 2, 3, 1 }; +const uint8_t intra_MCBPC_bits[9] = { 1, 3, 3, 3, 4, 6, 6, 6, 9 }; + +/* inter MCBPC, mb_type = (inter), (intra), (interq), (intraq), (inter4v) */ +/* Changed the tables for interq and inter4v+q, following the standard ** Juanjo ** */ +const uint8_t inter_MCBPC_code[28] = { + 1, 3, 2, 5, + 3, 4, 3, 3, + 3, 7, 6, 5, + 4, 4, 3, 2, + 2, 5, 4, 5, + 1, 0, 0, 0, /* Stuffing */ + 2, 12, 14, 15, +}; +const uint8_t inter_MCBPC_bits[28] = { + 1, 4, 4, 6, /* inter */ + 5, 8, 8, 7, /* intra */ + 3, 7, 7, 9, /* interQ */ + 6, 9, 9, 9, /* intraQ */ + 3, 7, 7, 8, /* inter4 */ + 9, 0, 0, 0, /* Stuffing */ + 11, 13, 13, 13,/* inter4Q*/ +}; + +static const uint8_t h263_mbtype_b_tab[15][2] = { + {1, 1}, + {3, 3}, + {1, 5}, + {4, 4}, + {5, 4}, + {6, 6}, + {2, 4}, + {3, 4}, + {7, 6}, + {4, 6}, + {5, 6}, + {1, 6}, + {1,10}, + {1, 7}, + {1, 8}, +}; + +static const int h263_mb_type_b_map[15]= { + MB_TYPE_DIRECT2 | MB_TYPE_L0L1, + MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP, + MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT, + MB_TYPE_L0 | MB_TYPE_16x16, + MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_16x16, + MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16, + MB_TYPE_L1 | MB_TYPE_16x16, + MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_16x16, + MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16, + MB_TYPE_L0L1 | MB_TYPE_16x16, + MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_16x16, + MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16, + 0, //stuffing + MB_TYPE_INTRA4x4 | MB_TYPE_CBP, + MB_TYPE_INTRA4x4 | MB_TYPE_CBP | MB_TYPE_QUANT, +}; + +const uint8_t cbpc_b_tab[4][2] = { +{0, 1}, +{2, 2}, +{7, 3}, +{6, 3}, +}; + +const uint8_t cbpy_tab[16][2] = +{ + {3,4}, {5,5}, {4,5}, {9,4}, {3,5}, {7,4}, {2,6}, {11,4}, + {2,5}, {3,6}, {5,4}, {10,4}, {4,4}, {8,4}, {6,4}, {3,2} +}; + +const uint8_t mvtab[33][2] = +{ + {1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7}, + {11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10}, + {12,10}, {11,10}, {10,10}, {9,10}, {8,10}, {7,10}, {6,10}, {5,10}, + {4,10}, {7,11}, {6,11}, {5,11}, {4,11}, {3,11}, {2,11}, {3,12}, + {2,12} +}; + +/* third non intra table */ +const uint16_t inter_vlc[103][2] = { +{ 0x2, 2 },{ 0xf, 4 },{ 0x15, 6 },{ 0x17, 7 }, +{ 0x1f, 8 },{ 0x25, 9 },{ 0x24, 9 },{ 0x21, 10 }, +{ 0x20, 10 },{ 0x7, 11 },{ 0x6, 11 },{ 0x20, 11 }, +{ 0x6, 3 },{ 0x14, 6 },{ 0x1e, 8 },{ 0xf, 10 }, +{ 0x21, 11 },{ 0x50, 12 },{ 0xe, 4 },{ 0x1d, 8 }, +{ 0xe, 10 },{ 0x51, 12 },{ 0xd, 5 },{ 0x23, 9 }, +{ 0xd, 10 },{ 0xc, 5 },{ 0x22, 9 },{ 0x52, 12 }, +{ 0xb, 5 },{ 0xc, 10 },{ 0x53, 12 },{ 0x13, 6 }, +{ 0xb, 10 },{ 0x54, 12 },{ 0x12, 6 },{ 0xa, 10 }, +{ 0x11, 6 },{ 0x9, 10 },{ 0x10, 6 },{ 0x8, 10 }, +{ 0x16, 7 },{ 0x55, 12 },{ 0x15, 7 },{ 0x14, 7 }, +{ 0x1c, 8 },{ 0x1b, 8 },{ 0x21, 9 },{ 0x20, 9 }, +{ 0x1f, 9 },{ 0x1e, 9 },{ 0x1d, 9 },{ 0x1c, 9 }, +{ 0x1b, 9 },{ 0x1a, 9 },{ 0x22, 11 },{ 0x23, 11 }, +{ 0x56, 12 },{ 0x57, 12 },{ 0x7, 4 },{ 0x19, 9 }, +{ 0x5, 11 },{ 0xf, 6 },{ 0x4, 11 },{ 0xe, 6 }, +{ 0xd, 6 },{ 0xc, 6 },{ 0x13, 7 },{ 0x12, 7 }, +{ 0x11, 7 },{ 0x10, 7 },{ 0x1a, 8 },{ 0x19, 8 }, +{ 0x18, 8 },{ 0x17, 8 },{ 0x16, 8 },{ 0x15, 8 }, +{ 0x14, 8 },{ 0x13, 8 },{ 0x18, 9 },{ 0x17, 9 }, +{ 0x16, 9 },{ 0x15, 9 },{ 0x14, 9 },{ 0x13, 9 }, +{ 0x12, 9 },{ 0x11, 9 },{ 0x7, 10 },{ 0x6, 10 }, +{ 0x5, 10 },{ 0x4, 10 },{ 0x24, 11 },{ 0x25, 11 }, +{ 0x26, 11 },{ 0x27, 11 },{ 0x58, 12 },{ 0x59, 12 }, +{ 0x5a, 12 },{ 0x5b, 12 },{ 0x5c, 12 },{ 0x5d, 12 }, +{ 0x5e, 12 },{ 0x5f, 12 },{ 0x3, 7 }, +}; + +const int8_t inter_level[102] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 1, 2, 3, 4, + 5, 6, 1, 2, 3, 4, 1, 2, + 3, 1, 2, 3, 1, 2, 3, 1, + 2, 3, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 3, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, +}; + +const int8_t inter_run[102] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 3, 3, + 3, 4, 4, 4, 5, 5, 5, 6, + 6, 6, 7, 7, 8, 8, 9, 9, + 10, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 0, 0, 0, 1, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, +}; + +static RLTable rl_inter = { + 102, + 58, + inter_vlc, + inter_run, + inter_level, +}; + +const uint16_t intra_vlc_aic[103][2] = { +{ 0x2, 2 }, { 0x6, 3 }, { 0xe, 4 }, { 0xc, 5 }, +{ 0xd, 5 }, { 0x10, 6 }, { 0x11, 6 }, { 0x12, 6 }, +{ 0x16, 7 }, { 0x1b, 8 }, { 0x20, 9 }, { 0x21, 9 }, +{ 0x1a, 9 }, { 0x1b, 9 }, { 0x1c, 9 }, { 0x1d, 9 }, +{ 0x1e, 9 }, { 0x1f, 9 }, { 0x23, 11 }, { 0x22, 11 }, +{ 0x57, 12 }, { 0x56, 12 }, { 0x55, 12 }, { 0x54, 12 }, +{ 0x53, 12 }, { 0xf, 4 }, { 0x14, 6 }, { 0x14, 7 }, +{ 0x1e, 8 }, { 0xf, 10 }, { 0x21, 11 }, { 0x50, 12 }, +{ 0xb, 5 }, { 0x15, 7 }, { 0xe, 10 }, { 0x9, 10 }, +{ 0x15, 6 }, { 0x1d, 8 }, { 0xd, 10 }, { 0x51, 12 }, +{ 0x13, 6 }, { 0x23, 9 }, { 0x7, 11 }, { 0x17, 7 }, +{ 0x22, 9 }, { 0x52, 12 }, { 0x1c, 8 }, { 0xc, 10 }, +{ 0x1f, 8 }, { 0xb, 10 }, { 0x25, 9 }, { 0xa, 10 }, +{ 0x24, 9 }, { 0x6, 11 }, { 0x21, 10 }, { 0x20, 10 }, +{ 0x8, 10 }, { 0x20, 11 }, { 0x7, 4 }, { 0xc, 6 }, +{ 0x10, 7 }, { 0x13, 8 }, { 0x11, 9 }, { 0x12, 9 }, +{ 0x4, 10 }, { 0x27, 11 }, { 0x26, 11 }, { 0x5f, 12 }, +{ 0xf, 6 }, { 0x13, 9 }, { 0x5, 10 }, { 0x25, 11 }, +{ 0xe, 6 }, { 0x14, 9 }, { 0x24, 11 }, { 0xd, 6 }, +{ 0x6, 10 }, { 0x5e, 12 }, { 0x11, 7 }, { 0x7, 10 }, +{ 0x13, 7 }, { 0x5d, 12 }, { 0x12, 7 }, { 0x5c, 12 }, +{ 0x14, 8 }, { 0x5b, 12 }, { 0x15, 8 }, { 0x1a, 8 }, +{ 0x19, 8 }, { 0x18, 8 }, { 0x17, 8 }, { 0x16, 8 }, +{ 0x19, 9 }, { 0x15, 9 }, { 0x16, 9 }, { 0x18, 9 }, +{ 0x17, 9 }, { 0x4, 11 }, { 0x5, 11 }, { 0x58, 12 }, +{ 0x59, 12 }, { 0x5a, 12 }, { 0x3, 7 }, +}; + +const int8_t intra_run_aic[102] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 5, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 11, +12, 13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 2, 2, 2, 3, 3, 3, 4, 4, + 5, 5, 6, 6, 7, 7, 8, 9, +10, 11, 12, 13, 14, 15, 16, 17, +18, 19, 20, 21, 22, 23, +}; + +const int8_t intra_level_aic[102] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, +17, 18, 19, 20, 21, 22, 23, 24, +25, 1, 2, 3, 4, 5, 6, 7, + 1, 2, 3, 4, 1, 2, 3, 4, + 1, 2, 3, 1, 2, 3, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 1, + 1, 1, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 1, 2, 3, 4, + 1, 2, 3, 1, 2, 3, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, +}; + +static RLTable rl_intra_aic = { + 102, + 58, + intra_vlc_aic, + intra_run_aic, + intra_level_aic, +}; + +static const uint8_t wrong_run[102] = { + 1, 2, 3, 5, 4, 10, 9, 8, +11, 15, 17, 16, 23, 22, 21, 20, +19, 18, 25, 24, 27, 26, 11, 7, + 6, 1, 2, 13, 2, 2, 2, 2, + 6, 12, 3, 9, 1, 3, 4, 3, + 7, 4, 1, 1, 5, 5, 14, 6, + 1, 7, 1, 8, 1, 1, 1, 1, +10, 1, 1, 5, 9, 17, 25, 24, +29, 33, 32, 41, 2, 23, 28, 31, + 3, 22, 30, 4, 27, 40, 8, 26, + 6, 39, 7, 38, 16, 37, 15, 10, +11, 12, 13, 14, 1, 21, 20, 18, +19, 2, 1, 34, 35, 36 +}; + +static const uint16_t h263_format[8][2] = { + { 0, 0 }, + { 128, 96 }, + { 176, 144 }, + { 352, 288 }, + { 704, 576 }, + { 1408, 1152 }, +}; + +const uint8_t ff_aic_dc_scale_table[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 2, 4, 6, 8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62 +}; + +static const uint8_t modified_quant_tab[2][32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +{ + 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9,10,11,12,13,14,15,16,17,18,18,19,20,21,22,23,24,25,26,27,28 +},{ + 0, 2, 3, 4, 5, 6, 7, 8, 9,10,11,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,29,30,31,31,31,26 +} +}; + +const uint8_t ff_h263_chroma_qscale_table[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 9,10,10,11,11,12,12,12,13,13,13,14,14,14,14,14,15,15,15,15,15 +}; + +const uint16_t ff_mba_max[6]={ + 47, 98, 395,1583,6335,9215 +}; + +const uint8_t ff_mba_length[7]={ + 6, 7, 9, 11, 13, 14, 14 +}; + +const uint8_t ff_h263_loop_filter_strength[32]={ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 + 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11,11,12,12,12 +}; + diff --git a/mpeg4/src/libavcodec/h263dec.c b/mpeg4/src/libavcodec/h263dec.c new file mode 100644 index 00000000..30303f8e --- /dev/null +++ b/mpeg4/src/libavcodec/h263dec.c @@ -0,0 +1,895 @@ +/* + * H.263 decoder + * Copyright (c) 2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file h263dec.c + * H.263 decoder. + */ + +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + +//#define DEBUG +//#define PRINT_FRAME_TIME + +int ff_h263_decode_init(AVCodecContext *avctx) +{ + MpegEncContext *s = avctx->priv_data; + + s->avctx = avctx; + s->out_format = FMT_H263; + + s->width = avctx->coded_width; + s->height = avctx->coded_height; + s->workaround_bugs= avctx->workaround_bugs; + + // set defaults + MPV_decode_defaults(s); + s->quant_precision=5; + s->decode_mb= ff_h263_decode_mb; + s->low_delay= 1; + avctx->pix_fmt= PIX_FMT_YUV420P; + s->unrestricted_mv= 1; + + /* select sub codec */ + switch(avctx->codec->id) { + case CODEC_ID_H263: + s->unrestricted_mv= 0; + break; + case CODEC_ID_MPEG4: + s->decode_mb= ff_mpeg4_decode_mb; + s->time_increment_bits = 4; /* default value for broken headers */ + s->h263_pred = 1; + s->low_delay = 0; //default, might be overriden in the vol header during header parsing + break; + case CODEC_ID_MSMPEG4V1: + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->msmpeg4_version=1; + break; + case CODEC_ID_MSMPEG4V2: + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->msmpeg4_version=2; + break; + case CODEC_ID_MSMPEG4V3: + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->msmpeg4_version=3; + break; + case CODEC_ID_WMV1: + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->msmpeg4_version=4; + break; + case CODEC_ID_WMV2: + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->msmpeg4_version=5; + break; + case CODEC_ID_WMV3: + s->h263_msmpeg4 = 1; + s->h263_pred = 1; + s->msmpeg4_version=6; + break; + case CODEC_ID_H263I: + break; + case CODEC_ID_FLV1: + s->h263_flv = 1; + break; + default: + return -1; + } + s->codec_id= avctx->codec->id; + + /* for h263, we allocate the images after having read the header */ + if (avctx->codec->id != CODEC_ID_H263 && avctx->codec->id != CODEC_ID_MPEG4) + if (MPV_common_init(s) < 0) + return -1; + + if (s->h263_msmpeg4) + ff_msmpeg4_decode_init(s); + else + h263_decode_init_vlc(s); + + return 0; +} + +int ff_h263_decode_end(AVCodecContext *avctx) +{ + MpegEncContext *s = avctx->priv_data; + + MPV_common_end(s); + return 0; +} + +/** + * returns the number of bytes consumed for building the current frame + */ +static int get_consumed_bytes(MpegEncContext *s, int buf_size){ + int pos= (get_bits_count(&s->gb)+7)>>3; + + if(s->divx_packed){ + //we would have to scan through the whole buf to handle the weird reordering ... + return buf_size; + }else if(s->flags&CODEC_FLAG_TRUNCATED){ + pos -= s->parse_context.last_index; + if(pos<0) pos=0; // padding is not really read so this might be -1 + return pos; + }else{ + if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) + if(pos+10>buf_size) pos=buf_size; // oops ;) + + return pos; + } +} + +static int decode_slice(MpegEncContext *s){ + const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F; + const int mb_size= 16>>s->avctx->lowres; + s->last_resync_gb= s->gb; + s->first_slice_line= 1; + + s->resync_mb_x= s->mb_x; + s->resync_mb_y= s->mb_y; + + ff_set_qscale(s, s->qscale); + + if(s->partitioned_frame){ + const int qscale= s->qscale; + + if(s->codec_id==CODEC_ID_MPEG4){ + if(ff_mpeg4_decode_partitions(s) < 0) + return -1; + } + + /* restore variables which were modified */ + s->first_slice_line=1; + s->mb_x= s->resync_mb_x; + s->mb_y= s->resync_mb_y; + ff_set_qscale(s, qscale); + } + + for(; s->mb_y < s->mb_height; s->mb_y++) { + /* per-row end of slice checks */ + if(s->msmpeg4_version){ + if(s->resync_mb_y + s->slice_height == s->mb_y){ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END); + + return 0; + } + } + + if(s->msmpeg4_version==1){ + s->last_dc[0]= + s->last_dc[1]= + s->last_dc[2]= 128; + } + + ff_init_block_index(s); + for(; s->mb_x < s->mb_width; s->mb_x++) { + int ret; + + ff_update_block_index(s); + + if(s->resync_mb_x == s->mb_x && s->resync_mb_y+1 == s->mb_y){ + s->first_slice_line=0; + } + + /* DCT & quantize */ + + s->mv_dir = MV_DIR_FORWARD; + s->mv_type = MV_TYPE_16X16; +// s->mb_skipped = 0; +//printf("%d %d %06X\n", ret, get_bits_count(&s->gb), show_bits(&s->gb, 24)); + ret= s->decode_mb(s, s->block); + + if (s->pict_type!=B_TYPE) + ff_h263_update_motion_val(s); + + if(ret<0){ + const int xy= s->mb_x + s->mb_y*s->mb_stride; + if(ret==SLICE_END){ + MPV_decode_mb(s, s->block); + if(s->loop_filter) + ff_h263_loop_filter(s); + +//printf("%d %d %d %06X\n", s->mb_x, s->mb_y, s->gb.size*8 - get_bits_count(&s->gb), show_bits(&s->gb, 24)); + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + + s->padding_bug_score--; + + if(++s->mb_x >= s->mb_width){ + s->mb_x=0; + ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size); + s->mb_y++; + } + return 0; + }else if(ret==SLICE_NOEND){ + av_log(s->avctx, AV_LOG_ERROR, "Slice mismatch at MB: %d\n", xy); + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + return -1; + } + av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy); + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask); + + return -1; + } + + MPV_decode_mb(s, s->block); + if(s->loop_filter) + ff_h263_loop_filter(s); + } + + ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size); + + s->mb_x= 0; + } + + assert(s->mb_x==0 && s->mb_y==s->mb_height); + + /* try to detect the padding bug */ + if( s->codec_id==CODEC_ID_MPEG4 + && (s->workaround_bugs&FF_BUG_AUTODETECT) + && s->gb.size_in_bits - get_bits_count(&s->gb) >=0 + && s->gb.size_in_bits - get_bits_count(&s->gb) < 48 +// && !s->resync_marker + && !s->data_partitioning){ + + const int bits_count= get_bits_count(&s->gb); + const int bits_left = s->gb.size_in_bits - bits_count; + + if(bits_left==0){ + s->padding_bug_score+=16; + } else if(bits_left != 1){ + int v= show_bits(&s->gb, 8); + v|= 0x7F >> (7-(bits_count&7)); + + if(v==0x7F && bits_left<=8) + s->padding_bug_score--; + else if(v==0x7F && ((get_bits_count(&s->gb)+8)&8) && bits_left<=16) + s->padding_bug_score+= 4; + else + s->padding_bug_score++; + } + } + + if(s->workaround_bugs&FF_BUG_AUTODETECT){ + if(s->padding_bug_score > -2 && !s->data_partitioning /*&& (s->divx_version || !s->resync_marker)*/) + s->workaround_bugs |= FF_BUG_NO_PADDING; + else + s->workaround_bugs &= ~FF_BUG_NO_PADDING; + } + + // handle formats which don't have unique end markers + if(s->msmpeg4_version || (s->workaround_bugs&FF_BUG_NO_PADDING)){ //FIXME perhaps solve this more cleanly + int left= s->gb.size_in_bits - get_bits_count(&s->gb); + int max_extra=7; + + /* no markers in M$ crap */ + if(s->msmpeg4_version && s->pict_type==I_TYPE) + max_extra+= 17; + + /* buggy padding but the frame should still end approximately at the bitstream end */ + if((s->workaround_bugs&FF_BUG_NO_PADDING) && s->error_resilience>=3) + max_extra+= 48; + else if((s->workaround_bugs&FF_BUG_NO_PADDING)) + max_extra+= 256*256*256*64; + + if(left>max_extra){ + av_log(s->avctx, AV_LOG_ERROR, "discarding %d junk bits at end, next would be %X\n", left, show_bits(&s->gb, 24)); + } + else if(left<0){ + av_log(s->avctx, AV_LOG_ERROR, "overreading %d bits\n", -left); + }else + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END); + + return 0; + } + + av_log(s->avctx, AV_LOG_ERROR, "slice end not reached but screenspace end (%d left %06X, score= %d)\n", + s->gb.size_in_bits - get_bits_count(&s->gb), + show_bits(&s->gb, 24), s->padding_bug_score); + + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + + return -1; +} + +/** + * finds the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ + int vop_found, i; + uint32_t state; + + vop_found= pc->frame_start_found; + state= pc->state; + + i=0; + if(!vop_found){ + for(i=0; iframe_start_found=0; + pc->state=-1; + return i-3; + } + } + } + pc->frame_start_found= vop_found; + pc->state= state; + return END_NOT_FOUND; +} + +static int h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){ + int vop_found, i; + uint32_t state; + + vop_found= pc->frame_start_found; + state= pc->state; + + i=0; + if(!vop_found){ + for(i=0; i>(32-22) == 0x20){ + i++; + vop_found=1; + break; + } + } + } + + if(vop_found){ + for(; i>(32-22) == 0x20){ + pc->frame_start_found=0; + pc->state=-1; + return i-3; + } + } + } + pc->frame_start_found= vop_found; + pc->state= state; + + return END_NOT_FOUND; +} + +static int h263_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + ParseContext *pc = s->priv_data; + int next; + + next= h263_find_frame_end(pc, buf, buf_size); + + if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + *poutbuf = (uint8_t *)buf; + *poutbuf_size = buf_size; + return next; +} + +int ff_h263_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + MpegEncContext *s = avctx->priv_data; + int ret; + AVFrame *pict = data; + +#ifdef PRINT_FRAME_TIME +uint64_t time= rdtsc(); +#endif +#ifdef DEBUG + printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); + printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); +#endif + s->flags= avctx->flags; + s->flags2= avctx->flags2; + + /* no supplementary picture */ + if (buf_size == 0) { + /* special case for last picture */ + if (s->low_delay==0 && s->next_picture_ptr) { + *pict= *(AVFrame*)s->next_picture_ptr; + s->next_picture_ptr= NULL; + + *data_size = sizeof(AVFrame); + } + + return 0; + } + + if(s->flags&CODEC_FLAG_TRUNCATED){ + int next; + + if(s->codec_id==CODEC_ID_MPEG4){ + next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size); + }else if(s->codec_id==CODEC_ID_H263){ + next= h263_find_frame_end(&s->parse_context, buf, buf_size); + }else{ + av_log(s->avctx, AV_LOG_ERROR, "this codec does not support truncated bitstreams\n"); + return -1; + } + + if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 ) + return buf_size; + } + + +retry: + + if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 5.01+/xvid frame reorder + init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8); + }else + init_get_bits(&s->gb, buf, buf_size*8); + s->bitstream_buffer_size=0; + + if (!s->context_initialized) { + if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix + return -1; + } + + //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there + if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){ + int i= ff_find_unused_picture(s, 0); + s->current_picture_ptr= &s->picture[i]; + } + + /* let's go :-) */ + if (s->msmpeg4_version==5) { + ret= ff_wmv2_decode_picture_header(s); + } else if (s->msmpeg4_version) { + ret = msmpeg4_decode_picture_header(s); + } else if (s->h263_pred) { + if(s->avctx->extradata_size && s->picture_number==0){ + GetBitContext gb; + + init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8); + ret = ff_mpeg4_decode_picture_header(s, &gb); + } + ret = ff_mpeg4_decode_picture_header(s, &s->gb); + + if(s->flags& CODEC_FLAG_LOW_DELAY) + s->low_delay=1; + } else if (s->codec_id == CODEC_ID_H263I) { + ret = intel_h263_decode_picture_header(s); + } else if (s->h263_flv) { + ret = flv_h263_decode_picture_header(s); + } else { + ret = h263_decode_picture_header(s); + } + + if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_size); + + /* skip if the header was thrashed */ + if (ret < 0){ + av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); + return -1; + } + + avctx->has_b_frames= !s->low_delay; + + if(s->xvid_build==0 && s->divx_version==0 && s->lavc_build==0){ + if(s->avctx->stream_codec_tag == ff_get_fourcc("XVID") || + s->avctx->codec_tag == ff_get_fourcc("XVID") || s->avctx->codec_tag == ff_get_fourcc("XVIX") || + s->avctx->codec_tag == ff_get_fourcc("RMP4")) + s->xvid_build= -1; +#if 0 + if(s->avctx->codec_tag == ff_get_fourcc("DIVX") && s->vo_type==0 && s->vol_control_parameters==1 + && s->padding_bug_score > 0 && s->low_delay) // XVID with modified fourcc + s->xvid_build= -1; +#endif + } + + if(s->xvid_build==0 && s->divx_version==0 && s->lavc_build==0){ + if(s->avctx->codec_tag == ff_get_fourcc("DIVX") && s->vo_type==0 && s->vol_control_parameters==0) + s->divx_version= 400; //divx 4 + } + + if(s->xvid_build && s->divx_version){ + s->divx_version= + s->divx_build= 0; + } + + if(s->workaround_bugs&FF_BUG_AUTODETECT){ + if(s->avctx->codec_tag == ff_get_fourcc("XVIX")) + s->workaround_bugs|= FF_BUG_XVID_ILACE; + + if(s->avctx->codec_tag == ff_get_fourcc("UMP4")){ + s->workaround_bugs|= FF_BUG_UMP4; + } + + if(s->divx_version>=500){ + s->workaround_bugs|= FF_BUG_QPEL_CHROMA; + } + + if(s->divx_version>502){ + s->workaround_bugs|= FF_BUG_QPEL_CHROMA2; + } + + if(s->xvid_build && s->xvid_build<=3) + s->padding_bug_score= 256*256*256*64; + + if(s->xvid_build && s->xvid_build<=1) + s->workaround_bugs|= FF_BUG_QPEL_CHROMA; + + if(s->xvid_build && s->xvid_build<=12) + s->workaround_bugs|= FF_BUG_EDGE; + + if(s->xvid_build && s->xvid_build<=32) + s->workaround_bugs|= FF_BUG_DC_CLIP; + +#define SET_QPEL_FUNC(postfix1, postfix2) \ + s->dsp.put_ ## postfix1 = ff_put_ ## postfix2;\ + s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2;\ + s->dsp.avg_ ## postfix1 = ff_avg_ ## postfix2; + + if(s->lavc_build && s->lavc_build<4653) + s->workaround_bugs|= FF_BUG_STD_QPEL; + + if(s->lavc_build && s->lavc_build<4655) + s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE; + + if(s->lavc_build && s->lavc_build<4670){ + s->workaround_bugs|= FF_BUG_EDGE; + } + + if(s->lavc_build && s->lavc_build<=4712) + s->workaround_bugs|= FF_BUG_DC_CLIP; + + if(s->divx_version) + s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE; +//printf("padding_bug_score: %d\n", s->padding_bug_score); + if(s->divx_version==501 && s->divx_build==20020416) + s->padding_bug_score= 256*256*256*64; + + if(s->divx_version && s->divx_version<500){ + s->workaround_bugs|= FF_BUG_EDGE; + } + + if(s->divx_version) + s->workaround_bugs|= FF_BUG_HPEL_CHROMA; +#if 0 + if(s->divx_version==500) + s->padding_bug_score= 256*256*256*64; + + /* very ugly XVID padding bug detection FIXME/XXX solve this differently + * lets hope this at least works + */ + if( s->resync_marker==0 && s->data_partitioning==0 && s->divx_version==0 + && s->codec_id==CODEC_ID_MPEG4 && s->vo_type==0) + s->workaround_bugs|= FF_BUG_NO_PADDING; + + if(s->lavc_build && s->lavc_build<4609) //FIXME not sure about the version num but a 4609 file seems ok + s->workaround_bugs|= FF_BUG_NO_PADDING; +#endif + } + + if(s->workaround_bugs& FF_BUG_STD_QPEL){ + SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c) + + SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c) + } + + if(avctx->debug & FF_DEBUG_BUGS) + av_log(s->avctx, AV_LOG_DEBUG, "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n", + s->workaround_bugs, s->lavc_build, s->xvid_build, s->divx_version, s->divx_build, + s->divx_packed ? "p" : ""); + +#if 0 // dump bits per frame / qp / complexity +{ + static FILE *f=NULL; + if(!f) f=fopen("rate_qp_cplx.txt", "w"); + fprintf(f, "%d %d %f\n", buf_size, s->qscale, buf_size*(double)s->qscale); +} +#endif + +#if defined(HAVE_MMX) && defined(CONFIG_GPL) + if(s->codec_id == CODEC_ID_MPEG4 && s->xvid_build && avctx->idct_algo == FF_IDCT_AUTO && (mm_flags & MM_MMX)){ + avctx->idct_algo= FF_IDCT_XVIDMMX; + avctx->coded_width= 0; // force reinit +// dsputil_init(&s->dsp, avctx); + s->picture_number=0; + } +#endif + + /* After H263 & mpeg4 header decode we have the height, width,*/ + /* and other parameters. So then we could init the picture */ + /* FIXME: By the way H263 decoder is evolving it should have */ + /* an H263EncContext */ + + if ( s->width != avctx->coded_width + || s->height != avctx->coded_height) { + /* H.263 could change picture size any time */ + ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat + s->parse_context.buffer=0; + MPV_common_end(s); + s->parse_context= pc; + } + if (!s->context_initialized) { + avcodec_set_dimensions(avctx, s->width, s->height); + + goto retry; + } + + if((s->codec_id==CODEC_ID_H263 || s->codec_id==CODEC_ID_H263P)) + s->gob_index = ff_h263_get_gob_height(s); + + // for hurry_up==5 + s->current_picture.pict_type= s->pict_type; + s->current_picture.key_frame= s->pict_type == I_TYPE; + + /* skip B-frames if we don't have reference frames */ + if(s->last_picture_ptr==NULL && (s->pict_type==B_TYPE || s->dropable)) return get_consumed_bytes(s, buf_size); + /* skip b frames if we are in a hurry */ + if(avctx->hurry_up && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size); + if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE) + || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE) + || avctx->skip_frame >= AVDISCARD_ALL) + return get_consumed_bytes(s, buf_size); + /* skip everything if we are in a hurry>=5 */ + if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size); + + if(s->next_p_frame_damaged){ + if(s->pict_type==B_TYPE) + return get_consumed_bytes(s, buf_size); + else + s->next_p_frame_damaged=0; + } + + if(MPV_frame_start(s, avctx) < 0) + return -1; + +#ifdef DEBUG + av_log(avctx, AV_LOG_DEBUG, "qscale=%d\n", s->qscale); +#endif + + ff_er_frame_start(s); + + //the second part of the wmv2 header contains the MB skip bits which are stored in current_picture->mb_type + //which isnt available before MPV_frame_start() + if (s->msmpeg4_version==5){ + if(ff_wmv2_decode_secondary_picture_header(s) < 0) + return -1; + } + + /* decode each macroblock */ + s->mb_x=0; + s->mb_y=0; + + decode_slice(s); + while(s->mb_ymb_height){ + if(s->msmpeg4_version){ + if(s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_count(&s->gb) > s->gb.size_in_bits) + break; + }else{ + if(ff_h263_resync(s)<0) + break; + } + + if(s->msmpeg4_version<4 && s->h263_pred) + ff_mpeg4_clean_buffers(s); + + decode_slice(s); + } + + if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE) + if(msmpeg4_decode_ext_header(s, buf_size) < 0){ + s->error_status_table[s->mb_num-1]= AC_ERROR|DC_ERROR|MV_ERROR; + } + + /* divx 5.01+ bistream reorder stuff */ + if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_packed){ + int current_pos= get_bits_count(&s->gb)>>3; + int startcode_found=0; + + if(buf_size - current_pos > 5){ + int i; + for(i=current_pos; igb.buffer == s->bitstream_buffer && buf_size>20){ //xvid style + startcode_found=1; + current_pos=0; + } + + if(startcode_found){ + s->bitstream_buffer= av_fast_realloc( + s->bitstream_buffer, + &s->allocated_bitstream_buffer_size, + buf_size - current_pos + FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos); + s->bitstream_buffer_size= buf_size - current_pos; + } + } + + ff_er_frame_end(s); + + MPV_frame_end(s); + +assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type); +assert(s->current_picture.pict_type == s->pict_type); + if (s->pict_type == B_TYPE || s->low_delay) { + *pict= *(AVFrame*)s->current_picture_ptr; + } else if (s->last_picture_ptr != NULL) { + *pict= *(AVFrame*)s->last_picture_ptr; + } + + if(s->last_picture_ptr || s->low_delay){ + *data_size = sizeof(AVFrame); + ff_print_debug_info(s, pict); + } + + /* Return the Picture timestamp as the frame number */ + /* we substract 1 because it is added on utils.c */ + avctx->frame_number = s->picture_number - 1; + +#ifdef PRINT_FRAME_TIME +av_log(avctx, AV_LOG_DEBUG, "%Ld\n", rdtsc()-time); +#endif + + return get_consumed_bytes(s, buf_size); +} + +AVCodec mpeg4_decoder = { + "mpeg4", + CODEC_TYPE_VIDEO, + CODEC_ID_MPEG4, + sizeof(MpegEncContext), + ff_h263_decode_init, + NULL, + ff_h263_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, + .flush= ff_mpeg_flush, +}; + +AVCodec h263_decoder = { + "h263", + CODEC_TYPE_VIDEO, + CODEC_ID_H263, + sizeof(MpegEncContext), + ff_h263_decode_init, + NULL, + ff_h263_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, + .flush= ff_mpeg_flush, +}; + +AVCodec msmpeg4v1_decoder = { + "msmpeg4v1", + CODEC_TYPE_VIDEO, + CODEC_ID_MSMPEG4V1, + sizeof(MpegEncContext), + ff_h263_decode_init, + NULL, + ff_h263_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, +}; + +AVCodec msmpeg4v2_decoder = { + "msmpeg4v2", + CODEC_TYPE_VIDEO, + CODEC_ID_MSMPEG4V2, + sizeof(MpegEncContext), + ff_h263_decode_init, + NULL, + ff_h263_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, +}; + +AVCodec msmpeg4v3_decoder = { + "msmpeg4", + CODEC_TYPE_VIDEO, + CODEC_ID_MSMPEG4V3, + sizeof(MpegEncContext), + ff_h263_decode_init, + NULL, + ff_h263_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, +}; + +AVCodec wmv1_decoder = { + "wmv1", + CODEC_TYPE_VIDEO, + CODEC_ID_WMV1, + sizeof(MpegEncContext), + ff_h263_decode_init, + NULL, + ff_h263_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, +}; + +AVCodec h263i_decoder = { + "h263i", + CODEC_TYPE_VIDEO, + CODEC_ID_H263I, + sizeof(MpegEncContext), + ff_h263_decode_init, + NULL, + ff_h263_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1, +}; + +AVCodec flv_decoder = { + "flv", + CODEC_TYPE_VIDEO, + CODEC_ID_FLV1, + sizeof(MpegEncContext), + ff_h263_decode_init, + NULL, + ff_h263_decode_end, + ff_h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 +}; + +AVCodecParser h263_parser = { + { CODEC_ID_H263 }, + sizeof(ParseContext), + NULL, + h263_parse, + ff_parse_close, +}; diff --git a/mpeg4/src/libavcodec/h264.c b/mpeg4/src/libavcodec/h264.c new file mode 100644 index 00000000..15fdfcfc --- /dev/null +++ b/mpeg4/src/libavcodec/h264.c @@ -0,0 +1,8090 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder + * Copyright (c) 2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file h264.c + * H.264 / AVC / MPEG4 part10 codec. + * @author Michael Niedermayer + */ + +#include "common.h" +#include "dsputil.h" +#include "avcodec.h" +#include "mpegvideo.h" +#include "h264data.h" +#include "golomb.h" + +#include "cabac.h" + +#undef NDEBUG +#include + +#define interlaced_dct interlaced_dct_is_a_bad_name +#define mb_intra mb_intra_isnt_initalized_see_mb_type + +#define LUMA_DC_BLOCK_INDEX 25 +#define CHROMA_DC_BLOCK_INDEX 26 + +#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8 +#define COEFF_TOKEN_VLC_BITS 8 +#define TOTAL_ZEROS_VLC_BITS 9 +#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3 +#define RUN_VLC_BITS 3 +#define RUN7_VLC_BITS 6 + +#define MAX_SPS_COUNT 32 +#define MAX_PPS_COUNT 256 + +#define MAX_MMCO_COUNT 66 + +/** + * Sequence parameter set + */ +typedef struct SPS{ + + int profile_idc; + int level_idc; + int transform_bypass; ///< qpprime_y_zero_transform_bypass_flag + int log2_max_frame_num; ///< log2_max_frame_num_minus4 + 4 + int poc_type; ///< pic_order_cnt_type + int log2_max_poc_lsb; ///< log2_max_pic_order_cnt_lsb_minus4 + int delta_pic_order_always_zero_flag; + int offset_for_non_ref_pic; + int offset_for_top_to_bottom_field; + int poc_cycle_length; ///< num_ref_frames_in_pic_order_cnt_cycle + int ref_frame_count; ///< num_ref_frames + int gaps_in_frame_num_allowed_flag; + int mb_width; ///< frame_width_in_mbs_minus1 + 1 + int mb_height; ///< frame_height_in_mbs_minus1 + 1 + int frame_mbs_only_flag; + int mb_aff; ///b4_stride + int b8_stride; + + int halfpel_flag; + int thirdpel_flag; + + int unknown_svq3_flag; + int next_slice_index; + + SPS sps_buffer[MAX_SPS_COUNT]; + SPS sps; ///< current sps + + PPS pps_buffer[MAX_PPS_COUNT]; + /** + * current pps + */ + PPS pps; //FIXME move to Picture perhaps? (->no) do we need that? + + uint32_t dequant4_buffer[6][52][16]; + uint32_t dequant8_buffer[2][52][64]; + uint32_t (*dequant4_coeff[6])[16]; + uint32_t (*dequant8_coeff[2])[64]; + int dequant_coeff_pps; ///< reinit tables when pps changes + + int slice_num; + uint8_t *slice_table_base; + uint8_t *slice_table; ///< slice_table_base + mb_stride + 1 + int slice_type; + int slice_type_fixed; + + //interlacing specific flags + int mb_aff_frame; + int mb_field_decoding_flag; + + int sub_mb_type[4]; + + //POC stuff + int poc_lsb; + int poc_msb; + int delta_poc_bottom; + int delta_poc[2]; + int frame_num; + int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0 + int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0 + int frame_num_offset; ///< for POC type 2 + int prev_frame_num_offset; ///< for POC type 2 + int prev_frame_num; ///< frame_num of the last pic for POC type 1/2 + + /** + * frame_num for frames or 2*frame_num for field pics. + */ + int curr_pic_num; + + /** + * max_frame_num or 2*max_frame_num for field pics. + */ + int max_pic_num; + + //Weighted pred stuff + int use_weight; + int use_weight_chroma; + int luma_log2_weight_denom; + int chroma_log2_weight_denom; + int luma_weight[2][16]; + int luma_offset[2][16]; + int chroma_weight[2][16][2]; + int chroma_offset[2][16][2]; + int implicit_weight[16][16]; + + //deblock + int deblocking_filter; ///< disable_deblocking_filter_idc with 1<->0 + int slice_alpha_c0_offset; + int slice_beta_offset; + + int redundant_pic_count; + + int direct_spatial_mv_pred; + int dist_scale_factor[16]; + int map_col_to_list0[2][16]; + + /** + * num_ref_idx_l0/1_active_minus1 + 1 + */ + int ref_count[2];// FIXME split for AFF + Picture *short_ref[32]; + Picture *long_ref[32]; + Picture default_ref_list[2][32]; + Picture ref_list[2][32]; //FIXME size? + Picture field_ref_list[2][32]; //FIXME size? + Picture *delayed_pic[16]; //FIXME size? + Picture *delayed_output_pic; + + /** + * memory management control operations buffer. + */ + MMCO mmco[MAX_MMCO_COUNT]; + int mmco_index; + + int long_ref_count; ///< number of actual long term references + int short_ref_count; ///< number of actual short term references + + //data partitioning + GetBitContext intra_gb; + GetBitContext inter_gb; + GetBitContext *intra_gb_ptr; + GetBitContext *inter_gb_ptr; + + DECLARE_ALIGNED_8(DCTELEM, mb[16*24]); + + /** + * Cabac + */ + CABACContext cabac; + uint8_t cabac_state[460]; + int cabac_init_idc; + + /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */ + uint16_t *cbp_table; + int top_cbp; + int left_cbp; + /* chroma_pred_mode for i4x4 or i16x16, else 0 */ + uint8_t *chroma_pred_mode_table; + int last_qscale_diff; + int16_t (*mvd_table[2])[2]; + DECLARE_ALIGNED_8(int16_t, mvd_cache[2][5*8][2]); + uint8_t *direct_table; + uint8_t direct_cache[5*8]; + + uint8_t zigzag_scan[16]; + uint8_t field_scan[16]; + uint8_t zigzag_scan8x8[64]; + uint8_t zigzag_scan8x8_cavlc[64]; + const uint8_t *zigzag_scan_q0; + const uint8_t *field_scan_q0; + const uint8_t *zigzag_scan8x8_q0; + const uint8_t *zigzag_scan8x8_cavlc_q0; + + int x264_build; +}H264Context; + +static VLC coeff_token_vlc[4]; +static VLC chroma_dc_coeff_token_vlc; + +static VLC total_zeros_vlc[15]; +static VLC chroma_dc_total_zeros_vlc[3]; + +static VLC run_vlc[6]; +static VLC run7_vlc; + +static void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp); +static void svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc); +static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize); + +static always_inline uint32_t pack16to32(int a, int b){ +#ifdef WORDS_BIGENDIAN + return (b&0xFFFF) + (a<<16); +#else + return (a&0xFFFF) + (b<<16); +#endif +} + +/** + * fill a rectangle. + * @param h height of the rectangle, should be a constant + * @param w width of the rectangle, should be a constant + * @param size the size of val (1 or 4), should be a constant + */ +static always_inline void fill_rectangle(void *vp, int w, int h, int stride, uint32_t val, int size){ + uint8_t *p= (uint8_t*)vp; + assert(size==1 || size==4); + + w *= size; + stride *= size; + + assert((((long)vp)&(FFMIN(w, STRIDE_ALIGN)-1)) == 0); + assert((stride&(w-1))==0); +//FIXME check what gcc generates for 64 bit on x86 and possibly write a 32 bit ver of it + if(w==2 && h==2){ + *(uint16_t*)(p + 0)= + *(uint16_t*)(p + stride)= size==4 ? val : val*0x0101; + }else if(w==2 && h==4){ + *(uint16_t*)(p + 0*stride)= + *(uint16_t*)(p + 1*stride)= + *(uint16_t*)(p + 2*stride)= + *(uint16_t*)(p + 3*stride)= size==4 ? val : val*0x0101; + }else if(w==4 && h==1){ + *(uint32_t*)(p + 0*stride)= size==4 ? val : val*0x01010101; + }else if(w==4 && h==2){ + *(uint32_t*)(p + 0*stride)= + *(uint32_t*)(p + 1*stride)= size==4 ? val : val*0x01010101; + }else if(w==4 && h==4){ + *(uint32_t*)(p + 0*stride)= + *(uint32_t*)(p + 1*stride)= + *(uint32_t*)(p + 2*stride)= + *(uint32_t*)(p + 3*stride)= size==4 ? val : val*0x01010101; + }else if(w==8 && h==1){ + *(uint32_t*)(p + 0)= + *(uint32_t*)(p + 4)= size==4 ? val : val*0x01010101; + }else if(w==8 && h==2){ + *(uint32_t*)(p + 0 + 0*stride)= + *(uint32_t*)(p + 4 + 0*stride)= + *(uint32_t*)(p + 0 + 1*stride)= + *(uint32_t*)(p + 4 + 1*stride)= size==4 ? val : val*0x01010101; + }else if(w==8 && h==4){ + *(uint64_t*)(p + 0*stride)= + *(uint64_t*)(p + 1*stride)= + *(uint64_t*)(p + 2*stride)= + *(uint64_t*)(p + 3*stride)= size==4 ? val*0x0100000001ULL : val*0x0101010101010101ULL; + }else if(w==16 && h==2){ + *(uint64_t*)(p + 0+0*stride)= + *(uint64_t*)(p + 8+0*stride)= + *(uint64_t*)(p + 0+1*stride)= + *(uint64_t*)(p + 8+1*stride)= size==4 ? val*0x0100000001ULL : val*0x0101010101010101ULL; + }else if(w==16 && h==4){ + *(uint64_t*)(p + 0+0*stride)= + *(uint64_t*)(p + 8+0*stride)= + *(uint64_t*)(p + 0+1*stride)= + *(uint64_t*)(p + 8+1*stride)= + *(uint64_t*)(p + 0+2*stride)= + *(uint64_t*)(p + 8+2*stride)= + *(uint64_t*)(p + 0+3*stride)= + *(uint64_t*)(p + 8+3*stride)= size==4 ? val*0x0100000001ULL : val*0x0101010101010101ULL; + }else + assert(0); +} + +static void fill_caches(H264Context *h, int mb_type, int for_deblock){ + MpegEncContext * const s = &h->s; + const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; + int topleft_xy, top_xy, topright_xy, left_xy[2]; + int topleft_type, top_type, topright_type, left_type[2]; + int left_block[8]; + int i; + + //FIXME deblocking can skip fill_caches much of the time with multiple slices too. + // the actual condition is whether we're on the edge of a slice, + // and even then the intra and nnz parts are unnecessary. + if(for_deblock && h->slice_num == 1) + return; + + //wow what a mess, why didn't they simplify the interlacing&intra stuff, i can't imagine that these complex rules are worth it + + top_xy = mb_xy - s->mb_stride; + topleft_xy = top_xy - 1; + topright_xy= top_xy + 1; + left_xy[1] = left_xy[0] = mb_xy-1; + left_block[0]= 0; + left_block[1]= 1; + left_block[2]= 2; + left_block[3]= 3; + left_block[4]= 7; + left_block[5]= 10; + left_block[6]= 8; + left_block[7]= 11; + if(h->mb_aff_frame){ + const int pair_xy = s->mb_x + (s->mb_y & ~1)*s->mb_stride; + const int top_pair_xy = pair_xy - s->mb_stride; + const int topleft_pair_xy = top_pair_xy - 1; + const int topright_pair_xy = top_pair_xy + 1; + const int topleft_mb_frame_flag = !IS_INTERLACED(s->current_picture.mb_type[topleft_pair_xy]); + const int top_mb_frame_flag = !IS_INTERLACED(s->current_picture.mb_type[top_pair_xy]); + const int topright_mb_frame_flag = !IS_INTERLACED(s->current_picture.mb_type[topright_pair_xy]); + const int left_mb_frame_flag = !IS_INTERLACED(s->current_picture.mb_type[pair_xy-1]); + const int curr_mb_frame_flag = !IS_INTERLACED(mb_type); + const int bottom = (s->mb_y & 1); + tprintf("fill_caches: curr_mb_frame_flag:%d, left_mb_frame_flag:%d, topleft_mb_frame_flag:%d, top_mb_frame_flag:%d, topright_mb_frame_flag:%d\n", curr_mb_frame_flag, left_mb_frame_flag, topleft_mb_frame_flag, top_mb_frame_flag, topright_mb_frame_flag); + if (bottom + ? !curr_mb_frame_flag // bottom macroblock + : (!curr_mb_frame_flag && !top_mb_frame_flag) // top macroblock + ) { + top_xy -= s->mb_stride; + } + if (bottom + ? !curr_mb_frame_flag // bottom macroblock + : (!curr_mb_frame_flag && !topleft_mb_frame_flag) // top macroblock + ) { + topleft_xy -= s->mb_stride; + } + if (bottom + ? !curr_mb_frame_flag // bottom macroblock + : (!curr_mb_frame_flag && !topright_mb_frame_flag) // top macroblock + ) { + topright_xy -= s->mb_stride; + } + if (left_mb_frame_flag != curr_mb_frame_flag) { + left_xy[1] = left_xy[0] = pair_xy - 1; + if (curr_mb_frame_flag) { + if (bottom) { + left_block[0]= 2; + left_block[1]= 2; + left_block[2]= 3; + left_block[3]= 3; + left_block[4]= 8; + left_block[5]= 11; + left_block[6]= 8; + left_block[7]= 11; + } else { + left_block[0]= 0; + left_block[1]= 0; + left_block[2]= 1; + left_block[3]= 1; + left_block[4]= 7; + left_block[5]= 10; + left_block[6]= 7; + left_block[7]= 10; + } + } else { + left_xy[1] += s->mb_stride; + //left_block[0]= 0; + left_block[1]= 2; + left_block[2]= 0; + left_block[3]= 2; + //left_block[4]= 7; + left_block[5]= 10; + left_block[6]= 7; + left_block[7]= 10; + } + } + } + + h->top_mb_xy = top_xy; + h->left_mb_xy[0] = left_xy[0]; + h->left_mb_xy[1] = left_xy[1]; + if(for_deblock){ + topleft_type = h->slice_table[topleft_xy ] < 255 ? s->current_picture.mb_type[topleft_xy] : 0; + top_type = h->slice_table[top_xy ] < 255 ? s->current_picture.mb_type[top_xy] : 0; + topright_type= h->slice_table[topright_xy] < 255 ? s->current_picture.mb_type[topright_xy]: 0; + left_type[0] = h->slice_table[left_xy[0] ] < 255 ? s->current_picture.mb_type[left_xy[0]] : 0; + left_type[1] = h->slice_table[left_xy[1] ] < 255 ? s->current_picture.mb_type[left_xy[1]] : 0; + }else{ + topleft_type = h->slice_table[topleft_xy ] == h->slice_num ? s->current_picture.mb_type[topleft_xy] : 0; + top_type = h->slice_table[top_xy ] == h->slice_num ? s->current_picture.mb_type[top_xy] : 0; + topright_type= h->slice_table[topright_xy] == h->slice_num ? s->current_picture.mb_type[topright_xy]: 0; + left_type[0] = h->slice_table[left_xy[0] ] == h->slice_num ? s->current_picture.mb_type[left_xy[0]] : 0; + left_type[1] = h->slice_table[left_xy[1] ] == h->slice_num ? s->current_picture.mb_type[left_xy[1]] : 0; + } + + if(IS_INTRA(mb_type)){ + h->topleft_samples_available= + h->top_samples_available= + h->left_samples_available= 0xFFFF; + h->topright_samples_available= 0xEEEA; + + if(!IS_INTRA(top_type) && (top_type==0 || h->pps.constrained_intra_pred)){ + h->topleft_samples_available= 0xB3FF; + h->top_samples_available= 0x33FF; + h->topright_samples_available= 0x26EA; + } + for(i=0; i<2; i++){ + if(!IS_INTRA(left_type[i]) && (left_type[i]==0 || h->pps.constrained_intra_pred)){ + h->topleft_samples_available&= 0xDF5F; + h->left_samples_available&= 0x5F5F; + } + } + + if(!IS_INTRA(topleft_type) && (topleft_type==0 || h->pps.constrained_intra_pred)) + h->topleft_samples_available&= 0x7FFF; + + if(!IS_INTRA(topright_type) && (topright_type==0 || h->pps.constrained_intra_pred)) + h->topright_samples_available&= 0xFBFF; + + if(IS_INTRA4x4(mb_type)){ + if(IS_INTRA4x4(top_type)){ + h->intra4x4_pred_mode_cache[4+8*0]= h->intra4x4_pred_mode[top_xy][4]; + h->intra4x4_pred_mode_cache[5+8*0]= h->intra4x4_pred_mode[top_xy][5]; + h->intra4x4_pred_mode_cache[6+8*0]= h->intra4x4_pred_mode[top_xy][6]; + h->intra4x4_pred_mode_cache[7+8*0]= h->intra4x4_pred_mode[top_xy][3]; + }else{ + int pred; + if(!top_type || (IS_INTER(top_type) && h->pps.constrained_intra_pred)) + pred= -1; + else{ + pred= 2; + } + h->intra4x4_pred_mode_cache[4+8*0]= + h->intra4x4_pred_mode_cache[5+8*0]= + h->intra4x4_pred_mode_cache[6+8*0]= + h->intra4x4_pred_mode_cache[7+8*0]= pred; + } + for(i=0; i<2; i++){ + if(IS_INTRA4x4(left_type[i])){ + h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[0+2*i]]; + h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[1+2*i]]; + }else{ + int pred; + if(!left_type[i] || (IS_INTER(left_type[i]) && h->pps.constrained_intra_pred)) + pred= -1; + else{ + pred= 2; + } + h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= + h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= pred; + } + } + } + } + + +/* +0 . T T. T T T T +1 L . .L . . . . +2 L . .L . . . . +3 . T TL . . . . +4 L . .L . . . . +5 L . .. . . . . +*/ +//FIXME constraint_intra_pred & partitioning & nnz (lets hope this is just a typo in the spec) + if(top_type){ + h->non_zero_count_cache[4+8*0]= h->non_zero_count[top_xy][4]; + h->non_zero_count_cache[5+8*0]= h->non_zero_count[top_xy][5]; + h->non_zero_count_cache[6+8*0]= h->non_zero_count[top_xy][6]; + h->non_zero_count_cache[7+8*0]= h->non_zero_count[top_xy][3]; + + h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][9]; + h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][8]; + + h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][12]; + h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][11]; + + }else{ + h->non_zero_count_cache[4+8*0]= + h->non_zero_count_cache[5+8*0]= + h->non_zero_count_cache[6+8*0]= + h->non_zero_count_cache[7+8*0]= + + h->non_zero_count_cache[1+8*0]= + h->non_zero_count_cache[2+8*0]= + + h->non_zero_count_cache[1+8*3]= + h->non_zero_count_cache[2+8*3]= h->pps.cabac && !IS_INTRA(mb_type) ? 0 : 64; + + } + + for (i=0; i<2; i++) { + if(left_type[i]){ + h->non_zero_count_cache[3+8*1 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[0+2*i]]; + h->non_zero_count_cache[3+8*2 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[1+2*i]]; + h->non_zero_count_cache[0+8*1 + 8*i]= h->non_zero_count[left_xy[i]][left_block[4+2*i]]; + h->non_zero_count_cache[0+8*4 + 8*i]= h->non_zero_count[left_xy[i]][left_block[5+2*i]]; + }else{ + h->non_zero_count_cache[3+8*1 + 2*8*i]= + h->non_zero_count_cache[3+8*2 + 2*8*i]= + h->non_zero_count_cache[0+8*1 + 8*i]= + h->non_zero_count_cache[0+8*4 + 8*i]= h->pps.cabac && !IS_INTRA(mb_type) ? 0 : 64; + } + } + + if( h->pps.cabac ) { + // top_cbp + if(top_type) { + h->top_cbp = h->cbp_table[top_xy]; + } else if(IS_INTRA(mb_type)) { + h->top_cbp = 0x1C0; + } else { + h->top_cbp = 0; + } + // left_cbp + if (left_type[0]) { + h->left_cbp = h->cbp_table[left_xy[0]] & 0x1f0; + } else if(IS_INTRA(mb_type)) { + h->left_cbp = 0x1C0; + } else { + h->left_cbp = 0; + } + if (left_type[0]) { + h->left_cbp |= ((h->cbp_table[left_xy[0]]>>((left_block[0]&(~1))+1))&0x1) << 1; + } + if (left_type[1]) { + h->left_cbp |= ((h->cbp_table[left_xy[1]]>>((left_block[2]&(~1))+1))&0x1) << 3; + } + } + +#if 1 + //FIXME direct mb can skip much of this + if(IS_INTER(mb_type) || IS_DIRECT(mb_type)){ + int list; + for(list=0; list<1+(h->slice_type==B_TYPE); list++){ + if(!USES_LIST(mb_type, list) && !IS_DIRECT(mb_type) && !h->deblocking_filter){ + /*if(!h->mv_cache_clean[list]){ + memset(h->mv_cache [list], 0, 8*5*2*sizeof(int16_t)); //FIXME clean only input? clean at all? + memset(h->ref_cache[list], PART_NOT_AVAILABLE, 8*5*sizeof(int8_t)); + h->mv_cache_clean[list]= 1; + }*/ + continue; + } + h->mv_cache_clean[list]= 0; + + if(USES_LIST(top_type, list)){ + const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride; + const int b8_xy= h->mb2b8_xy[top_xy] + h->b8_stride; + *(uint32_t*)h->mv_cache[list][scan8[0] + 0 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 0]; + *(uint32_t*)h->mv_cache[list][scan8[0] + 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 1]; + *(uint32_t*)h->mv_cache[list][scan8[0] + 2 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 2]; + *(uint32_t*)h->mv_cache[list][scan8[0] + 3 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 3]; + h->ref_cache[list][scan8[0] + 0 - 1*8]= + h->ref_cache[list][scan8[0] + 1 - 1*8]= s->current_picture.ref_index[list][b8_xy + 0]; + h->ref_cache[list][scan8[0] + 2 - 1*8]= + h->ref_cache[list][scan8[0] + 3 - 1*8]= s->current_picture.ref_index[list][b8_xy + 1]; + }else{ + *(uint32_t*)h->mv_cache [list][scan8[0] + 0 - 1*8]= + *(uint32_t*)h->mv_cache [list][scan8[0] + 1 - 1*8]= + *(uint32_t*)h->mv_cache [list][scan8[0] + 2 - 1*8]= + *(uint32_t*)h->mv_cache [list][scan8[0] + 3 - 1*8]= 0; + *(uint32_t*)&h->ref_cache[list][scan8[0] + 0 - 1*8]= ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE)&0xFF)*0x01010101; + } + + //FIXME unify cleanup or sth + if(USES_LIST(left_type[0], list)){ + const int b_xy= h->mb2b_xy[left_xy[0]] + 3; + const int b8_xy= h->mb2b8_xy[left_xy[0]] + 1; + *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 0*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[0]]; + *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[1]]; + h->ref_cache[list][scan8[0] - 1 + 0*8]= + h->ref_cache[list][scan8[0] - 1 + 1*8]= s->current_picture.ref_index[list][b8_xy + h->b8_stride*(left_block[0]>>1)]; + }else{ + *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 0*8]= + *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 1*8]= 0; + h->ref_cache[list][scan8[0] - 1 + 0*8]= + h->ref_cache[list][scan8[0] - 1 + 1*8]= left_type[0] ? LIST_NOT_USED : PART_NOT_AVAILABLE; + } + + if(USES_LIST(left_type[1], list)){ + const int b_xy= h->mb2b_xy[left_xy[1]] + 3; + const int b8_xy= h->mb2b8_xy[left_xy[1]] + 1; + *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 2*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[2]]; + *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 3*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[3]]; + h->ref_cache[list][scan8[0] - 1 + 2*8]= + h->ref_cache[list][scan8[0] - 1 + 3*8]= s->current_picture.ref_index[list][b8_xy + h->b8_stride*(left_block[2]>>1)]; + }else{ + *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 2*8]= + *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 3*8]= 0; + h->ref_cache[list][scan8[0] - 1 + 2*8]= + h->ref_cache[list][scan8[0] - 1 + 3*8]= left_type[0] ? LIST_NOT_USED : PART_NOT_AVAILABLE; + assert((!left_type[0]) == (!left_type[1])); + } + + if(for_deblock || (IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred)) + continue; + + if(USES_LIST(topleft_type, list)){ + const int b_xy = h->mb2b_xy[topleft_xy] + 3 + 3*h->b_stride; + const int b8_xy= h->mb2b8_xy[topleft_xy] + 1 + h->b8_stride; + *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy]; + h->ref_cache[list][scan8[0] - 1 - 1*8]= s->current_picture.ref_index[list][b8_xy]; + }else{ + *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= 0; + h->ref_cache[list][scan8[0] - 1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; + } + + if(USES_LIST(topright_type, list)){ + const int b_xy= h->mb2b_xy[topright_xy] + 3*h->b_stride; + const int b8_xy= h->mb2b8_xy[topright_xy] + h->b8_stride; + *(uint32_t*)h->mv_cache[list][scan8[0] + 4 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy]; + h->ref_cache[list][scan8[0] + 4 - 1*8]= s->current_picture.ref_index[list][b8_xy]; + }else{ + *(uint32_t*)h->mv_cache [list][scan8[0] + 4 - 1*8]= 0; + h->ref_cache[list][scan8[0] + 4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE; + } + + + h->ref_cache[list][scan8[5 ]+1] = + h->ref_cache[list][scan8[7 ]+1] = + h->ref_cache[list][scan8[13]+1] = //FIXME remove past 3 (init somewhere else) + h->ref_cache[list][scan8[4 ]] = + h->ref_cache[list][scan8[12]] = PART_NOT_AVAILABLE; + *(uint32_t*)h->mv_cache [list][scan8[5 ]+1]= + *(uint32_t*)h->mv_cache [list][scan8[7 ]+1]= + *(uint32_t*)h->mv_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewhere else) + *(uint32_t*)h->mv_cache [list][scan8[4 ]]= + *(uint32_t*)h->mv_cache [list][scan8[12]]= 0; + + if( h->pps.cabac ) { + /* XXX beurk, Load mvd */ + if(USES_LIST(topleft_type, list)){ + const int b_xy = h->mb2b_xy[topleft_xy] + 3 + 3*h->b_stride; + *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy]; + }else{ + *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 - 1*8]= 0; + } + + if(USES_LIST(top_type, list)){ + const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride; + *(uint32_t*)h->mvd_cache[list][scan8[0] + 0 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 0]; + *(uint32_t*)h->mvd_cache[list][scan8[0] + 1 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 1]; + *(uint32_t*)h->mvd_cache[list][scan8[0] + 2 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 2]; + *(uint32_t*)h->mvd_cache[list][scan8[0] + 3 - 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + 3]; + }else{ + *(uint32_t*)h->mvd_cache [list][scan8[0] + 0 - 1*8]= + *(uint32_t*)h->mvd_cache [list][scan8[0] + 1 - 1*8]= + *(uint32_t*)h->mvd_cache [list][scan8[0] + 2 - 1*8]= + *(uint32_t*)h->mvd_cache [list][scan8[0] + 3 - 1*8]= 0; + } + if(USES_LIST(left_type[0], list)){ + const int b_xy= h->mb2b_xy[left_xy[0]] + 3; + *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 0*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[0]]; + *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 1*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[1]]; + }else{ + *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 0*8]= + *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 1*8]= 0; + } + if(USES_LIST(left_type[1], list)){ + const int b_xy= h->mb2b_xy[left_xy[1]] + 3; + *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 2*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[2]]; + *(uint32_t*)h->mvd_cache[list][scan8[0] - 1 + 3*8]= *(uint32_t*)h->mvd_table[list][b_xy + h->b_stride*left_block[3]]; + }else{ + *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 2*8]= + *(uint32_t*)h->mvd_cache [list][scan8[0] - 1 + 3*8]= 0; + } + *(uint32_t*)h->mvd_cache [list][scan8[5 ]+1]= + *(uint32_t*)h->mvd_cache [list][scan8[7 ]+1]= + *(uint32_t*)h->mvd_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewhere else) + *(uint32_t*)h->mvd_cache [list][scan8[4 ]]= + *(uint32_t*)h->mvd_cache [list][scan8[12]]= 0; + + if(h->slice_type == B_TYPE){ + fill_rectangle(&h->direct_cache[scan8[0]], 4, 4, 8, 0, 1); + + if(IS_DIRECT(top_type)){ + *(uint32_t*)&h->direct_cache[scan8[0] - 1*8]= 0x01010101; + }else if(IS_8X8(top_type)){ + int b8_xy = h->mb2b8_xy[top_xy] + h->b8_stride; + h->direct_cache[scan8[0] + 0 - 1*8]= h->direct_table[b8_xy]; + h->direct_cache[scan8[0] + 2 - 1*8]= h->direct_table[b8_xy + 1]; + }else{ + *(uint32_t*)&h->direct_cache[scan8[0] - 1*8]= 0; + } + + //FIXME interlacing + if(IS_DIRECT(left_type[0])){ + h->direct_cache[scan8[0] - 1 + 0*8]= + h->direct_cache[scan8[0] - 1 + 2*8]= 1; + }else if(IS_8X8(left_type[0])){ + int b8_xy = h->mb2b8_xy[left_xy[0]] + 1; + h->direct_cache[scan8[0] - 1 + 0*8]= h->direct_table[b8_xy]; + h->direct_cache[scan8[0] - 1 + 2*8]= h->direct_table[b8_xy + h->b8_stride]; + }else{ + h->direct_cache[scan8[0] - 1 + 0*8]= + h->direct_cache[scan8[0] - 1 + 2*8]= 0; + } + } + } + } + } +#endif + + h->neighbor_transform_size= !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[0]); +} + +static inline void write_back_intra_pred_mode(H264Context *h){ + MpegEncContext * const s = &h->s; + const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; + + h->intra4x4_pred_mode[mb_xy][0]= h->intra4x4_pred_mode_cache[7+8*1]; + h->intra4x4_pred_mode[mb_xy][1]= h->intra4x4_pred_mode_cache[7+8*2]; + h->intra4x4_pred_mode[mb_xy][2]= h->intra4x4_pred_mode_cache[7+8*3]; + h->intra4x4_pred_mode[mb_xy][3]= h->intra4x4_pred_mode_cache[7+8*4]; + h->intra4x4_pred_mode[mb_xy][4]= h->intra4x4_pred_mode_cache[4+8*4]; + h->intra4x4_pred_mode[mb_xy][5]= h->intra4x4_pred_mode_cache[5+8*4]; + h->intra4x4_pred_mode[mb_xy][6]= h->intra4x4_pred_mode_cache[6+8*4]; +} + +/** + * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. + */ +static inline int check_intra4x4_pred_mode(H264Context *h){ + MpegEncContext * const s = &h->s; + static const int8_t top [12]= {-1, 0,LEFT_DC_PRED,-1,-1,-1,-1,-1, 0}; + static const int8_t left[12]= { 0,-1, TOP_DC_PRED, 0,-1,-1,-1, 0,-1,DC_128_PRED}; + int i; + + if(!(h->top_samples_available&0x8000)){ + for(i=0; i<4; i++){ + int status= top[ h->intra4x4_pred_mode_cache[scan8[0] + i] ]; + if(status<0){ + av_log(h->s.avctx, AV_LOG_ERROR, "top block unavailable for requested intra4x4 mode %d at %d %d\n", status, s->mb_x, s->mb_y); + return -1; + } else if(status){ + h->intra4x4_pred_mode_cache[scan8[0] + i]= status; + } + } + } + + if(!(h->left_samples_available&0x8000)){ + for(i=0; i<4; i++){ + int status= left[ h->intra4x4_pred_mode_cache[scan8[0] + 8*i] ]; + if(status<0){ + av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra4x4 mode %d at %d %d\n", status, s->mb_x, s->mb_y); + return -1; + } else if(status){ + h->intra4x4_pred_mode_cache[scan8[0] + 8*i]= status; + } + } + } + + return 0; +} //FIXME cleanup like next + +/** + * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. + */ +static inline int check_intra_pred_mode(H264Context *h, int mode){ + MpegEncContext * const s = &h->s; + static const int8_t top [7]= {LEFT_DC_PRED8x8, 1,-1,-1}; + static const int8_t left[7]= { TOP_DC_PRED8x8,-1, 2,-1,DC_128_PRED8x8}; + + if(mode < 0 || mode > 6) { + av_log(h->s.avctx, AV_LOG_ERROR, "out of range intra chroma pred mode at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + if(!(h->top_samples_available&0x8000)){ + mode= top[ mode ]; + if(mode<0){ + av_log(h->s.avctx, AV_LOG_ERROR, "top block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + } + + if(!(h->left_samples_available&0x8000)){ + mode= left[ mode ]; + if(mode<0){ + av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + } + + return mode; +} + +/** + * gets the predicted intra4x4 prediction mode. + */ +static inline int pred_intra_mode(H264Context *h, int n){ + const int index8= scan8[n]; + const int left= h->intra4x4_pred_mode_cache[index8 - 1]; + const int top = h->intra4x4_pred_mode_cache[index8 - 8]; + const int min= FFMIN(left, top); + + tprintf("mode:%d %d min:%d\n", left ,top, min); + + if(min<0) return DC_PRED; + else return min; +} + +static inline void write_back_non_zero_count(H264Context *h){ + MpegEncContext * const s = &h->s; + const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; + + h->non_zero_count[mb_xy][0]= h->non_zero_count_cache[7+8*1]; + h->non_zero_count[mb_xy][1]= h->non_zero_count_cache[7+8*2]; + h->non_zero_count[mb_xy][2]= h->non_zero_count_cache[7+8*3]; + h->non_zero_count[mb_xy][3]= h->non_zero_count_cache[7+8*4]; + h->non_zero_count[mb_xy][4]= h->non_zero_count_cache[4+8*4]; + h->non_zero_count[mb_xy][5]= h->non_zero_count_cache[5+8*4]; + h->non_zero_count[mb_xy][6]= h->non_zero_count_cache[6+8*4]; + + h->non_zero_count[mb_xy][9]= h->non_zero_count_cache[1+8*2]; + h->non_zero_count[mb_xy][8]= h->non_zero_count_cache[2+8*2]; + h->non_zero_count[mb_xy][7]= h->non_zero_count_cache[2+8*1]; + + h->non_zero_count[mb_xy][12]=h->non_zero_count_cache[1+8*5]; + h->non_zero_count[mb_xy][11]=h->non_zero_count_cache[2+8*5]; + h->non_zero_count[mb_xy][10]=h->non_zero_count_cache[2+8*4]; +} + +/** + * gets the predicted number of non zero coefficients. + * @param n block index + */ +static inline int pred_non_zero_count(H264Context *h, int n){ + const int index8= scan8[n]; + const int left= h->non_zero_count_cache[index8 - 1]; + const int top = h->non_zero_count_cache[index8 - 8]; + int i= left + top; + + if(i<64) i= (i+1)>>1; + + tprintf("pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31); + + return i&31; +} + +static inline int fetch_diagonal_mv(H264Context *h, const int16_t **C, int i, int list, int part_width){ + const int topright_ref= h->ref_cache[list][ i - 8 + part_width ]; + + if(topright_ref != PART_NOT_AVAILABLE){ + *C= h->mv_cache[list][ i - 8 + part_width ]; + return topright_ref; + }else{ + tprintf("topright MV not available\n"); + + *C= h->mv_cache[list][ i - 8 - 1 ]; + return h->ref_cache[list][ i - 8 - 1 ]; + } +} + +/** + * gets the predicted MV. + * @param n the block index + * @param part_width the width of the partition (4, 8,16) -> (1, 2, 4) + * @param mx the x component of the predicted motion vector + * @param my the y component of the predicted motion vector + */ +static inline void pred_motion(H264Context * const h, int n, int part_width, int list, int ref, int * const mx, int * const my){ + const int index8= scan8[n]; + const int top_ref= h->ref_cache[list][ index8 - 8 ]; + const int left_ref= h->ref_cache[list][ index8 - 1 ]; + const int16_t * const A= h->mv_cache[list][ index8 - 1 ]; + const int16_t * const B= h->mv_cache[list][ index8 - 8 ]; + const int16_t * C; + int diagonal_ref, match_count; + + assert(part_width==1 || part_width==2 || part_width==4); + +/* mv_cache + B . . A T T T T + U . . L . . , . + U . . L . . . . + U . . L . . , . + . . . L . . . . +*/ + + diagonal_ref= fetch_diagonal_mv(h, &C, index8, list, part_width); + match_count= (diagonal_ref==ref) + (top_ref==ref) + (left_ref==ref); + tprintf("pred_motion match_count=%d\n", match_count); + if(match_count > 1){ //most common + *mx= mid_pred(A[0], B[0], C[0]); + *my= mid_pred(A[1], B[1], C[1]); + }else if(match_count==1){ + if(left_ref==ref){ + *mx= A[0]; + *my= A[1]; + }else if(top_ref==ref){ + *mx= B[0]; + *my= B[1]; + }else{ + *mx= C[0]; + *my= C[1]; + } + }else{ + if(top_ref == PART_NOT_AVAILABLE && diagonal_ref == PART_NOT_AVAILABLE && left_ref != PART_NOT_AVAILABLE){ + *mx= A[0]; + *my= A[1]; + }else{ + *mx= mid_pred(A[0], B[0], C[0]); + *my= mid_pred(A[1], B[1], C[1]); + } + } + + tprintf("pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d\n", top_ref, B[0], B[1], diagonal_ref, C[0], C[1], left_ref, A[0], A[1], ref, *mx, *my, h->s.mb_x, h->s.mb_y, n, list); +} + +/** + * gets the directionally predicted 16x8 MV. + * @param n the block index + * @param mx the x component of the predicted motion vector + * @param my the y component of the predicted motion vector + */ +static inline void pred_16x8_motion(H264Context * const h, int n, int list, int ref, int * const mx, int * const my){ + if(n==0){ + const int top_ref= h->ref_cache[list][ scan8[0] - 8 ]; + const int16_t * const B= h->mv_cache[list][ scan8[0] - 8 ]; + + tprintf("pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", top_ref, B[0], B[1], h->s.mb_x, h->s.mb_y, n, list); + + if(top_ref == ref){ + *mx= B[0]; + *my= B[1]; + return; + } + }else{ + const int left_ref= h->ref_cache[list][ scan8[8] - 1 ]; + const int16_t * const A= h->mv_cache[list][ scan8[8] - 1 ]; + + tprintf("pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list); + + if(left_ref == ref){ + *mx= A[0]; + *my= A[1]; + return; + } + } + + //RARE + pred_motion(h, n, 4, list, ref, mx, my); +} + +/** + * gets the directionally predicted 8x16 MV. + * @param n the block index + * @param mx the x component of the predicted motion vector + * @param my the y component of the predicted motion vector + */ +static inline void pred_8x16_motion(H264Context * const h, int n, int list, int ref, int * const mx, int * const my){ + if(n==0){ + const int left_ref= h->ref_cache[list][ scan8[0] - 1 ]; + const int16_t * const A= h->mv_cache[list][ scan8[0] - 1 ]; + + tprintf("pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list); + + if(left_ref == ref){ + *mx= A[0]; + *my= A[1]; + return; + } + }else{ + const int16_t * C; + int diagonal_ref; + + diagonal_ref= fetch_diagonal_mv(h, &C, scan8[4], list, 2); + + tprintf("pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", diagonal_ref, C[0], C[1], h->s.mb_x, h->s.mb_y, n, list); + + if(diagonal_ref == ref){ + *mx= C[0]; + *my= C[1]; + return; + } + } + + //RARE + pred_motion(h, n, 2, list, ref, mx, my); +} + +static inline void pred_pskip_motion(H264Context * const h, int * const mx, int * const my){ + const int top_ref = h->ref_cache[0][ scan8[0] - 8 ]; + const int left_ref= h->ref_cache[0][ scan8[0] - 1 ]; + + tprintf("pred_pskip: (%d) (%d) at %2d %2d\n", top_ref, left_ref, h->s.mb_x, h->s.mb_y); + + if(top_ref == PART_NOT_AVAILABLE || left_ref == PART_NOT_AVAILABLE + || (top_ref == 0 && *(uint32_t*)h->mv_cache[0][ scan8[0] - 8 ] == 0) + || (left_ref == 0 && *(uint32_t*)h->mv_cache[0][ scan8[0] - 1 ] == 0)){ + + *mx = *my = 0; + return; + } + + pred_motion(h, 0, 4, 0, 0, mx, my); + + return; +} + +static inline void direct_dist_scale_factor(H264Context * const h){ + const int poc = h->s.current_picture_ptr->poc; + const int poc1 = h->ref_list[1][0].poc; + int i; + for(i=0; iref_count[0]; i++){ + int poc0 = h->ref_list[0][i].poc; + int td = clip(poc1 - poc0, -128, 127); + if(td == 0 /* FIXME || pic0 is a long-term ref */){ + h->dist_scale_factor[i] = 256; + }else{ + int tb = clip(poc - poc0, -128, 127); + int tx = (16384 + (ABS(td) >> 1)) / td; + h->dist_scale_factor[i] = clip((tb*tx + 32) >> 6, -1024, 1023); + } + } +} +static inline void direct_ref_list_init(H264Context * const h){ + MpegEncContext * const s = &h->s; + Picture * const ref1 = &h->ref_list[1][0]; + Picture * const cur = s->current_picture_ptr; + int list, i, j; + if(cur->pict_type == I_TYPE) + cur->ref_count[0] = 0; + if(cur->pict_type != B_TYPE) + cur->ref_count[1] = 0; + for(list=0; list<2; list++){ + cur->ref_count[list] = h->ref_count[list]; + for(j=0; jref_count[list]; j++) + cur->ref_poc[list][j] = h->ref_list[list][j].poc; + } + if(cur->pict_type != B_TYPE || h->direct_spatial_mv_pred) + return; + for(list=0; list<2; list++){ + for(i=0; iref_count[list]; i++){ + const int poc = ref1->ref_poc[list][i]; + h->map_col_to_list0[list][i] = 0; /* bogus; fills in for missing frames */ + for(j=0; jref_count[list]; j++) + if(h->ref_list[list][j].poc == poc){ + h->map_col_to_list0[list][i] = j; + break; + } + } + } +} + +static inline void pred_direct_motion(H264Context * const h, int *mb_type){ + MpegEncContext * const s = &h->s; + const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; + const int b8_xy = 2*s->mb_x + 2*s->mb_y*h->b8_stride; + const int b4_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; + const int mb_type_col = h->ref_list[1][0].mb_type[mb_xy]; + const int16_t (*l1mv0)[2] = (const int16_t (*)[2]) &h->ref_list[1][0].motion_val[0][b4_xy]; + const int16_t (*l1mv1)[2] = (const int16_t (*)[2]) &h->ref_list[1][0].motion_val[1][b4_xy]; + const int8_t *l1ref0 = &h->ref_list[1][0].ref_index[0][b8_xy]; + const int8_t *l1ref1 = &h->ref_list[1][0].ref_index[1][b8_xy]; + const int is_b8x8 = IS_8X8(*mb_type); + int sub_mb_type; + int i8, i4; + + if(IS_8X8(mb_type_col) && !h->sps.direct_8x8_inference_flag){ + /* FIXME save sub mb types from previous frames (or derive from MVs) + * so we know exactly what block size to use */ + sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */ + *mb_type = MB_TYPE_8x8|MB_TYPE_L0L1; + }else if(!is_b8x8 && (IS_16X16(mb_type_col) || IS_INTRA(mb_type_col))){ + sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ + *mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */ + }else{ + sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ + *mb_type = MB_TYPE_8x8|MB_TYPE_L0L1; + } + if(!is_b8x8) + *mb_type |= MB_TYPE_DIRECT2; + + tprintf("mb_type = %08x, sub_mb_type = %08x, is_b8x8 = %d, mb_type_col = %08x\n", *mb_type, sub_mb_type, is_b8x8, mb_type_col); + + if(h->direct_spatial_mv_pred){ + int ref[2]; + int mv[2][2]; + int list; + + /* ref = min(neighbors) */ + for(list=0; list<2; list++){ + int refa = h->ref_cache[list][scan8[0] - 1]; + int refb = h->ref_cache[list][scan8[0] - 8]; + int refc = h->ref_cache[list][scan8[0] - 8 + 4]; + if(refc == -2) + refc = h->ref_cache[list][scan8[0] - 8 - 1]; + ref[list] = refa; + if(ref[list] < 0 || (refb < ref[list] && refb >= 0)) + ref[list] = refb; + if(ref[list] < 0 || (refc < ref[list] && refc >= 0)) + ref[list] = refc; + if(ref[list] < 0) + ref[list] = -1; + } + + if(ref[0] < 0 && ref[1] < 0){ + ref[0] = ref[1] = 0; + mv[0][0] = mv[0][1] = + mv[1][0] = mv[1][1] = 0; + }else{ + for(list=0; list<2; list++){ + if(ref[list] >= 0) + pred_motion(h, 0, 4, list, ref[list], &mv[list][0], &mv[list][1]); + else + mv[list][0] = mv[list][1] = 0; + } + } + + if(ref[1] < 0){ + *mb_type &= ~MB_TYPE_P0L1; + sub_mb_type &= ~MB_TYPE_P0L1; + }else if(ref[0] < 0){ + *mb_type &= ~MB_TYPE_P0L0; + sub_mb_type &= ~MB_TYPE_P0L0; + } + + if(IS_16X16(*mb_type)){ + fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1); + fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1); + if(!IS_INTRA(mb_type_col) + && ( (l1ref0[0] == 0 && ABS(l1mv0[0][0]) <= 1 && ABS(l1mv0[0][1]) <= 1) + || (l1ref0[0] < 0 && l1ref1[0] == 0 && ABS(l1mv1[0][0]) <= 1 && ABS(l1mv1[0][1]) <= 1 + && (h->x264_build>33 || !h->x264_build)))){ + if(ref[0] > 0) + fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv[0][0],mv[0][1]), 4); + else + fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); + if(ref[1] > 0) + fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, pack16to32(mv[1][0],mv[1][1]), 4); + else + fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4); + }else{ + fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv[0][0],mv[0][1]), 4); + fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, pack16to32(mv[1][0],mv[1][1]), 4); + } + }else{ + for(i8=0; i8<4; i8++){ + const int x8 = i8&1; + const int y8 = i8>>1; + + if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) + continue; + h->sub_mb_type[i8] = sub_mb_type; + + fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mv[0][0],mv[0][1]), 4); + fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mv[1][0],mv[1][1]), 4); + fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[0], 1); + fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, (uint8_t)ref[1], 1); + + /* col_zero_flag */ + if(!IS_INTRA(mb_type_col) && ( l1ref0[x8 + y8*h->b8_stride] == 0 + || (l1ref0[x8 + y8*h->b8_stride] < 0 && l1ref1[x8 + y8*h->b8_stride] == 0 + && (h->x264_build>33 || !h->x264_build)))){ + const int16_t (*l1mv)[2]= l1ref0[x8 + y8*h->b8_stride] == 0 ? l1mv0 : l1mv1; + if(IS_SUB_8X8(sub_mb_type)){ + const int16_t *mv_col = l1mv[x8*3 + y8*3*h->b_stride]; + if(ABS(mv_col[0]) <= 1 && ABS(mv_col[1]) <= 1){ + if(ref[0] == 0) + fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); + if(ref[1] == 0) + fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); + } + }else + for(i4=0; i4<4; i4++){ + const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; + if(ABS(mv_col[0]) <= 1 && ABS(mv_col[1]) <= 1){ + if(ref[0] == 0) + *(uint32_t*)h->mv_cache[0][scan8[i8*4+i4]] = 0; + if(ref[1] == 0) + *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = 0; + } + } + } + } + } + }else{ /* direct temporal mv pred */ + if(IS_16X16(*mb_type)){ + fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1); + if(IS_INTRA(mb_type_col)){ + fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1); + fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); + fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, 0, 4); + }else{ + const int ref0 = l1ref0[0] >= 0 ? h->map_col_to_list0[0][l1ref0[0]] + : h->map_col_to_list0[1][l1ref1[0]]; + const int dist_scale_factor = h->dist_scale_factor[ref0]; + const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0]; + int mv_l0[2]; + mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8; + mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8; + fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref0, 1); + fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv_l0[0],mv_l0[1]), 4); + fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]), 4); + } + }else{ + for(i8=0; i8<4; i8++){ + const int x8 = i8&1; + const int y8 = i8>>1; + int ref0, dist_scale_factor; + const int16_t (*l1mv)[2]= l1mv0; + + if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) + continue; + h->sub_mb_type[i8] = sub_mb_type; + if(IS_INTRA(mb_type_col)){ + fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1); + fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); + fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); + fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); + continue; + } + + ref0 = l1ref0[x8 + y8*h->b8_stride]; + if(ref0 >= 0) + ref0 = h->map_col_to_list0[0][ref0]; + else{ + ref0 = h->map_col_to_list0[1][l1ref1[x8 + y8*h->b8_stride]]; + l1mv= l1mv1; + } + dist_scale_factor = h->dist_scale_factor[ref0]; + + fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); + fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); + if(IS_SUB_8X8(sub_mb_type)){ + const int16_t *mv_col = l1mv[x8*3 + y8*3*h->b_stride]; + int mx = (dist_scale_factor * mv_col[0] + 128) >> 8; + int my = (dist_scale_factor * mv_col[1] + 128) >> 8; + fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mx,my), 4); + fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mx-mv_col[0],my-mv_col[1]), 4); + }else + for(i4=0; i4<4; i4++){ + const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; + int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; + mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8; + mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8; + *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = + pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]); + } + } + } + } +} + +static inline void write_back_motion(H264Context *h, int mb_type){ + MpegEncContext * const s = &h->s; + const int b_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; + const int b8_xy= 2*s->mb_x + 2*s->mb_y*h->b8_stride; + int list; + + if(!USES_LIST(mb_type, 0)) + fill_rectangle(&s->current_picture.ref_index[0][b8_xy], 2, 2, h->b8_stride, (uint8_t)LIST_NOT_USED, 1); + + for(list=0; list<2; list++){ + int y; + if(!USES_LIST(mb_type, list)) + continue; + + for(y=0; y<4; y++){ + *(uint64_t*)s->current_picture.motion_val[list][b_xy + 0 + y*h->b_stride]= *(uint64_t*)h->mv_cache[list][scan8[0]+0 + 8*y]; + *(uint64_t*)s->current_picture.motion_val[list][b_xy + 2 + y*h->b_stride]= *(uint64_t*)h->mv_cache[list][scan8[0]+2 + 8*y]; + } + if( h->pps.cabac ) { + for(y=0; y<4; y++){ + *(uint64_t*)h->mvd_table[list][b_xy + 0 + y*h->b_stride]= *(uint64_t*)h->mvd_cache[list][scan8[0]+0 + 8*y]; + *(uint64_t*)h->mvd_table[list][b_xy + 2 + y*h->b_stride]= *(uint64_t*)h->mvd_cache[list][scan8[0]+2 + 8*y]; + } + } + + { + uint8_t *ref_index = &s->current_picture.ref_index[list][b8_xy]; + ref_index[0+0*h->b8_stride]= h->ref_cache[list][scan8[0]]; + ref_index[1+0*h->b8_stride]= h->ref_cache[list][scan8[4]]; + ref_index[0+1*h->b8_stride]= h->ref_cache[list][scan8[8]]; + ref_index[1+1*h->b8_stride]= h->ref_cache[list][scan8[12]]; + } + } + + if(h->slice_type == B_TYPE && h->pps.cabac){ + if(IS_8X8(mb_type)){ + uint8_t *direct_table = &h->direct_table[b8_xy]; + direct_table[1+0*h->b8_stride] = IS_DIRECT(h->sub_mb_type[1]) ? 1 : 0; + direct_table[0+1*h->b8_stride] = IS_DIRECT(h->sub_mb_type[2]) ? 1 : 0; + direct_table[1+1*h->b8_stride] = IS_DIRECT(h->sub_mb_type[3]) ? 1 : 0; + } + } +} + +/** + * Decodes a network abstraction layer unit. + * @param consumed is the number of bytes used as input + * @param length is the length of the array + * @param dst_length is the number of decoded bytes FIXME here or a decode rbsp tailing? + * @returns decoded bytes, might be src+1 if no escapes + */ +static uint8_t *decode_nal(H264Context *h, uint8_t *src, int *dst_length, int *consumed, int length){ + int i, si, di; + uint8_t *dst; + +// src[0]&0x80; //forbidden bit + h->nal_ref_idc= src[0]>>5; + h->nal_unit_type= src[0]&0x1F; + + src++; length--; +#if 0 + for(i=0; i0 && src[i-1]==0) i--; + if(i+2=length-1){ //no escaped 0 + *dst_length= length; + *consumed= length+1; //+1 for the header + return src; + } + + h->rbsp_buffer= av_fast_realloc(h->rbsp_buffer, &h->rbsp_buffer_size, length); + dst= h->rbsp_buffer; + +//printf("decoding esc\n"); + si=di=0; + while(si=0); + assert(dst_length>0); + + dst[0]= (h->nal_ref_idc<<5) + h->nal_unit_type; + + if(length==0) return 1; + + escape_count= 0; + for(i=0; i0 && src[i-1]==0) + i--; + if(i+2 dst_length) + return -1; + + //this should be damn rare (hopefully) + + h->rbsp_buffer= av_fast_realloc(h->rbsp_buffer, &h->rbsp_buffer_size, length + escape_count); + temp= h->rbsp_buffer; +//printf("encoding esc\n"); + + si= 0; + di= 0; + while(si < length){ + if(si+2>=1; + } + return 0; +} + +/** + * idct tranforms the 16 dc values and dequantize them. + * @param qp quantization parameter + */ +static void h264_luma_dc_dequant_idct_c(DCTELEM *block, int qp, int qmul){ +#define stride 16 + int i; + int temp[16]; //FIXME check if this is a good idea + static const int x_offset[4]={0, 1*stride, 4* stride, 5*stride}; + static const int y_offset[4]={0, 2*stride, 8* stride, 10*stride}; + +//memset(block, 64, 2*256); +//return; + for(i=0; i<4; i++){ + const int offset= y_offset[i]; + const int z0= block[offset+stride*0] + block[offset+stride*4]; + const int z1= block[offset+stride*0] - block[offset+stride*4]; + const int z2= block[offset+stride*1] - block[offset+stride*5]; + const int z3= block[offset+stride*1] + block[offset+stride*5]; + + temp[4*i+0]= z0+z3; + temp[4*i+1]= z1+z2; + temp[4*i+2]= z1-z2; + temp[4*i+3]= z0-z3; + } + + for(i=0; i<4; i++){ + const int offset= x_offset[i]; + const int z0= temp[4*0+i] + temp[4*2+i]; + const int z1= temp[4*0+i] - temp[4*2+i]; + const int z2= temp[4*1+i] - temp[4*3+i]; + const int z3= temp[4*1+i] + temp[4*3+i]; + + block[stride*0 +offset]= ((((z0 + z3)*qmul + 128 ) >> 8)); //FIXME think about merging this into decode_resdual + block[stride*2 +offset]= ((((z1 + z2)*qmul + 128 ) >> 8)); + block[stride*8 +offset]= ((((z1 - z2)*qmul + 128 ) >> 8)); + block[stride*10+offset]= ((((z0 - z3)*qmul + 128 ) >> 8)); + } +} + +#if 0 +/** + * dct tranforms the 16 dc values. + * @param qp quantization parameter ??? FIXME + */ +static void h264_luma_dc_dct_c(DCTELEM *block/*, int qp*/){ +// const int qmul= dequant_coeff[qp][0]; + int i; + int temp[16]; //FIXME check if this is a good idea + static const int x_offset[4]={0, 1*stride, 4* stride, 5*stride}; + static const int y_offset[4]={0, 2*stride, 8* stride, 10*stride}; + + for(i=0; i<4; i++){ + const int offset= y_offset[i]; + const int z0= block[offset+stride*0] + block[offset+stride*4]; + const int z1= block[offset+stride*0] - block[offset+stride*4]; + const int z2= block[offset+stride*1] - block[offset+stride*5]; + const int z3= block[offset+stride*1] + block[offset+stride*5]; + + temp[4*i+0]= z0+z3; + temp[4*i+1]= z1+z2; + temp[4*i+2]= z1-z2; + temp[4*i+3]= z0-z3; + } + + for(i=0; i<4; i++){ + const int offset= x_offset[i]; + const int z0= temp[4*0+i] + temp[4*2+i]; + const int z1= temp[4*0+i] - temp[4*2+i]; + const int z2= temp[4*1+i] - temp[4*3+i]; + const int z3= temp[4*1+i] + temp[4*3+i]; + + block[stride*0 +offset]= (z0 + z3)>>1; + block[stride*2 +offset]= (z1 + z2)>>1; + block[stride*8 +offset]= (z1 - z2)>>1; + block[stride*10+offset]= (z0 - z3)>>1; + } +} +#endif + +#undef xStride +#undef stride + +static void chroma_dc_dequant_idct_c(DCTELEM *block, int qp, int qmul){ + const int stride= 16*2; + const int xStride= 16; + int a,b,c,d,e; + + a= block[stride*0 + xStride*0]; + b= block[stride*0 + xStride*1]; + c= block[stride*1 + xStride*0]; + d= block[stride*1 + xStride*1]; + + e= a-b; + a= a+b; + b= c-d; + c= c+d; + + block[stride*0 + xStride*0]= ((a+c)*qmul) >> 7; + block[stride*0 + xStride*1]= ((e+b)*qmul) >> 7; + block[stride*1 + xStride*0]= ((a-c)*qmul) >> 7; + block[stride*1 + xStride*1]= ((e-b)*qmul) >> 7; +} + +#if 0 +static void chroma_dc_dct_c(DCTELEM *block){ + const int stride= 16*2; + const int xStride= 16; + int a,b,c,d,e; + + a= block[stride*0 + xStride*0]; + b= block[stride*0 + xStride*1]; + c= block[stride*1 + xStride*0]; + d= block[stride*1 + xStride*1]; + + e= a-b; + a= a+b; + b= c-d; + c= c+d; + + block[stride*0 + xStride*0]= (a+c); + block[stride*0 + xStride*1]= (e+b); + block[stride*1 + xStride*0]= (a-c); + block[stride*1 + xStride*1]= (e-b); +} +#endif + +/** + * gets the chroma qp. + */ +static inline int get_chroma_qp(int chroma_qp_index_offset, int qscale){ + + return chroma_qp[clip(qscale + chroma_qp_index_offset, 0, 51)]; +} + + +#if 0 +static void h264_diff_dct_c(DCTELEM *block, uint8_t *src1, uint8_t *src2, int stride){ + int i; + //FIXME try int temp instead of block + + for(i=0; i<4; i++){ + const int d0= src1[0 + i*stride] - src2[0 + i*stride]; + const int d1= src1[1 + i*stride] - src2[1 + i*stride]; + const int d2= src1[2 + i*stride] - src2[2 + i*stride]; + const int d3= src1[3 + i*stride] - src2[3 + i*stride]; + const int z0= d0 + d3; + const int z3= d0 - d3; + const int z1= d1 + d2; + const int z2= d1 - d2; + + block[0 + 4*i]= z0 + z1; + block[1 + 4*i]= 2*z3 + z2; + block[2 + 4*i]= z0 - z1; + block[3 + 4*i]= z3 - 2*z2; + } + + for(i=0; i<4; i++){ + const int z0= block[0*4 + i] + block[3*4 + i]; + const int z3= block[0*4 + i] - block[3*4 + i]; + const int z1= block[1*4 + i] + block[2*4 + i]; + const int z2= block[1*4 + i] - block[2*4 + i]; + + block[0*4 + i]= z0 + z1; + block[1*4 + i]= 2*z3 + z2; + block[2*4 + i]= z0 - z1; + block[3*4 + i]= z3 - 2*z2; + } +} +#endif + +//FIXME need to check that this doesnt overflow signed 32 bit for low qp, i am not sure, it's very close +//FIXME check that gcc inlines this (and optimizes intra & seperate_dc stuff away) +static inline int quantize_c(DCTELEM *block, uint8_t *scantable, int qscale, int intra, int seperate_dc){ + int i; + const int * const quant_table= quant_coeff[qscale]; + const int bias= intra ? (1<dc_threshold2){ + if(level>0){ + level= (dc_bias + level)>>(QUANT_SHIFT-2); + block[0]= level; + }else{ + level= (dc_bias - level)>>(QUANT_SHIFT-2); + block[0]= -level; + } +// last_non_zero = i; + }else{ + block[0]=0; + } + }else{ + const int dc_bias= intra ? (1<<(QUANT_SHIFT+1))/3 : (1<<(QUANT_SHIFT+1))/6; + const unsigned int dc_threshold1= (1<<(QUANT_SHIFT+1)) - dc_bias - 1; + const unsigned int dc_threshold2= (dc_threshold1<<1); + + int level= block[0]*quant_table[0]; + if(((unsigned)(level+dc_threshold1))>dc_threshold2){ + if(level>0){ + level= (dc_bias + level)>>(QUANT_SHIFT+1); + block[0]= level; + }else{ + level= (dc_bias - level)>>(QUANT_SHIFT+1); + block[0]= -level; + } +// last_non_zero = i; + }else{ + block[0]=0; + } + } + last_non_zero= 0; + i=1; + }else{ + last_non_zero= -1; + i=0; + } + + for(; i<16; i++){ + const int j= scantable[i]; + int level= block[j]*quant_table[j]; + +// if( bias+level >= (1<<(QMAT_SHIFT - 3)) +// || bias-level >= (1<<(QMAT_SHIFT - 3))){ + if(((unsigned)(level+threshold1))>threshold2){ + if(level>0){ + level= (bias + level)>>QUANT_SHIFT; + block[j]= level; + }else{ + level= (bias - level)>>QUANT_SHIFT; + block[j]= -level; + } + last_non_zero = i; + }else{ + block[j]=0; + } + } + + return last_non_zero; +} + +static void pred4x4_vertical_c(uint8_t *src, uint8_t *topright, int stride){ + const uint32_t a= ((uint32_t*)(src-stride))[0]; + ((uint32_t*)(src+0*stride))[0]= a; + ((uint32_t*)(src+1*stride))[0]= a; + ((uint32_t*)(src+2*stride))[0]= a; + ((uint32_t*)(src+3*stride))[0]= a; +} + +static void pred4x4_horizontal_c(uint8_t *src, uint8_t *topright, int stride){ + ((uint32_t*)(src+0*stride))[0]= src[-1+0*stride]*0x01010101; + ((uint32_t*)(src+1*stride))[0]= src[-1+1*stride]*0x01010101; + ((uint32_t*)(src+2*stride))[0]= src[-1+2*stride]*0x01010101; + ((uint32_t*)(src+3*stride))[0]= src[-1+3*stride]*0x01010101; +} + +static void pred4x4_dc_c(uint8_t *src, uint8_t *topright, int stride){ + const int dc= ( src[-stride] + src[1-stride] + src[2-stride] + src[3-stride] + + src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 4) >>3; + + ((uint32_t*)(src+0*stride))[0]= + ((uint32_t*)(src+1*stride))[0]= + ((uint32_t*)(src+2*stride))[0]= + ((uint32_t*)(src+3*stride))[0]= dc* 0x01010101; +} + +static void pred4x4_left_dc_c(uint8_t *src, uint8_t *topright, int stride){ + const int dc= ( src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 2) >>2; + + ((uint32_t*)(src+0*stride))[0]= + ((uint32_t*)(src+1*stride))[0]= + ((uint32_t*)(src+2*stride))[0]= + ((uint32_t*)(src+3*stride))[0]= dc* 0x01010101; +} + +static void pred4x4_top_dc_c(uint8_t *src, uint8_t *topright, int stride){ + const int dc= ( src[-stride] + src[1-stride] + src[2-stride] + src[3-stride] + 2) >>2; + + ((uint32_t*)(src+0*stride))[0]= + ((uint32_t*)(src+1*stride))[0]= + ((uint32_t*)(src+2*stride))[0]= + ((uint32_t*)(src+3*stride))[0]= dc* 0x01010101; +} + +static void pred4x4_128_dc_c(uint8_t *src, uint8_t *topright, int stride){ + ((uint32_t*)(src+0*stride))[0]= + ((uint32_t*)(src+1*stride))[0]= + ((uint32_t*)(src+2*stride))[0]= + ((uint32_t*)(src+3*stride))[0]= 128U*0x01010101U; +} + + +#define LOAD_TOP_RIGHT_EDGE\ + const int t4= topright[0];\ + const int t5= topright[1];\ + const int t6= topright[2];\ + const int t7= topright[3];\ + +#define LOAD_LEFT_EDGE\ + const int l0= src[-1+0*stride];\ + const int l1= src[-1+1*stride];\ + const int l2= src[-1+2*stride];\ + const int l3= src[-1+3*stride];\ + +#define LOAD_TOP_EDGE\ + const int t0= src[ 0-1*stride];\ + const int t1= src[ 1-1*stride];\ + const int t2= src[ 2-1*stride];\ + const int t3= src[ 3-1*stride];\ + +static void pred4x4_down_right_c(uint8_t *src, uint8_t *topright, int stride){ + const int lt= src[-1-1*stride]; + LOAD_TOP_EDGE + LOAD_LEFT_EDGE + + src[0+3*stride]=(l3 + 2*l2 + l1 + 2)>>2; + src[0+2*stride]= + src[1+3*stride]=(l2 + 2*l1 + l0 + 2)>>2; + src[0+1*stride]= + src[1+2*stride]= + src[2+3*stride]=(l1 + 2*l0 + lt + 2)>>2; + src[0+0*stride]= + src[1+1*stride]= + src[2+2*stride]= + src[3+3*stride]=(l0 + 2*lt + t0 + 2)>>2; + src[1+0*stride]= + src[2+1*stride]= + src[3+2*stride]=(lt + 2*t0 + t1 + 2)>>2; + src[2+0*stride]= + src[3+1*stride]=(t0 + 2*t1 + t2 + 2)>>2; + src[3+0*stride]=(t1 + 2*t2 + t3 + 2)>>2; +} + +static void pred4x4_down_left_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_TOP_EDGE + LOAD_TOP_RIGHT_EDGE +// LOAD_LEFT_EDGE + + src[0+0*stride]=(t0 + t2 + 2*t1 + 2)>>2; + src[1+0*stride]= + src[0+1*stride]=(t1 + t3 + 2*t2 + 2)>>2; + src[2+0*stride]= + src[1+1*stride]= + src[0+2*stride]=(t2 + t4 + 2*t3 + 2)>>2; + src[3+0*stride]= + src[2+1*stride]= + src[1+2*stride]= + src[0+3*stride]=(t3 + t5 + 2*t4 + 2)>>2; + src[3+1*stride]= + src[2+2*stride]= + src[1+3*stride]=(t4 + t6 + 2*t5 + 2)>>2; + src[3+2*stride]= + src[2+3*stride]=(t5 + t7 + 2*t6 + 2)>>2; + src[3+3*stride]=(t6 + 3*t7 + 2)>>2; +} + +static void pred4x4_vertical_right_c(uint8_t *src, uint8_t *topright, int stride){ + const int lt= src[-1-1*stride]; + LOAD_TOP_EDGE + LOAD_LEFT_EDGE + const __attribute__((unused)) int unu= l3; + + src[0+0*stride]= + src[1+2*stride]=(lt + t0 + 1)>>1; + src[1+0*stride]= + src[2+2*stride]=(t0 + t1 + 1)>>1; + src[2+0*stride]= + src[3+2*stride]=(t1 + t2 + 1)>>1; + src[3+0*stride]=(t2 + t3 + 1)>>1; + src[0+1*stride]= + src[1+3*stride]=(l0 + 2*lt + t0 + 2)>>2; + src[1+1*stride]= + src[2+3*stride]=(lt + 2*t0 + t1 + 2)>>2; + src[2+1*stride]= + src[3+3*stride]=(t0 + 2*t1 + t2 + 2)>>2; + src[3+1*stride]=(t1 + 2*t2 + t3 + 2)>>2; + src[0+2*stride]=(lt + 2*l0 + l1 + 2)>>2; + src[0+3*stride]=(l0 + 2*l1 + l2 + 2)>>2; +} + +static void pred4x4_vertical_left_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_TOP_EDGE + LOAD_TOP_RIGHT_EDGE + const __attribute__((unused)) int unu= t7; + + src[0+0*stride]=(t0 + t1 + 1)>>1; + src[1+0*stride]= + src[0+2*stride]=(t1 + t2 + 1)>>1; + src[2+0*stride]= + src[1+2*stride]=(t2 + t3 + 1)>>1; + src[3+0*stride]= + src[2+2*stride]=(t3 + t4+ 1)>>1; + src[3+2*stride]=(t4 + t5+ 1)>>1; + src[0+1*stride]=(t0 + 2*t1 + t2 + 2)>>2; + src[1+1*stride]= + src[0+3*stride]=(t1 + 2*t2 + t3 + 2)>>2; + src[2+1*stride]= + src[1+3*stride]=(t2 + 2*t3 + t4 + 2)>>2; + src[3+1*stride]= + src[2+3*stride]=(t3 + 2*t4 + t5 + 2)>>2; + src[3+3*stride]=(t4 + 2*t5 + t6 + 2)>>2; +} + +static void pred4x4_horizontal_up_c(uint8_t *src, uint8_t *topright, int stride){ + LOAD_LEFT_EDGE + + src[0+0*stride]=(l0 + l1 + 1)>>1; + src[1+0*stride]=(l0 + 2*l1 + l2 + 2)>>2; + src[2+0*stride]= + src[0+1*stride]=(l1 + l2 + 1)>>1; + src[3+0*stride]= + src[1+1*stride]=(l1 + 2*l2 + l3 + 2)>>2; + src[2+1*stride]= + src[0+2*stride]=(l2 + l3 + 1)>>1; + src[3+1*stride]= + src[1+2*stride]=(l2 + 2*l3 + l3 + 2)>>2; + src[3+2*stride]= + src[1+3*stride]= + src[0+3*stride]= + src[2+2*stride]= + src[2+3*stride]= + src[3+3*stride]=l3; +} + +static void pred4x4_horizontal_down_c(uint8_t *src, uint8_t *topright, int stride){ + const int lt= src[-1-1*stride]; + LOAD_TOP_EDGE + LOAD_LEFT_EDGE + const __attribute__((unused)) int unu= t3; + + src[0+0*stride]= + src[2+1*stride]=(lt + l0 + 1)>>1; + src[1+0*stride]= + src[3+1*stride]=(l0 + 2*lt + t0 + 2)>>2; + src[2+0*stride]=(lt + 2*t0 + t1 + 2)>>2; + src[3+0*stride]=(t0 + 2*t1 + t2 + 2)>>2; + src[0+1*stride]= + src[2+2*stride]=(l0 + l1 + 1)>>1; + src[1+1*stride]= + src[3+2*stride]=(lt + 2*l0 + l1 + 2)>>2; + src[0+2*stride]= + src[2+3*stride]=(l1 + l2+ 1)>>1; + src[1+2*stride]= + src[3+3*stride]=(l0 + 2*l1 + l2 + 2)>>2; + src[0+3*stride]=(l2 + l3 + 1)>>1; + src[1+3*stride]=(l1 + 2*l2 + l3 + 2)>>2; +} + +static void pred16x16_vertical_c(uint8_t *src, int stride){ + int i; + const uint32_t a= ((uint32_t*)(src-stride))[0]; + const uint32_t b= ((uint32_t*)(src-stride))[1]; + const uint32_t c= ((uint32_t*)(src-stride))[2]; + const uint32_t d= ((uint32_t*)(src-stride))[3]; + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= a; + ((uint32_t*)(src+i*stride))[1]= b; + ((uint32_t*)(src+i*stride))[2]= c; + ((uint32_t*)(src+i*stride))[3]= d; + } +} + +static void pred16x16_horizontal_c(uint8_t *src, int stride){ + int i; + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= src[-1+i*stride]*0x01010101; + } +} + +static void pred16x16_dc_c(uint8_t *src, int stride){ + int i, dc=0; + + for(i=0;i<16; i++){ + dc+= src[-1+i*stride]; + } + + for(i=0;i<16; i++){ + dc+= src[i-stride]; + } + + dc= 0x01010101*((dc + 16)>>5); + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= dc; + } +} + +static void pred16x16_left_dc_c(uint8_t *src, int stride){ + int i, dc=0; + + for(i=0;i<16; i++){ + dc+= src[-1+i*stride]; + } + + dc= 0x01010101*((dc + 8)>>4); + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= dc; + } +} + +static void pred16x16_top_dc_c(uint8_t *src, int stride){ + int i, dc=0; + + for(i=0;i<16; i++){ + dc+= src[i-stride]; + } + dc= 0x01010101*((dc + 8)>>4); + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= dc; + } +} + +static void pred16x16_128_dc_c(uint8_t *src, int stride){ + int i; + + for(i=0; i<16; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= + ((uint32_t*)(src+i*stride))[2]= + ((uint32_t*)(src+i*stride))[3]= 0x01010101U*128U; + } +} + +static inline void pred16x16_plane_compat_c(uint8_t *src, int stride, const int svq3){ + int i, j, k; + int a; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + const uint8_t * const src0 = src+7-stride; + const uint8_t *src1 = src+8*stride-1; + const uint8_t *src2 = src1-2*stride; // == src+6*stride-1; + int H = src0[1] - src0[-1]; + int V = src1[0] - src2[ 0]; + for(k=2; k<=8; ++k) { + src1 += stride; src2 -= stride; + H += k*(src0[k] - src0[-k]); + V += k*(src1[0] - src2[ 0]); + } + if(svq3){ + H = ( 5*(H/4) ) / 16; + V = ( 5*(V/4) ) / 16; + + /* required for 100% accuracy */ + i = H; H = V; V = i; + }else{ + H = ( 5*H+32 ) >> 6; + V = ( 5*V+32 ) >> 6; + } + + a = 16*(src1[0] + src2[16] + 1) - 7*(V+H); + for(j=16; j>0; --j) { + int b = a; + a += V; + for(i=-16; i<0; i+=4) { + src[16+i] = cm[ (b ) >> 5 ]; + src[17+i] = cm[ (b+ H) >> 5 ]; + src[18+i] = cm[ (b+2*H) >> 5 ]; + src[19+i] = cm[ (b+3*H) >> 5 ]; + b += 4*H; + } + src += stride; + } +} + +static void pred16x16_plane_c(uint8_t *src, int stride){ + pred16x16_plane_compat_c(src, stride, 0); +} + +static void pred8x8_vertical_c(uint8_t *src, int stride){ + int i; + const uint32_t a= ((uint32_t*)(src-stride))[0]; + const uint32_t b= ((uint32_t*)(src-stride))[1]; + + for(i=0; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= a; + ((uint32_t*)(src+i*stride))[1]= b; + } +} + +static void pred8x8_horizontal_c(uint8_t *src, int stride){ + int i; + + for(i=0; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= src[-1+i*stride]*0x01010101; + } +} + +static void pred8x8_128_dc_c(uint8_t *src, int stride){ + int i; + + for(i=0; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= 0x01010101U*128U; + } +} + +static void pred8x8_left_dc_c(uint8_t *src, int stride){ + int i; + int dc0, dc2; + + dc0=dc2=0; + for(i=0;i<4; i++){ + dc0+= src[-1+i*stride]; + dc2+= src[-1+(i+4)*stride]; + } + dc0= 0x01010101*((dc0 + 2)>>2); + dc2= 0x01010101*((dc2 + 2)>>2); + + for(i=0; i<4; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= dc0; + } + for(i=4; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= + ((uint32_t*)(src+i*stride))[1]= dc2; + } +} + +static void pred8x8_top_dc_c(uint8_t *src, int stride){ + int i; + int dc0, dc1; + + dc0=dc1=0; + for(i=0;i<4; i++){ + dc0+= src[i-stride]; + dc1+= src[4+i-stride]; + } + dc0= 0x01010101*((dc0 + 2)>>2); + dc1= 0x01010101*((dc1 + 2)>>2); + + for(i=0; i<4; i++){ + ((uint32_t*)(src+i*stride))[0]= dc0; + ((uint32_t*)(src+i*stride))[1]= dc1; + } + for(i=4; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= dc0; + ((uint32_t*)(src+i*stride))[1]= dc1; + } +} + + +static void pred8x8_dc_c(uint8_t *src, int stride){ + int i; + int dc0, dc1, dc2, dc3; + + dc0=dc1=dc2=0; + for(i=0;i<4; i++){ + dc0+= src[-1+i*stride] + src[i-stride]; + dc1+= src[4+i-stride]; + dc2+= src[-1+(i+4)*stride]; + } + dc3= 0x01010101*((dc1 + dc2 + 4)>>3); + dc0= 0x01010101*((dc0 + 4)>>3); + dc1= 0x01010101*((dc1 + 2)>>2); + dc2= 0x01010101*((dc2 + 2)>>2); + + for(i=0; i<4; i++){ + ((uint32_t*)(src+i*stride))[0]= dc0; + ((uint32_t*)(src+i*stride))[1]= dc1; + } + for(i=4; i<8; i++){ + ((uint32_t*)(src+i*stride))[0]= dc2; + ((uint32_t*)(src+i*stride))[1]= dc3; + } +} + +static void pred8x8_plane_c(uint8_t *src, int stride){ + int j, k; + int a; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + const uint8_t * const src0 = src+3-stride; + const uint8_t *src1 = src+4*stride-1; + const uint8_t *src2 = src1-2*stride; // == src+2*stride-1; + int H = src0[1] - src0[-1]; + int V = src1[0] - src2[ 0]; + for(k=2; k<=4; ++k) { + src1 += stride; src2 -= stride; + H += k*(src0[k] - src0[-k]); + V += k*(src1[0] - src2[ 0]); + } + H = ( 17*H+16 ) >> 5; + V = ( 17*V+16 ) >> 5; + + a = 16*(src1[0] + src2[8]+1) - 3*(V+H); + for(j=8; j>0; --j) { + int b = a; + a += V; + src[0] = cm[ (b ) >> 5 ]; + src[1] = cm[ (b+ H) >> 5 ]; + src[2] = cm[ (b+2*H) >> 5 ]; + src[3] = cm[ (b+3*H) >> 5 ]; + src[4] = cm[ (b+4*H) >> 5 ]; + src[5] = cm[ (b+5*H) >> 5 ]; + src[6] = cm[ (b+6*H) >> 5 ]; + src[7] = cm[ (b+7*H) >> 5 ]; + src += stride; + } +} + +#define SRC(x,y) src[(x)+(y)*stride] +#define PL(y) \ + const int l##y = (SRC(-1,y-1) + 2*SRC(-1,y) + SRC(-1,y+1) + 2) >> 2; +#define PREDICT_8x8_LOAD_LEFT \ + const int l0 = ((has_topleft ? SRC(-1,-1) : SRC(-1,0)) \ + + 2*SRC(-1,0) + SRC(-1,1) + 2) >> 2; \ + PL(1) PL(2) PL(3) PL(4) PL(5) PL(6) \ + const int l7 attribute_unused = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2 + +#define PT(x) \ + const int t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2; +#define PREDICT_8x8_LOAD_TOP \ + const int t0 = ((has_topleft ? SRC(-1,-1) : SRC(0,-1)) \ + + 2*SRC(0,-1) + SRC(1,-1) + 2) >> 2; \ + PT(1) PT(2) PT(3) PT(4) PT(5) PT(6) \ + const int t7 attribute_unused = ((has_topright ? SRC(8,-1) : SRC(7,-1)) \ + + 2*SRC(7,-1) + SRC(6,-1) + 2) >> 2 + +#define PTR(x) \ + t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2; +#define PREDICT_8x8_LOAD_TOPRIGHT \ + int t8, t9, t10, t11, t12, t13, t14, t15; \ + if(has_topright) { \ + PTR(8) PTR(9) PTR(10) PTR(11) PTR(12) PTR(13) PTR(14) \ + t15 = (SRC(14,-1) + 3*SRC(15,-1) + 2) >> 2; \ + } else t8=t9=t10=t11=t12=t13=t14=t15= SRC(7,-1); + +#define PREDICT_8x8_LOAD_TOPLEFT \ + const int lt = (SRC(-1,0) + 2*SRC(-1,-1) + SRC(0,-1) + 2) >> 2 + +#define PREDICT_8x8_DC(v) \ + int y; \ + for( y = 0; y < 8; y++ ) { \ + ((uint32_t*)src)[0] = \ + ((uint32_t*)src)[1] = v; \ + src += stride; \ + } + +static void pred8x8l_128_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_DC(0x80808080); +} +static void pred8x8l_left_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_LEFT; + const uint32_t dc = ((l0+l1+l2+l3+l4+l5+l6+l7+4) >> 3) * 0x01010101; + PREDICT_8x8_DC(dc); +} +static void pred8x8l_top_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + const uint32_t dc = ((t0+t1+t2+t3+t4+t5+t6+t7+4) >> 3) * 0x01010101; + PREDICT_8x8_DC(dc); +} +static void pred8x8l_dc_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_LEFT; + PREDICT_8x8_LOAD_TOP; + const uint32_t dc = ((l0+l1+l2+l3+l4+l5+l6+l7 + +t0+t1+t2+t3+t4+t5+t6+t7+8) >> 4) * 0x01010101; + PREDICT_8x8_DC(dc); +} +static void pred8x8l_horizontal_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_LEFT; +#define ROW(y) ((uint32_t*)(src+y*stride))[0] =\ + ((uint32_t*)(src+y*stride))[1] = 0x01010101 * l##y + ROW(0); ROW(1); ROW(2); ROW(3); ROW(4); ROW(5); ROW(6); ROW(7); +#undef ROW +} +static void pred8x8l_vertical_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + int y; + PREDICT_8x8_LOAD_TOP; + src[0] = t0; + src[1] = t1; + src[2] = t2; + src[3] = t3; + src[4] = t4; + src[5] = t5; + src[6] = t6; + src[7] = t7; + for( y = 1; y < 8; y++ ) + *(uint64_t*)(src+y*stride) = *(uint64_t*)src; +} +static void pred8x8l_down_left_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_TOPRIGHT; + SRC(0,0)= (t0 + 2*t1 + t2 + 2) >> 2; + SRC(0,1)=SRC(1,0)= (t1 + 2*t2 + t3 + 2) >> 2; + SRC(0,2)=SRC(1,1)=SRC(2,0)= (t2 + 2*t3 + t4 + 2) >> 2; + SRC(0,3)=SRC(1,2)=SRC(2,1)=SRC(3,0)= (t3 + 2*t4 + t5 + 2) >> 2; + SRC(0,4)=SRC(1,3)=SRC(2,2)=SRC(3,1)=SRC(4,0)= (t4 + 2*t5 + t6 + 2) >> 2; + SRC(0,5)=SRC(1,4)=SRC(2,3)=SRC(3,2)=SRC(4,1)=SRC(5,0)= (t5 + 2*t6 + t7 + 2) >> 2; + SRC(0,6)=SRC(1,5)=SRC(2,4)=SRC(3,3)=SRC(4,2)=SRC(5,1)=SRC(6,0)= (t6 + 2*t7 + t8 + 2) >> 2; + SRC(0,7)=SRC(1,6)=SRC(2,5)=SRC(3,4)=SRC(4,3)=SRC(5,2)=SRC(6,1)=SRC(7,0)= (t7 + 2*t8 + t9 + 2) >> 2; + SRC(1,7)=SRC(2,6)=SRC(3,5)=SRC(4,4)=SRC(5,3)=SRC(6,2)=SRC(7,1)= (t8 + 2*t9 + t10 + 2) >> 2; + SRC(2,7)=SRC(3,6)=SRC(4,5)=SRC(5,4)=SRC(6,3)=SRC(7,2)= (t9 + 2*t10 + t11 + 2) >> 2; + SRC(3,7)=SRC(4,6)=SRC(5,5)=SRC(6,4)=SRC(7,3)= (t10 + 2*t11 + t12 + 2) >> 2; + SRC(4,7)=SRC(5,6)=SRC(6,5)=SRC(7,4)= (t11 + 2*t12 + t13 + 2) >> 2; + SRC(5,7)=SRC(6,6)=SRC(7,5)= (t12 + 2*t13 + t14 + 2) >> 2; + SRC(6,7)=SRC(7,6)= (t13 + 2*t14 + t15 + 2) >> 2; + SRC(7,7)= (t14 + 3*t15 + 2) >> 2; +} +static void pred8x8l_down_right_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_LEFT; + PREDICT_8x8_LOAD_TOPLEFT; + SRC(0,7)= (l7 + 2*l6 + l5 + 2) >> 2; + SRC(0,6)=SRC(1,7)= (l6 + 2*l5 + l4 + 2) >> 2; + SRC(0,5)=SRC(1,6)=SRC(2,7)= (l5 + 2*l4 + l3 + 2) >> 2; + SRC(0,4)=SRC(1,5)=SRC(2,6)=SRC(3,7)= (l4 + 2*l3 + l2 + 2) >> 2; + SRC(0,3)=SRC(1,4)=SRC(2,5)=SRC(3,6)=SRC(4,7)= (l3 + 2*l2 + l1 + 2) >> 2; + SRC(0,2)=SRC(1,3)=SRC(2,4)=SRC(3,5)=SRC(4,6)=SRC(5,7)= (l2 + 2*l1 + l0 + 2) >> 2; + SRC(0,1)=SRC(1,2)=SRC(2,3)=SRC(3,4)=SRC(4,5)=SRC(5,6)=SRC(6,7)= (l1 + 2*l0 + lt + 2) >> 2; + SRC(0,0)=SRC(1,1)=SRC(2,2)=SRC(3,3)=SRC(4,4)=SRC(5,5)=SRC(6,6)=SRC(7,7)= (l0 + 2*lt + t0 + 2) >> 2; + SRC(1,0)=SRC(2,1)=SRC(3,2)=SRC(4,3)=SRC(5,4)=SRC(6,5)=SRC(7,6)= (lt + 2*t0 + t1 + 2) >> 2; + SRC(2,0)=SRC(3,1)=SRC(4,2)=SRC(5,3)=SRC(6,4)=SRC(7,5)= (t0 + 2*t1 + t2 + 2) >> 2; + SRC(3,0)=SRC(4,1)=SRC(5,2)=SRC(6,3)=SRC(7,4)= (t1 + 2*t2 + t3 + 2) >> 2; + SRC(4,0)=SRC(5,1)=SRC(6,2)=SRC(7,3)= (t2 + 2*t3 + t4 + 2) >> 2; + SRC(5,0)=SRC(6,1)=SRC(7,2)= (t3 + 2*t4 + t5 + 2) >> 2; + SRC(6,0)=SRC(7,1)= (t4 + 2*t5 + t6 + 2) >> 2; + SRC(7,0)= (t5 + 2*t6 + t7 + 2) >> 2; + +} +static void pred8x8l_vertical_right_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_LEFT; + PREDICT_8x8_LOAD_TOPLEFT; + SRC(0,6)= (l5 + 2*l4 + l3 + 2) >> 2; + SRC(0,7)= (l6 + 2*l5 + l4 + 2) >> 2; + SRC(0,4)=SRC(1,6)= (l3 + 2*l2 + l1 + 2) >> 2; + SRC(0,5)=SRC(1,7)= (l4 + 2*l3 + l2 + 2) >> 2; + SRC(0,2)=SRC(1,4)=SRC(2,6)= (l1 + 2*l0 + lt + 2) >> 2; + SRC(0,3)=SRC(1,5)=SRC(2,7)= (l2 + 2*l1 + l0 + 2) >> 2; + SRC(0,1)=SRC(1,3)=SRC(2,5)=SRC(3,7)= (l0 + 2*lt + t0 + 2) >> 2; + SRC(0,0)=SRC(1,2)=SRC(2,4)=SRC(3,6)= (lt + t0 + 1) >> 1; + SRC(1,1)=SRC(2,3)=SRC(3,5)=SRC(4,7)= (lt + 2*t0 + t1 + 2) >> 2; + SRC(1,0)=SRC(2,2)=SRC(3,4)=SRC(4,6)= (t0 + t1 + 1) >> 1; + SRC(2,1)=SRC(3,3)=SRC(4,5)=SRC(5,7)= (t0 + 2*t1 + t2 + 2) >> 2; + SRC(2,0)=SRC(3,2)=SRC(4,4)=SRC(5,6)= (t1 + t2 + 1) >> 1; + SRC(3,1)=SRC(4,3)=SRC(5,5)=SRC(6,7)= (t1 + 2*t2 + t3 + 2) >> 2; + SRC(3,0)=SRC(4,2)=SRC(5,4)=SRC(6,6)= (t2 + t3 + 1) >> 1; + SRC(4,1)=SRC(5,3)=SRC(6,5)=SRC(7,7)= (t2 + 2*t3 + t4 + 2) >> 2; + SRC(4,0)=SRC(5,2)=SRC(6,4)=SRC(7,6)= (t3 + t4 + 1) >> 1; + SRC(5,1)=SRC(6,3)=SRC(7,5)= (t3 + 2*t4 + t5 + 2) >> 2; + SRC(5,0)=SRC(6,2)=SRC(7,4)= (t4 + t5 + 1) >> 1; + SRC(6,1)=SRC(7,3)= (t4 + 2*t5 + t6 + 2) >> 2; + SRC(6,0)=SRC(7,2)= (t5 + t6 + 1) >> 1; + SRC(7,1)= (t5 + 2*t6 + t7 + 2) >> 2; + SRC(7,0)= (t6 + t7 + 1) >> 1; +} +static void pred8x8l_horizontal_down_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_LEFT; + PREDICT_8x8_LOAD_TOPLEFT; + SRC(0,7)= (l6 + l7 + 1) >> 1; + SRC(1,7)= (l5 + 2*l6 + l7 + 2) >> 2; + SRC(0,6)=SRC(2,7)= (l5 + l6 + 1) >> 1; + SRC(1,6)=SRC(3,7)= (l4 + 2*l5 + l6 + 2) >> 2; + SRC(0,5)=SRC(2,6)=SRC(4,7)= (l4 + l5 + 1) >> 1; + SRC(1,5)=SRC(3,6)=SRC(5,7)= (l3 + 2*l4 + l5 + 2) >> 2; + SRC(0,4)=SRC(2,5)=SRC(4,6)=SRC(6,7)= (l3 + l4 + 1) >> 1; + SRC(1,4)=SRC(3,5)=SRC(5,6)=SRC(7,7)= (l2 + 2*l3 + l4 + 2) >> 2; + SRC(0,3)=SRC(2,4)=SRC(4,5)=SRC(6,6)= (l2 + l3 + 1) >> 1; + SRC(1,3)=SRC(3,4)=SRC(5,5)=SRC(7,6)= (l1 + 2*l2 + l3 + 2) >> 2; + SRC(0,2)=SRC(2,3)=SRC(4,4)=SRC(6,5)= (l1 + l2 + 1) >> 1; + SRC(1,2)=SRC(3,3)=SRC(5,4)=SRC(7,5)= (l0 + 2*l1 + l2 + 2) >> 2; + SRC(0,1)=SRC(2,2)=SRC(4,3)=SRC(6,4)= (l0 + l1 + 1) >> 1; + SRC(1,1)=SRC(3,2)=SRC(5,3)=SRC(7,4)= (lt + 2*l0 + l1 + 2) >> 2; + SRC(0,0)=SRC(2,1)=SRC(4,2)=SRC(6,3)= (lt + l0 + 1) >> 1; + SRC(1,0)=SRC(3,1)=SRC(5,2)=SRC(7,3)= (l0 + 2*lt + t0 + 2) >> 2; + SRC(2,0)=SRC(4,1)=SRC(6,2)= (t1 + 2*t0 + lt + 2) >> 2; + SRC(3,0)=SRC(5,1)=SRC(7,2)= (t2 + 2*t1 + t0 + 2) >> 2; + SRC(4,0)=SRC(6,1)= (t3 + 2*t2 + t1 + 2) >> 2; + SRC(5,0)=SRC(7,1)= (t4 + 2*t3 + t2 + 2) >> 2; + SRC(6,0)= (t5 + 2*t4 + t3 + 2) >> 2; + SRC(7,0)= (t6 + 2*t5 + t4 + 2) >> 2; +} +static void pred8x8l_vertical_left_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_TOP; + PREDICT_8x8_LOAD_TOPRIGHT; + SRC(0,0)= (t0 + t1 + 1) >> 1; + SRC(0,1)= (t0 + 2*t1 + t2 + 2) >> 2; + SRC(0,2)=SRC(1,0)= (t1 + t2 + 1) >> 1; + SRC(0,3)=SRC(1,1)= (t1 + 2*t2 + t3 + 2) >> 2; + SRC(0,4)=SRC(1,2)=SRC(2,0)= (t2 + t3 + 1) >> 1; + SRC(0,5)=SRC(1,3)=SRC(2,1)= (t2 + 2*t3 + t4 + 2) >> 2; + SRC(0,6)=SRC(1,4)=SRC(2,2)=SRC(3,0)= (t3 + t4 + 1) >> 1; + SRC(0,7)=SRC(1,5)=SRC(2,3)=SRC(3,1)= (t3 + 2*t4 + t5 + 2) >> 2; + SRC(1,6)=SRC(2,4)=SRC(3,2)=SRC(4,0)= (t4 + t5 + 1) >> 1; + SRC(1,7)=SRC(2,5)=SRC(3,3)=SRC(4,1)= (t4 + 2*t5 + t6 + 2) >> 2; + SRC(2,6)=SRC(3,4)=SRC(4,2)=SRC(5,0)= (t5 + t6 + 1) >> 1; + SRC(2,7)=SRC(3,5)=SRC(4,3)=SRC(5,1)= (t5 + 2*t6 + t7 + 2) >> 2; + SRC(3,6)=SRC(4,4)=SRC(5,2)=SRC(6,0)= (t6 + t7 + 1) >> 1; + SRC(3,7)=SRC(4,5)=SRC(5,3)=SRC(6,1)= (t6 + 2*t7 + t8 + 2) >> 2; + SRC(4,6)=SRC(5,4)=SRC(6,2)=SRC(7,0)= (t7 + t8 + 1) >> 1; + SRC(4,7)=SRC(5,5)=SRC(6,3)=SRC(7,1)= (t7 + 2*t8 + t9 + 2) >> 2; + SRC(5,6)=SRC(6,4)=SRC(7,2)= (t8 + t9 + 1) >> 1; + SRC(5,7)=SRC(6,5)=SRC(7,3)= (t8 + 2*t9 + t10 + 2) >> 2; + SRC(6,6)=SRC(7,4)= (t9 + t10 + 1) >> 1; + SRC(6,7)=SRC(7,5)= (t9 + 2*t10 + t11 + 2) >> 2; + SRC(7,6)= (t10 + t11 + 1) >> 1; + SRC(7,7)= (t10 + 2*t11 + t12 + 2) >> 2; +} +static void pred8x8l_horizontal_up_c(uint8_t *src, int has_topleft, int has_topright, int stride) +{ + PREDICT_8x8_LOAD_LEFT; + SRC(0,0)= (l0 + l1 + 1) >> 1; + SRC(1,0)= (l0 + 2*l1 + l2 + 2) >> 2; + SRC(0,1)=SRC(2,0)= (l1 + l2 + 1) >> 1; + SRC(1,1)=SRC(3,0)= (l1 + 2*l2 + l3 + 2) >> 2; + SRC(0,2)=SRC(2,1)=SRC(4,0)= (l2 + l3 + 1) >> 1; + SRC(1,2)=SRC(3,1)=SRC(5,0)= (l2 + 2*l3 + l4 + 2) >> 2; + SRC(0,3)=SRC(2,2)=SRC(4,1)=SRC(6,0)= (l3 + l4 + 1) >> 1; + SRC(1,3)=SRC(3,2)=SRC(5,1)=SRC(7,0)= (l3 + 2*l4 + l5 + 2) >> 2; + SRC(0,4)=SRC(2,3)=SRC(4,2)=SRC(6,1)= (l4 + l5 + 1) >> 1; + SRC(1,4)=SRC(3,3)=SRC(5,2)=SRC(7,1)= (l4 + 2*l5 + l6 + 2) >> 2; + SRC(0,5)=SRC(2,4)=SRC(4,3)=SRC(6,2)= (l5 + l6 + 1) >> 1; + SRC(1,5)=SRC(3,4)=SRC(5,3)=SRC(7,2)= (l5 + 2*l6 + l7 + 2) >> 2; + SRC(0,6)=SRC(2,5)=SRC(4,4)=SRC(6,3)= (l6 + l7 + 1) >> 1; + SRC(1,6)=SRC(3,5)=SRC(5,4)=SRC(7,3)= (l6 + 3*l7 + 2) >> 2; + SRC(0,7)=SRC(1,7)=SRC(2,6)=SRC(2,7)=SRC(3,6)= + SRC(3,7)=SRC(4,5)=SRC(4,6)=SRC(4,7)=SRC(5,5)= + SRC(5,6)=SRC(5,7)=SRC(6,4)=SRC(6,5)=SRC(6,6)= + SRC(6,7)=SRC(7,4)=SRC(7,5)=SRC(7,6)=SRC(7,7)= l7; +} +#undef PREDICT_8x8_LOAD_LEFT +#undef PREDICT_8x8_LOAD_TOP +#undef PREDICT_8x8_LOAD_TOPLEFT +#undef PREDICT_8x8_LOAD_TOPRIGHT +#undef PREDICT_8x8_DC +#undef PTR +#undef PT +#undef PL +#undef SRC + +static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square, int chroma_height, int delta, int list, + uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + int src_x_offset, int src_y_offset, + qpel_mc_func *qpix_op, h264_chroma_mc_func chroma_op){ + MpegEncContext * const s = &h->s; + const int mx= h->mv_cache[list][ scan8[n] ][0] + src_x_offset*8; + const int my= h->mv_cache[list][ scan8[n] ][1] + src_y_offset*8; + const int luma_xy= (mx&3) + ((my&3)<<2); + uint8_t * src_y = pic->data[0] + (mx>>2) + (my>>2)*s->linesize; + uint8_t * src_cb= pic->data[1] + (mx>>3) + (my>>3)*s->uvlinesize; + uint8_t * src_cr= pic->data[2] + (mx>>3) + (my>>3)*s->uvlinesize; + int extra_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16; //FIXME increase edge?, IMHO not worth it + int extra_height= extra_width; + int emu=0; + const int full_mx= mx>>2; + const int full_my= my>>2; + const int pic_width = 16*s->mb_width; + const int pic_height = 16*s->mb_height; + + if(!pic->data[0]) + return; + + if(mx&7) extra_width -= 3; + if(my&7) extra_height -= 3; + + if( full_mx < 0-extra_width + || full_my < 0-extra_height + || full_mx + 16/*FIXME*/ > pic_width + extra_width + || full_my + 16/*FIXME*/ > pic_height + extra_height){ + ff_emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*s->linesize, s->linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height); + src_y= s->edge_emu_buffer + 2 + 2*s->linesize; + emu=1; + } + + qpix_op[luma_xy](dest_y, src_y, s->linesize); //FIXME try variable height perhaps? + if(!square){ + qpix_op[luma_xy](dest_y + delta, src_y + delta, s->linesize); + } + + if(s->flags&CODEC_FLAG_GRAY) return; + + if(emu){ + ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1); + src_cb= s->edge_emu_buffer; + } + chroma_op(dest_cb, src_cb, s->uvlinesize, chroma_height, mx&7, my&7); + + if(emu){ + ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1); + src_cr= s->edge_emu_buffer; + } + chroma_op(dest_cr, src_cr, s->uvlinesize, chroma_height, mx&7, my&7); +} + +static inline void mc_part_std(H264Context *h, int n, int square, int chroma_height, int delta, + uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + int x_offset, int y_offset, + qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put, + qpel_mc_func *qpix_avg, h264_chroma_mc_func chroma_avg, + int list0, int list1){ + MpegEncContext * const s = &h->s; + qpel_mc_func *qpix_op= qpix_put; + h264_chroma_mc_func chroma_op= chroma_put; + + dest_y += 2*x_offset + 2*y_offset*s-> linesize; + dest_cb += x_offset + y_offset*s->uvlinesize; + dest_cr += x_offset + y_offset*s->uvlinesize; + x_offset += 8*s->mb_x; + y_offset += 8*s->mb_y; + + if(list0){ + Picture *ref= &h->ref_list[0][ h->ref_cache[0][ scan8[n] ] ]; + mc_dir_part(h, ref, n, square, chroma_height, delta, 0, + dest_y, dest_cb, dest_cr, x_offset, y_offset, + qpix_op, chroma_op); + + qpix_op= qpix_avg; + chroma_op= chroma_avg; + } + + if(list1){ + Picture *ref= &h->ref_list[1][ h->ref_cache[1][ scan8[n] ] ]; + mc_dir_part(h, ref, n, square, chroma_height, delta, 1, + dest_y, dest_cb, dest_cr, x_offset, y_offset, + qpix_op, chroma_op); + } +} + +static inline void mc_part_weighted(H264Context *h, int n, int square, int chroma_height, int delta, + uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + int x_offset, int y_offset, + qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put, + h264_weight_func luma_weight_op, h264_weight_func chroma_weight_op, + h264_biweight_func luma_weight_avg, h264_biweight_func chroma_weight_avg, + int list0, int list1){ + MpegEncContext * const s = &h->s; + + dest_y += 2*x_offset + 2*y_offset*s-> linesize; + dest_cb += x_offset + y_offset*s->uvlinesize; + dest_cr += x_offset + y_offset*s->uvlinesize; + x_offset += 8*s->mb_x; + y_offset += 8*s->mb_y; + + if(list0 && list1){ + /* don't optimize for luma-only case, since B-frames usually + * use implicit weights => chroma too. */ + uint8_t *tmp_cb = s->obmc_scratchpad; + uint8_t *tmp_cr = tmp_cb + 8*s->uvlinesize; + uint8_t *tmp_y = tmp_cr + 8*s->uvlinesize; + int refn0 = h->ref_cache[0][ scan8[n] ]; + int refn1 = h->ref_cache[1][ scan8[n] ]; + + mc_dir_part(h, &h->ref_list[0][refn0], n, square, chroma_height, delta, 0, + dest_y, dest_cb, dest_cr, + x_offset, y_offset, qpix_put, chroma_put); + mc_dir_part(h, &h->ref_list[1][refn1], n, square, chroma_height, delta, 1, + tmp_y, tmp_cb, tmp_cr, + x_offset, y_offset, qpix_put, chroma_put); + + if(h->use_weight == 2){ + int weight0 = h->implicit_weight[refn0][refn1]; + int weight1 = 64 - weight0; + luma_weight_avg( dest_y, tmp_y, s-> linesize, 5, weight0, weight1, 0); + chroma_weight_avg(dest_cb, tmp_cb, s->uvlinesize, 5, weight0, weight1, 0); + chroma_weight_avg(dest_cr, tmp_cr, s->uvlinesize, 5, weight0, weight1, 0); + }else{ + luma_weight_avg(dest_y, tmp_y, s->linesize, h->luma_log2_weight_denom, + h->luma_weight[0][refn0], h->luma_weight[1][refn1], + h->luma_offset[0][refn0] + h->luma_offset[1][refn1]); + chroma_weight_avg(dest_cb, tmp_cb, s->uvlinesize, h->chroma_log2_weight_denom, + h->chroma_weight[0][refn0][0], h->chroma_weight[1][refn1][0], + h->chroma_offset[0][refn0][0] + h->chroma_offset[1][refn1][0]); + chroma_weight_avg(dest_cr, tmp_cr, s->uvlinesize, h->chroma_log2_weight_denom, + h->chroma_weight[0][refn0][1], h->chroma_weight[1][refn1][1], + h->chroma_offset[0][refn0][1] + h->chroma_offset[1][refn1][1]); + } + }else{ + int list = list1 ? 1 : 0; + int refn = h->ref_cache[list][ scan8[n] ]; + Picture *ref= &h->ref_list[list][refn]; + mc_dir_part(h, ref, n, square, chroma_height, delta, list, + dest_y, dest_cb, dest_cr, x_offset, y_offset, + qpix_put, chroma_put); + + luma_weight_op(dest_y, s->linesize, h->luma_log2_weight_denom, + h->luma_weight[list][refn], h->luma_offset[list][refn]); + if(h->use_weight_chroma){ + chroma_weight_op(dest_cb, s->uvlinesize, h->chroma_log2_weight_denom, + h->chroma_weight[list][refn][0], h->chroma_offset[list][refn][0]); + chroma_weight_op(dest_cr, s->uvlinesize, h->chroma_log2_weight_denom, + h->chroma_weight[list][refn][1], h->chroma_offset[list][refn][1]); + } + } +} + +static inline void mc_part(H264Context *h, int n, int square, int chroma_height, int delta, + uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + int x_offset, int y_offset, + qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put, + qpel_mc_func *qpix_avg, h264_chroma_mc_func chroma_avg, + h264_weight_func *weight_op, h264_biweight_func *weight_avg, + int list0, int list1){ + if((h->use_weight==2 && list0 && list1 + && (h->implicit_weight[ h->ref_cache[0][scan8[n]] ][ h->ref_cache[1][scan8[n]] ] != 32)) + || h->use_weight==1) + mc_part_weighted(h, n, square, chroma_height, delta, dest_y, dest_cb, dest_cr, + x_offset, y_offset, qpix_put, chroma_put, + weight_op[0], weight_op[3], weight_avg[0], weight_avg[3], list0, list1); + else + mc_part_std(h, n, square, chroma_height, delta, dest_y, dest_cb, dest_cr, + x_offset, y_offset, qpix_put, chroma_put, qpix_avg, chroma_avg, list0, list1); +} + +static inline void prefetch_motion(H264Context *h, int list){ + /* fetch pixels for estimated mv 4 macroblocks ahead + * optimized for 64byte cache lines */ + MpegEncContext * const s = &h->s; + const int refn = h->ref_cache[list][scan8[0]]; + if(refn >= 0){ + const int mx= (h->mv_cache[list][scan8[0]][0]>>2) + 16*s->mb_x + 8; + const int my= (h->mv_cache[list][scan8[0]][1]>>2) + 16*s->mb_y; + uint8_t **src= h->ref_list[list][refn].data; + int off= mx + (my + (s->mb_x&3)*4)*s->linesize + 64; + s->dsp.prefetch(src[0]+off, s->linesize, 4); + off= (mx>>1) + ((my>>1) + (s->mb_x&7))*s->uvlinesize + 64; + s->dsp.prefetch(src[1]+off, src[2]-src[1], 2); + } +} + +static void hl_motion(H264Context *h, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, + qpel_mc_func (*qpix_put)[16], h264_chroma_mc_func (*chroma_put), + qpel_mc_func (*qpix_avg)[16], h264_chroma_mc_func (*chroma_avg), + h264_weight_func *weight_op, h264_biweight_func *weight_avg){ + MpegEncContext * const s = &h->s; + const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; + const int mb_type= s->current_picture.mb_type[mb_xy]; + + assert(IS_INTER(mb_type)); + + prefetch_motion(h, 0); + + if(IS_16X16(mb_type)){ + mc_part(h, 0, 1, 8, 0, dest_y, dest_cb, dest_cr, 0, 0, + qpix_put[0], chroma_put[0], qpix_avg[0], chroma_avg[0], + &weight_op[0], &weight_avg[0], + IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1)); + }else if(IS_16X8(mb_type)){ + mc_part(h, 0, 0, 4, 8, dest_y, dest_cb, dest_cr, 0, 0, + qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0], + &weight_op[1], &weight_avg[1], + IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1)); + mc_part(h, 8, 0, 4, 8, dest_y, dest_cb, dest_cr, 0, 4, + qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0], + &weight_op[1], &weight_avg[1], + IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1)); + }else if(IS_8X16(mb_type)){ + mc_part(h, 0, 0, 8, 8*s->linesize, dest_y, dest_cb, dest_cr, 0, 0, + qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1], + &weight_op[2], &weight_avg[2], + IS_DIR(mb_type, 0, 0), IS_DIR(mb_type, 0, 1)); + mc_part(h, 4, 0, 8, 8*s->linesize, dest_y, dest_cb, dest_cr, 4, 0, + qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1], + &weight_op[2], &weight_avg[2], + IS_DIR(mb_type, 1, 0), IS_DIR(mb_type, 1, 1)); + }else{ + int i; + + assert(IS_8X8(mb_type)); + + for(i=0; i<4; i++){ + const int sub_mb_type= h->sub_mb_type[i]; + const int n= 4*i; + int x_offset= (i&1)<<2; + int y_offset= (i&2)<<1; + + if(IS_SUB_8X8(sub_mb_type)){ + mc_part(h, n, 1, 4, 0, dest_y, dest_cb, dest_cr, x_offset, y_offset, + qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1], + &weight_op[3], &weight_avg[3], + IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1)); + }else if(IS_SUB_8X4(sub_mb_type)){ + mc_part(h, n , 0, 2, 4, dest_y, dest_cb, dest_cr, x_offset, y_offset, + qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1], + &weight_op[4], &weight_avg[4], + IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1)); + mc_part(h, n+2, 0, 2, 4, dest_y, dest_cb, dest_cr, x_offset, y_offset+2, + qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1], + &weight_op[4], &weight_avg[4], + IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1)); + }else if(IS_SUB_4X8(sub_mb_type)){ + mc_part(h, n , 0, 4, 4*s->linesize, dest_y, dest_cb, dest_cr, x_offset, y_offset, + qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2], + &weight_op[5], &weight_avg[5], + IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1)); + mc_part(h, n+1, 0, 4, 4*s->linesize, dest_y, dest_cb, dest_cr, x_offset+2, y_offset, + qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2], + &weight_op[5], &weight_avg[5], + IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1)); + }else{ + int j; + assert(IS_SUB_4X4(sub_mb_type)); + for(j=0; j<4; j++){ + int sub_x_offset= x_offset + 2*(j&1); + int sub_y_offset= y_offset + (j&2); + mc_part(h, n+j, 1, 2, 0, dest_y, dest_cb, dest_cr, sub_x_offset, sub_y_offset, + qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2], + &weight_op[6], &weight_avg[6], + IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1)); + } + } + } + } + + prefetch_motion(h, 1); +} + +static void decode_init_vlc(H264Context *h){ + static int done = 0; + + if (!done) { + int i; + done = 1; + + init_vlc(&chroma_dc_coeff_token_vlc, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 4*5, + &chroma_dc_coeff_token_len [0], 1, 1, + &chroma_dc_coeff_token_bits[0], 1, 1, 1); + + for(i=0; i<4; i++){ + init_vlc(&coeff_token_vlc[i], COEFF_TOKEN_VLC_BITS, 4*17, + &coeff_token_len [i][0], 1, 1, + &coeff_token_bits[i][0], 1, 1, 1); + } + + for(i=0; i<3; i++){ + init_vlc(&chroma_dc_total_zeros_vlc[i], CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 4, + &chroma_dc_total_zeros_len [i][0], 1, 1, + &chroma_dc_total_zeros_bits[i][0], 1, 1, 1); + } + for(i=0; i<15; i++){ + init_vlc(&total_zeros_vlc[i], TOTAL_ZEROS_VLC_BITS, 16, + &total_zeros_len [i][0], 1, 1, + &total_zeros_bits[i][0], 1, 1, 1); + } + + for(i=0; i<6; i++){ + init_vlc(&run_vlc[i], RUN_VLC_BITS, 7, + &run_len [i][0], 1, 1, + &run_bits[i][0], 1, 1, 1); + } + init_vlc(&run7_vlc, RUN7_VLC_BITS, 16, + &run_len [6][0], 1, 1, + &run_bits[6][0], 1, 1, 1); + } +} + +/** + * Sets the intra prediction function pointers. + */ +static void init_pred_ptrs(H264Context *h){ +// MpegEncContext * const s = &h->s; + + h->pred4x4[VERT_PRED ]= pred4x4_vertical_c; + h->pred4x4[HOR_PRED ]= pred4x4_horizontal_c; + h->pred4x4[DC_PRED ]= pred4x4_dc_c; + h->pred4x4[DIAG_DOWN_LEFT_PRED ]= pred4x4_down_left_c; + h->pred4x4[DIAG_DOWN_RIGHT_PRED]= pred4x4_down_right_c; + h->pred4x4[VERT_RIGHT_PRED ]= pred4x4_vertical_right_c; + h->pred4x4[HOR_DOWN_PRED ]= pred4x4_horizontal_down_c; + h->pred4x4[VERT_LEFT_PRED ]= pred4x4_vertical_left_c; + h->pred4x4[HOR_UP_PRED ]= pred4x4_horizontal_up_c; + h->pred4x4[LEFT_DC_PRED ]= pred4x4_left_dc_c; + h->pred4x4[TOP_DC_PRED ]= pred4x4_top_dc_c; + h->pred4x4[DC_128_PRED ]= pred4x4_128_dc_c; + + h->pred8x8l[VERT_PRED ]= pred8x8l_vertical_c; + h->pred8x8l[HOR_PRED ]= pred8x8l_horizontal_c; + h->pred8x8l[DC_PRED ]= pred8x8l_dc_c; + h->pred8x8l[DIAG_DOWN_LEFT_PRED ]= pred8x8l_down_left_c; + h->pred8x8l[DIAG_DOWN_RIGHT_PRED]= pred8x8l_down_right_c; + h->pred8x8l[VERT_RIGHT_PRED ]= pred8x8l_vertical_right_c; + h->pred8x8l[HOR_DOWN_PRED ]= pred8x8l_horizontal_down_c; + h->pred8x8l[VERT_LEFT_PRED ]= pred8x8l_vertical_left_c; + h->pred8x8l[HOR_UP_PRED ]= pred8x8l_horizontal_up_c; + h->pred8x8l[LEFT_DC_PRED ]= pred8x8l_left_dc_c; + h->pred8x8l[TOP_DC_PRED ]= pred8x8l_top_dc_c; + h->pred8x8l[DC_128_PRED ]= pred8x8l_128_dc_c; + + h->pred8x8[DC_PRED8x8 ]= pred8x8_dc_c; + h->pred8x8[VERT_PRED8x8 ]= pred8x8_vertical_c; + h->pred8x8[HOR_PRED8x8 ]= pred8x8_horizontal_c; + h->pred8x8[PLANE_PRED8x8 ]= pred8x8_plane_c; + h->pred8x8[LEFT_DC_PRED8x8]= pred8x8_left_dc_c; + h->pred8x8[TOP_DC_PRED8x8 ]= pred8x8_top_dc_c; + h->pred8x8[DC_128_PRED8x8 ]= pred8x8_128_dc_c; + + h->pred16x16[DC_PRED8x8 ]= pred16x16_dc_c; + h->pred16x16[VERT_PRED8x8 ]= pred16x16_vertical_c; + h->pred16x16[HOR_PRED8x8 ]= pred16x16_horizontal_c; + h->pred16x16[PLANE_PRED8x8 ]= pred16x16_plane_c; + h->pred16x16[LEFT_DC_PRED8x8]= pred16x16_left_dc_c; + h->pred16x16[TOP_DC_PRED8x8 ]= pred16x16_top_dc_c; + h->pred16x16[DC_128_PRED8x8 ]= pred16x16_128_dc_c; +} + +static void free_tables(H264Context *h){ + av_freep(&h->intra4x4_pred_mode); + av_freep(&h->chroma_pred_mode_table); + av_freep(&h->cbp_table); + av_freep(&h->mvd_table[0]); + av_freep(&h->mvd_table[1]); + av_freep(&h->direct_table); + av_freep(&h->non_zero_count); + av_freep(&h->slice_table_base); + av_freep(&h->top_borders[1]); + av_freep(&h->top_borders[0]); + h->slice_table= NULL; + + av_freep(&h->mb2b_xy); + av_freep(&h->mb2b8_xy); + + av_freep(&h->s.obmc_scratchpad); +} + +static void init_dequant8_coeff_table(H264Context *h){ + int i,q,x; + const int transpose = (h->s.dsp.h264_idct8_add != ff_h264_idct8_add_c); //FIXME ugly + h->dequant8_coeff[0] = h->dequant8_buffer[0]; + h->dequant8_coeff[1] = h->dequant8_buffer[1]; + + for(i=0; i<2; i++ ){ + if(i && !memcmp(h->pps.scaling_matrix8[0], h->pps.scaling_matrix8[1], 64*sizeof(uint8_t))){ + h->dequant8_coeff[1] = h->dequant8_buffer[0]; + break; + } + + for(q=0; q<52; q++){ + int shift = div6[q]; + int idx = rem6[q]; + for(x=0; x<64; x++) + h->dequant8_coeff[i][q][transpose ? (x>>3)|((x&7)<<3) : x] = + ((uint32_t)dequant8_coeff_init[idx][ dequant8_coeff_init_scan[((x>>1)&12) | (x&3)] ] * + h->pps.scaling_matrix8[i][x]) << shift; + } + } +} + +static void init_dequant4_coeff_table(H264Context *h){ + int i,j,q,x; + const int transpose = (h->s.dsp.h264_idct_add != ff_h264_idct_add_c); //FIXME ugly + for(i=0; i<6; i++ ){ + h->dequant4_coeff[i] = h->dequant4_buffer[i]; + for(j=0; jpps.scaling_matrix4[j], h->pps.scaling_matrix4[i], 16*sizeof(uint8_t))){ + h->dequant4_coeff[i] = h->dequant4_buffer[j]; + break; + } + } + if(jdequant4_coeff[i][q][transpose ? (x>>2)|((x<<2)&0xF) : x] = + ((uint32_t)dequant4_coeff_init[idx][(x&1) + ((x>>2)&1)] * + h->pps.scaling_matrix4[i][x]) << shift; + } + } +} + +static void init_dequant_tables(H264Context *h){ + int i,x; + init_dequant4_coeff_table(h); + if(h->pps.transform_8x8_mode) + init_dequant8_coeff_table(h); + if(h->sps.transform_bypass){ + for(i=0; i<6; i++) + for(x=0; x<16; x++) + h->dequant4_coeff[i][0][x] = 1<<6; + if(h->pps.transform_8x8_mode) + for(i=0; i<2; i++) + for(x=0; x<64; x++) + h->dequant8_coeff[i][0][x] = 1<<6; + } +} + + +/** + * allocates tables. + * needs width/height + */ +static int alloc_tables(H264Context *h){ + MpegEncContext * const s = &h->s; + const int big_mb_num= s->mb_stride * (s->mb_height+1); + int x,y; + + CHECKED_ALLOCZ(h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t)) + + CHECKED_ALLOCZ(h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t)) + CHECKED_ALLOCZ(h->slice_table_base , big_mb_num * sizeof(uint8_t)) + CHECKED_ALLOCZ(h->top_borders[0] , s->mb_width * (16+8+8) * sizeof(uint8_t)) + CHECKED_ALLOCZ(h->top_borders[1] , s->mb_width * (16+8+8) * sizeof(uint8_t)) + CHECKED_ALLOCZ(h->cbp_table, big_mb_num * sizeof(uint16_t)) + + if( h->pps.cabac ) { + CHECKED_ALLOCZ(h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t)) + CHECKED_ALLOCZ(h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t)); + CHECKED_ALLOCZ(h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t)); + CHECKED_ALLOCZ(h->direct_table, 32*big_mb_num * sizeof(uint8_t)); + } + + memset(h->slice_table_base, -1, big_mb_num * sizeof(uint8_t)); + h->slice_table= h->slice_table_base + s->mb_stride + 1; + + CHECKED_ALLOCZ(h->mb2b_xy , big_mb_num * sizeof(uint32_t)); + CHECKED_ALLOCZ(h->mb2b8_xy , big_mb_num * sizeof(uint32_t)); + for(y=0; ymb_height; y++){ + for(x=0; xmb_width; x++){ + const int mb_xy= x + y*s->mb_stride; + const int b_xy = 4*x + 4*y*h->b_stride; + const int b8_xy= 2*x + 2*y*h->b8_stride; + + h->mb2b_xy [mb_xy]= b_xy; + h->mb2b8_xy[mb_xy]= b8_xy; + } + } + + s->obmc_scratchpad = NULL; + + if(!h->dequant4_coeff[0]) + init_dequant_tables(h); + + return 0; +fail: + free_tables(h); + return -1; +} + +static void common_init(H264Context *h){ + MpegEncContext * const s = &h->s; + + s->width = s->avctx->width; + s->height = s->avctx->height; + s->codec_id= s->avctx->codec->id; + + init_pred_ptrs(h); + + h->dequant_coeff_pps= -1; + s->unrestricted_mv=1; + s->decode=1; //FIXME + + memset(h->pps.scaling_matrix4, 16, 6*16*sizeof(uint8_t)); + memset(h->pps.scaling_matrix8, 16, 2*64*sizeof(uint8_t)); +} + +static int decode_init(AVCodecContext *avctx){ + H264Context *h= avctx->priv_data; + MpegEncContext * const s = &h->s; + + MPV_decode_defaults(s); + + s->avctx = avctx; + common_init(h); + + s->out_format = FMT_H264; + s->workaround_bugs= avctx->workaround_bugs; + + // set defaults +// s->decode_mb= ff_h263_decode_mb; + s->low_delay= 1; + avctx->pix_fmt= PIX_FMT_YUV420P; + + decode_init_vlc(h); + + if(avctx->extradata_size > 0 && avctx->extradata && + *(char *)avctx->extradata == 1){ + h->is_avc = 1; + h->got_avcC = 0; + } else { + h->is_avc = 0; + } + + return 0; +} + +static int frame_start(H264Context *h){ + MpegEncContext * const s = &h->s; + int i; + + if(MPV_frame_start(s, s->avctx) < 0) + return -1; + ff_er_frame_start(s); + + assert(s->linesize && s->uvlinesize); + + for(i=0; i<16; i++){ + h->block_offset[i]= 4*((scan8[i] - scan8[0])&7) + 4*s->linesize*((scan8[i] - scan8[0])>>3); + h->block_offset[24+i]= 4*((scan8[i] - scan8[0])&7) + 8*s->linesize*((scan8[i] - scan8[0])>>3); + } + for(i=0; i<4; i++){ + h->block_offset[16+i]= + h->block_offset[20+i]= 4*((scan8[i] - scan8[0])&7) + 4*s->uvlinesize*((scan8[i] - scan8[0])>>3); + h->block_offset[24+16+i]= + h->block_offset[24+20+i]= 4*((scan8[i] - scan8[0])&7) + 8*s->uvlinesize*((scan8[i] - scan8[0])>>3); + } + + /* can't be in alloc_tables because linesize isn't known there. + * FIXME: redo bipred weight to not require extra buffer? */ + if(!s->obmc_scratchpad) + s->obmc_scratchpad = av_malloc(16*s->linesize + 2*8*s->uvlinesize); + +// s->decode= (s->flags&CODEC_FLAG_PSNR) || !s->encoding || s->current_picture.reference /*|| h->contains_intra*/ || 1; + return 0; +} + +static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize){ + MpegEncContext * const s = &h->s; + int i; + + src_y -= linesize; + src_cb -= uvlinesize; + src_cr -= uvlinesize; + + // There are two lines saved, the line above the the top macroblock of a pair, + // and the line above the bottom macroblock + h->left_border[0]= h->top_borders[0][s->mb_x][15]; + for(i=1; i<17; i++){ + h->left_border[i]= src_y[15+i* linesize]; + } + + *(uint64_t*)(h->top_borders[0][s->mb_x]+0)= *(uint64_t*)(src_y + 16*linesize); + *(uint64_t*)(h->top_borders[0][s->mb_x]+8)= *(uint64_t*)(src_y +8+16*linesize); + + if(!(s->flags&CODEC_FLAG_GRAY)){ + h->left_border[17 ]= h->top_borders[0][s->mb_x][16+7]; + h->left_border[17+9]= h->top_borders[0][s->mb_x][24+7]; + for(i=1; i<9; i++){ + h->left_border[i+17 ]= src_cb[7+i*uvlinesize]; + h->left_border[i+17+9]= src_cr[7+i*uvlinesize]; + } + *(uint64_t*)(h->top_borders[0][s->mb_x]+16)= *(uint64_t*)(src_cb+8*uvlinesize); + *(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+8*uvlinesize); + } +} + +static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int xchg){ + MpegEncContext * const s = &h->s; + int temp8, i; + uint64_t temp64; + int deblock_left = (s->mb_x > 0); + int deblock_top = (s->mb_y > 0); + + src_y -= linesize + 1; + src_cb -= uvlinesize + 1; + src_cr -= uvlinesize + 1; + +#define XCHG(a,b,t,xchg)\ +t= a;\ +if(xchg)\ + a= b;\ +b= t; + + if(deblock_left){ + for(i = !deblock_top; i<17; i++){ + XCHG(h->left_border[i ], src_y [i* linesize], temp8, xchg); + } + } + + if(deblock_top){ + XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+0), *(uint64_t*)(src_y +1), temp64, xchg); + XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+8), *(uint64_t*)(src_y +9), temp64, 1); + if(s->mb_x+1 < s->mb_width){ + XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x+1]), *(uint64_t*)(src_y +17), temp64, 1); + } + } + + if(!(s->flags&CODEC_FLAG_GRAY)){ + if(deblock_left){ + for(i = !deblock_top; i<9; i++){ + XCHG(h->left_border[i+17 ], src_cb[i*uvlinesize], temp8, xchg); + XCHG(h->left_border[i+17+9], src_cr[i*uvlinesize], temp8, xchg); + } + } + if(deblock_top){ + XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+16), *(uint64_t*)(src_cb+1), temp64, 1); + XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+24), *(uint64_t*)(src_cr+1), temp64, 1); + } + } +} + +static inline void backup_pair_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize){ + MpegEncContext * const s = &h->s; + int i; + + src_y -= 2 * linesize; + src_cb -= 2 * uvlinesize; + src_cr -= 2 * uvlinesize; + + // There are two lines saved, the line above the the top macroblock of a pair, + // and the line above the bottom macroblock + h->left_border[0]= h->top_borders[0][s->mb_x][15]; + h->left_border[1]= h->top_borders[1][s->mb_x][15]; + for(i=2; i<34; i++){ + h->left_border[i]= src_y[15+i* linesize]; + } + + *(uint64_t*)(h->top_borders[0][s->mb_x]+0)= *(uint64_t*)(src_y + 32*linesize); + *(uint64_t*)(h->top_borders[0][s->mb_x]+8)= *(uint64_t*)(src_y +8+32*linesize); + *(uint64_t*)(h->top_borders[1][s->mb_x]+0)= *(uint64_t*)(src_y + 33*linesize); + *(uint64_t*)(h->top_borders[1][s->mb_x]+8)= *(uint64_t*)(src_y +8+33*linesize); + + if(!(s->flags&CODEC_FLAG_GRAY)){ + h->left_border[34 ]= h->top_borders[0][s->mb_x][16+7]; + h->left_border[34+ 1]= h->top_borders[1][s->mb_x][16+7]; + h->left_border[34+18 ]= h->top_borders[0][s->mb_x][24+7]; + h->left_border[34+18+1]= h->top_borders[1][s->mb_x][24+7]; + for(i=2; i<18; i++){ + h->left_border[i+34 ]= src_cb[7+i*uvlinesize]; + h->left_border[i+34+18]= src_cr[7+i*uvlinesize]; + } + *(uint64_t*)(h->top_borders[0][s->mb_x]+16)= *(uint64_t*)(src_cb+16*uvlinesize); + *(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+16*uvlinesize); + *(uint64_t*)(h->top_borders[1][s->mb_x]+16)= *(uint64_t*)(src_cb+17*uvlinesize); + *(uint64_t*)(h->top_borders[1][s->mb_x]+24)= *(uint64_t*)(src_cr+17*uvlinesize); + } +} + +static inline void xchg_pair_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int xchg){ + MpegEncContext * const s = &h->s; + int temp8, i; + uint64_t temp64; + int deblock_left = (s->mb_x > 0); + int deblock_top = (s->mb_y > 0); + + tprintf("xchg_pair_border: src_y:%p src_cb:%p src_cr:%p ls:%d uvls:%d\n", src_y, src_cb, src_cr, linesize, uvlinesize); + + src_y -= 2 * linesize + 1; + src_cb -= 2 * uvlinesize + 1; + src_cr -= 2 * uvlinesize + 1; + +#define XCHG(a,b,t,xchg)\ +t= a;\ +if(xchg)\ + a= b;\ +b= t; + + if(deblock_left){ + for(i = (!deblock_top)<<1; i<34; i++){ + XCHG(h->left_border[i ], src_y [i* linesize], temp8, xchg); + } + } + + if(deblock_top){ + XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+0), *(uint64_t*)(src_y +1), temp64, xchg); + XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+8), *(uint64_t*)(src_y +9), temp64, 1); + XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+0), *(uint64_t*)(src_y +1 +linesize), temp64, xchg); + XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+8), *(uint64_t*)(src_y +9 +linesize), temp64, 1); + } + + if(!(s->flags&CODEC_FLAG_GRAY)){ + if(deblock_left){ + for(i = (!deblock_top) << 1; i<18; i++){ + XCHG(h->left_border[i+34 ], src_cb[i*uvlinesize], temp8, xchg); + XCHG(h->left_border[i+34+18], src_cr[i*uvlinesize], temp8, xchg); + } + } + if(deblock_top){ + XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+16), *(uint64_t*)(src_cb+1), temp64, 1); + XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+24), *(uint64_t*)(src_cr+1), temp64, 1); + XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+16), *(uint64_t*)(src_cb+1 +uvlinesize), temp64, 1); + XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+24), *(uint64_t*)(src_cr+1 +uvlinesize), temp64, 1); + } + } +} + +static void hl_decode_mb(H264Context *h){ + MpegEncContext * const s = &h->s; + const int mb_x= s->mb_x; + const int mb_y= s->mb_y; + const int mb_xy= mb_x + mb_y*s->mb_stride; + const int mb_type= s->current_picture.mb_type[mb_xy]; + uint8_t *dest_y, *dest_cb, *dest_cr; + int linesize, uvlinesize /*dct_offset*/; + int i; + int *block_offset = &h->block_offset[0]; + const unsigned int bottom = mb_y & 1; + const int transform_bypass = (s->qscale == 0 && h->sps.transform_bypass); + void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride); + void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride); + + if(!s->decode) + return; + + dest_y = s->current_picture.data[0] + (mb_y * 16* s->linesize ) + mb_x * 16; + dest_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; + dest_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; + + if (h->mb_field_decoding_flag) { + linesize = s->linesize * 2; + uvlinesize = s->uvlinesize * 2; + block_offset = &h->block_offset[24]; + if(mb_y&1){ //FIXME move out of this func? + dest_y -= s->linesize*15; + dest_cb-= s->uvlinesize*7; + dest_cr-= s->uvlinesize*7; + } + } else { + linesize = s->linesize; + uvlinesize = s->uvlinesize; +// dct_offset = s->linesize * 16; + } + + if(transform_bypass){ + idct_dc_add = + idct_add = IS_8x8DCT(mb_type) ? s->dsp.add_pixels8 : s->dsp.add_pixels4; + }else if(IS_8x8DCT(mb_type)){ + idct_dc_add = s->dsp.h264_idct8_dc_add; + idct_add = s->dsp.h264_idct8_add; + }else{ + idct_dc_add = s->dsp.h264_idct_dc_add; + idct_add = s->dsp.h264_idct_add; + } + + if (IS_INTRA_PCM(mb_type)) { + unsigned int x, y; + + // The pixels are stored in h->mb array in the same order as levels, + // copy them in output in the correct order. + for(i=0; i<16; i++) { + for (y=0; y<4; y++) { + for (x=0; x<4; x++) { + *(dest_y + block_offset[i] + y*linesize + x) = h->mb[i*16+y*4+x]; + } + } + } + for(i=16; i<16+4; i++) { + for (y=0; y<4; y++) { + for (x=0; x<4; x++) { + *(dest_cb + block_offset[i] + y*uvlinesize + x) = h->mb[i*16+y*4+x]; + } + } + } + for(i=20; i<20+4; i++) { + for (y=0; y<4; y++) { + for (x=0; x<4; x++) { + *(dest_cr + block_offset[i] + y*uvlinesize + x) = h->mb[i*16+y*4+x]; + } + } + } + } else { + if(IS_INTRA(mb_type)){ + if(h->deblocking_filter) { + if (h->mb_aff_frame) { + if (!bottom) + xchg_pair_border(h, dest_y, dest_cb, dest_cr, s->linesize, s->uvlinesize, 1); + } else { + xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 1); + } + } + + if(!(s->flags&CODEC_FLAG_GRAY)){ + h->pred8x8[ h->chroma_pred_mode ](dest_cb, uvlinesize); + h->pred8x8[ h->chroma_pred_mode ](dest_cr, uvlinesize); + } + + if(IS_INTRA4x4(mb_type)){ + if(!s->encoding){ + if(IS_8x8DCT(mb_type)){ + for(i=0; i<16; i+=4){ + uint8_t * const ptr= dest_y + block_offset[i]; + const int dir= h->intra4x4_pred_mode_cache[ scan8[i] ]; + const int nnz = h->non_zero_count_cache[ scan8[i] ]; + h->pred8x8l[ dir ](ptr, (h->topleft_samples_available<topright_samples_available<<(i+1))&0x8000, linesize); + if(nnz){ + if(nnz == 1 && h->mb[i*16]) + idct_dc_add(ptr, h->mb + i*16, linesize); + else + idct_add(ptr, h->mb + i*16, linesize); + } + } + }else + for(i=0; i<16; i++){ + uint8_t * const ptr= dest_y + block_offset[i]; + uint8_t *topright; + const int dir= h->intra4x4_pred_mode_cache[ scan8[i] ]; + int nnz, tr; + + if(dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED){ + const int topright_avail= (h->topright_samples_available<pred4x4[ dir ](ptr, topright, linesize); + nnz = h->non_zero_count_cache[ scan8[i] ]; + if(nnz){ + if(s->codec_id == CODEC_ID_H264){ + if(nnz == 1 && h->mb[i*16]) + idct_dc_add(ptr, h->mb + i*16, linesize); + else + idct_add(ptr, h->mb + i*16, linesize); + }else + svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, 0); + } + } + } + }else{ + h->pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize); + if(s->codec_id == CODEC_ID_H264){ + if(!transform_bypass) + h264_luma_dc_dequant_idct_c(h->mb, s->qscale, h->dequant4_coeff[IS_INTRA(mb_type) ? 0:3][s->qscale][0]); + }else + svq3_luma_dc_dequant_idct_c(h->mb, s->qscale); + } + if(h->deblocking_filter) { + if (h->mb_aff_frame) { + if (bottom) { + uint8_t *pair_dest_y = s->current_picture.data[0] + ((mb_y-1) * 16* s->linesize ) + mb_x * 16; + uint8_t *pair_dest_cb = s->current_picture.data[1] + ((mb_y-1) * 8 * s->uvlinesize) + mb_x * 8; + uint8_t *pair_dest_cr = s->current_picture.data[2] + ((mb_y-1) * 8 * s->uvlinesize) + mb_x * 8; + s->mb_y--; + xchg_pair_border(h, pair_dest_y, pair_dest_cb, pair_dest_cr, s->linesize, s->uvlinesize, 0); + s->mb_y++; + } + } else { + xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0); + } + } + }else if(s->codec_id == CODEC_ID_H264){ + hl_motion(h, dest_y, dest_cb, dest_cr, + s->dsp.put_h264_qpel_pixels_tab, s->dsp.put_h264_chroma_pixels_tab, + s->dsp.avg_h264_qpel_pixels_tab, s->dsp.avg_h264_chroma_pixels_tab, + s->dsp.weight_h264_pixels_tab, s->dsp.biweight_h264_pixels_tab); + } + + + if(!IS_INTRA4x4(mb_type)){ + if(s->codec_id == CODEC_ID_H264){ + if(IS_INTRA16x16(mb_type)){ + for(i=0; i<16; i++){ + if(h->non_zero_count_cache[ scan8[i] ]) + idct_add(dest_y + block_offset[i], h->mb + i*16, linesize); + else if(h->mb[i*16]) + idct_dc_add(dest_y + block_offset[i], h->mb + i*16, linesize); + } + }else{ + const int di = IS_8x8DCT(mb_type) ? 4 : 1; + for(i=0; i<16; i+=di){ + int nnz = h->non_zero_count_cache[ scan8[i] ]; + if(nnz){ + if(nnz==1 && h->mb[i*16]) + idct_dc_add(dest_y + block_offset[i], h->mb + i*16, linesize); + else + idct_add(dest_y + block_offset[i], h->mb + i*16, linesize); + } + } + } + }else{ + for(i=0; i<16; i++){ + if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ //FIXME benchmark weird rule, & below + uint8_t * const ptr= dest_y + block_offset[i]; + svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0); + } + } + } + } + + if(!(s->flags&CODEC_FLAG_GRAY)){ + uint8_t *dest[2] = {dest_cb, dest_cr}; + if(transform_bypass){ + idct_add = idct_dc_add = s->dsp.add_pixels4; + }else{ + idct_add = s->dsp.h264_idct_add; + idct_dc_add = s->dsp.h264_idct_dc_add; + chroma_dc_dequant_idct_c(h->mb + 16*16, h->chroma_qp, h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp][0]); + chroma_dc_dequant_idct_c(h->mb + 16*16+4*16, h->chroma_qp, h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp][0]); + } + if(s->codec_id == CODEC_ID_H264){ + for(i=16; i<16+8; i++){ + if(h->non_zero_count_cache[ scan8[i] ]) + idct_add(dest[(i&4)>>2] + block_offset[i], h->mb + i*16, uvlinesize); + else if(h->mb[i*16]) + idct_dc_add(dest[(i&4)>>2] + block_offset[i], h->mb + i*16, uvlinesize); + } + }else{ + for(i=16; i<16+8; i++){ + if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ + uint8_t * const ptr= dest[(i&4)>>2] + block_offset[i]; + svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, chroma_qp[s->qscale + 12] - 12, 2); + } + } + } + } + } + if(h->deblocking_filter) { + if (h->mb_aff_frame) { + const int mb_y = s->mb_y - 1; + uint8_t *pair_dest_y, *pair_dest_cb, *pair_dest_cr; + const int mb_xy= mb_x + mb_y*s->mb_stride; + const int mb_type_top = s->current_picture.mb_type[mb_xy]; + const int mb_type_bottom= s->current_picture.mb_type[mb_xy+s->mb_stride]; + uint8_t tmp = s->current_picture.data[1][384]; + if (!bottom) return; + pair_dest_y = s->current_picture.data[0] + (mb_y * 16* s->linesize ) + mb_x * 16; + pair_dest_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; + pair_dest_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; + + backup_pair_border(h, pair_dest_y, pair_dest_cb, pair_dest_cr, s->linesize, s->uvlinesize); + // TODO deblock a pair + // top + s->mb_y--; + tprintf("call mbaff filter_mb mb_x:%d mb_y:%d pair_dest_y = %p, dest_y = %p\n", mb_x, mb_y, pair_dest_y, dest_y); + fill_caches(h, mb_type_top, 1); //FIXME don't fill stuff which isn't used by filter_mb + filter_mb(h, mb_x, mb_y, pair_dest_y, pair_dest_cb, pair_dest_cr, linesize, uvlinesize); + if (tmp != s->current_picture.data[1][384]) { + tprintf("modified pixel 8,1 (1)\n"); + } + // bottom + s->mb_y++; + tprintf("call mbaff filter_mb\n"); + fill_caches(h, mb_type_bottom, 1); //FIXME don't fill stuff which isn't used by filter_mb + filter_mb(h, mb_x, mb_y+1, dest_y, dest_cb, dest_cr, linesize, uvlinesize); + if (tmp != s->current_picture.data[1][384]) { + tprintf("modified pixel 8,1 (2)\n"); + } + } else { + tprintf("call filter_mb\n"); + backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize); + fill_caches(h, mb_type, 1); //FIXME don't fill stuff which isn't used by filter_mb + filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize); + } + } +} + +/** + * fills the default_ref_list. + */ +static int fill_default_ref_list(H264Context *h){ + MpegEncContext * const s = &h->s; + int i; + int smallest_poc_greater_than_current = -1; + Picture sorted_short_ref[32]; + + if(h->slice_type==B_TYPE){ + int out_i; + int limit= INT_MIN; + + /* sort frame according to poc in B slice */ + for(out_i=0; out_ishort_ref_count; out_i++){ + int best_i=INT_MIN; + int best_poc=INT_MAX; + + for(i=0; ishort_ref_count; i++){ + const int poc= h->short_ref[i]->poc; + if(poc > limit && poc < best_poc){ + best_poc= poc; + best_i= i; + } + } + + assert(best_i != INT_MIN); + + limit= best_poc; + sorted_short_ref[out_i]= *h->short_ref[best_i]; + tprintf("sorted poc: %d->%d poc:%d fn:%d\n", best_i, out_i, sorted_short_ref[out_i].poc, sorted_short_ref[out_i].frame_num); + if (-1 == smallest_poc_greater_than_current) { + if (h->short_ref[best_i]->poc >= s->current_picture_ptr->poc) { + smallest_poc_greater_than_current = out_i; + } + } + } + } + + if(s->picture_structure == PICT_FRAME){ + if(h->slice_type==B_TYPE){ + int list; + tprintf("current poc: %d, smallest_poc_greater_than_current: %d\n", s->current_picture_ptr->poc, smallest_poc_greater_than_current); + + // find the largest poc + for(list=0; list<2; list++){ + int index = 0; + int j= -99; + int step= list ? -1 : 1; + + for(i=0; ishort_ref_count && index < h->ref_count[list]; i++, j+=step) { + while(j<0 || j>= h->short_ref_count){ + if(j != -99 && step == (list ? -1 : 1)) + return -1; + step = -step; + j= smallest_poc_greater_than_current + (step>>1); + } + if(sorted_short_ref[j].reference != 3) continue; + h->default_ref_list[list][index ]= sorted_short_ref[j]; + h->default_ref_list[list][index++].pic_id= sorted_short_ref[j].frame_num; + } + + for(i = 0; i < 16 && index < h->ref_count[ list ]; i++){ + if(h->long_ref[i] == NULL) continue; + if(h->long_ref[i]->reference != 3) continue; + + h->default_ref_list[ list ][index ]= *h->long_ref[i]; + h->default_ref_list[ list ][index++].pic_id= i;; + } + + if(list && (smallest_poc_greater_than_current<=0 || smallest_poc_greater_than_current>=h->short_ref_count) && (1 < index)){ + // swap the two first elements of L1 when + // L0 and L1 are identical + Picture temp= h->default_ref_list[1][0]; + h->default_ref_list[1][0] = h->default_ref_list[1][1]; + h->default_ref_list[1][1] = temp; + } + + if(index < h->ref_count[ list ]) + memset(&h->default_ref_list[list][index], 0, sizeof(Picture)*(h->ref_count[ list ] - index)); + } + }else{ + int index=0; + for(i=0; ishort_ref_count; i++){ + if(h->short_ref[i]->reference != 3) continue; //FIXME refernce field shit + h->default_ref_list[0][index ]= *h->short_ref[i]; + h->default_ref_list[0][index++].pic_id= h->short_ref[i]->frame_num; + } + for(i = 0; i < 16; i++){ + if(h->long_ref[i] == NULL) continue; + if(h->long_ref[i]->reference != 3) continue; + h->default_ref_list[0][index ]= *h->long_ref[i]; + h->default_ref_list[0][index++].pic_id= i;; + } + if(index < h->ref_count[0]) + memset(&h->default_ref_list[0][index], 0, sizeof(Picture)*(h->ref_count[0] - index)); + } + }else{ //FIELD + if(h->slice_type==B_TYPE){ + }else{ + //FIXME second field balh + } + } +#ifdef TRACE + for (i=0; iref_count[0]; i++) { + tprintf("List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].data[0]); + } + if(h->slice_type==B_TYPE){ + for (i=0; iref_count[1]; i++) { + tprintf("List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[0][i].data[0]); + } + } +#endif + return 0; +} + +static void print_short_term(H264Context *h); +static void print_long_term(H264Context *h); + +static int decode_ref_pic_list_reordering(H264Context *h){ + MpegEncContext * const s = &h->s; + int list, index; + + print_short_term(h); + print_long_term(h); + if(h->slice_type==I_TYPE || h->slice_type==SI_TYPE) return 0; //FIXME move before func + + for(list=0; list<2; list++){ + memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]); + + if(get_bits1(&s->gb)){ + int pred= h->curr_pic_num; + + for(index=0; ; index++){ + int reordering_of_pic_nums_idc= get_ue_golomb(&s->gb); + int pic_id; + int i; + Picture *ref = NULL; + + if(reordering_of_pic_nums_idc==3) + break; + + if(index >= h->ref_count[list]){ + av_log(h->s.avctx, AV_LOG_ERROR, "reference count overflow\n"); + return -1; + } + + if(reordering_of_pic_nums_idc<3){ + if(reordering_of_pic_nums_idc<2){ + const int abs_diff_pic_num= get_ue_golomb(&s->gb) + 1; + + if(abs_diff_pic_num >= h->max_pic_num){ + av_log(h->s.avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); + return -1; + } + + if(reordering_of_pic_nums_idc == 0) pred-= abs_diff_pic_num; + else pred+= abs_diff_pic_num; + pred &= h->max_pic_num - 1; + + for(i= h->short_ref_count-1; i>=0; i--){ + ref = h->short_ref[i]; + assert(ref->reference == 3); + assert(!ref->long_ref); + if(ref->data[0] != NULL && ref->frame_num == pred && ref->long_ref == 0) // ignore non existing pictures by testing data[0] pointer + break; + } + if(i>=0) + ref->pic_id= ref->frame_num; + }else{ + pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx + ref = h->long_ref[pic_id]; + ref->pic_id= pic_id; + assert(ref->reference == 3); + assert(ref->long_ref); + i=0; + } + + if (i < 0) { + av_log(h->s.avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); + memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME + } else { + for(i=index; i+1ref_count[list]; i++){ + if(ref->long_ref == h->ref_list[list][i].long_ref && ref->pic_id == h->ref_list[list][i].pic_id) + break; + } + for(; i > index; i--){ + h->ref_list[list][i]= h->ref_list[list][i-1]; + } + h->ref_list[list][index]= *ref; + } + }else{ + av_log(h->s.avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); + return -1; + } + } + } + + if(h->slice_type!=B_TYPE) break; + } + for(list=0; list<2; list++){ + for(index= 0; index < h->ref_count[list]; index++){ + if(!h->ref_list[list][index].data[0]) + h->ref_list[list][index]= s->current_picture; + } + if(h->slice_type!=B_TYPE) break; + } + + if(h->slice_type==B_TYPE && !h->direct_spatial_mv_pred) + direct_dist_scale_factor(h); + direct_ref_list_init(h); + return 0; +} + +static int pred_weight_table(H264Context *h){ + MpegEncContext * const s = &h->s; + int list, i; + int luma_def, chroma_def; + + h->use_weight= 0; + h->use_weight_chroma= 0; + h->luma_log2_weight_denom= get_ue_golomb(&s->gb); + h->chroma_log2_weight_denom= get_ue_golomb(&s->gb); + luma_def = 1<luma_log2_weight_denom; + chroma_def = 1<chroma_log2_weight_denom; + + for(list=0; list<2; list++){ + for(i=0; iref_count[list]; i++){ + int luma_weight_flag, chroma_weight_flag; + + luma_weight_flag= get_bits1(&s->gb); + if(luma_weight_flag){ + h->luma_weight[list][i]= get_se_golomb(&s->gb); + h->luma_offset[list][i]= get_se_golomb(&s->gb); + if( h->luma_weight[list][i] != luma_def + || h->luma_offset[list][i] != 0) + h->use_weight= 1; + }else{ + h->luma_weight[list][i]= luma_def; + h->luma_offset[list][i]= 0; + } + + chroma_weight_flag= get_bits1(&s->gb); + if(chroma_weight_flag){ + int j; + for(j=0; j<2; j++){ + h->chroma_weight[list][i][j]= get_se_golomb(&s->gb); + h->chroma_offset[list][i][j]= get_se_golomb(&s->gb); + if( h->chroma_weight[list][i][j] != chroma_def + || h->chroma_offset[list][i][j] != 0) + h->use_weight_chroma= 1; + } + }else{ + int j; + for(j=0; j<2; j++){ + h->chroma_weight[list][i][j]= chroma_def; + h->chroma_offset[list][i][j]= 0; + } + } + } + if(h->slice_type != B_TYPE) break; + } + h->use_weight= h->use_weight || h->use_weight_chroma; + return 0; +} + +static void implicit_weight_table(H264Context *h){ + MpegEncContext * const s = &h->s; + int ref0, ref1; + int cur_poc = s->current_picture_ptr->poc; + + if( h->ref_count[0] == 1 && h->ref_count[1] == 1 + && h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2*cur_poc){ + h->use_weight= 0; + h->use_weight_chroma= 0; + return; + } + + h->use_weight= 2; + h->use_weight_chroma= 2; + h->luma_log2_weight_denom= 5; + h->chroma_log2_weight_denom= 5; + + /* FIXME: MBAFF */ + for(ref0=0; ref0 < h->ref_count[0]; ref0++){ + int poc0 = h->ref_list[0][ref0].poc; + for(ref1=0; ref1 < h->ref_count[1]; ref1++){ + int poc1 = h->ref_list[1][ref1].poc; + int td = clip(poc1 - poc0, -128, 127); + if(td){ + int tb = clip(cur_poc - poc0, -128, 127); + int tx = (16384 + (ABS(td) >> 1)) / td; + int dist_scale_factor = clip((tb*tx + 32) >> 6, -1024, 1023) >> 2; + if(dist_scale_factor < -64 || dist_scale_factor > 128) + h->implicit_weight[ref0][ref1] = 32; + else + h->implicit_weight[ref0][ref1] = 64 - dist_scale_factor; + }else + h->implicit_weight[ref0][ref1] = 32; + } + } +} + +static inline void unreference_pic(H264Context *h, Picture *pic){ + int i; + pic->reference=0; + if(pic == h->delayed_output_pic) + pic->reference=1; + else{ + for(i = 0; h->delayed_pic[i]; i++) + if(pic == h->delayed_pic[i]){ + pic->reference=1; + break; + } + } +} + +/** + * instantaneous decoder refresh. + */ +static void idr(H264Context *h){ + int i; + + for(i=0; i<16; i++){ + if (h->long_ref[i] != NULL) { + unreference_pic(h, h->long_ref[i]); + h->long_ref[i]= NULL; + } + } + h->long_ref_count=0; + + for(i=0; ishort_ref_count; i++){ + unreference_pic(h, h->short_ref[i]); + h->short_ref[i]= NULL; + } + h->short_ref_count=0; +} + +/* forget old pics after a seek */ +static void flush_dpb(AVCodecContext *avctx){ + H264Context *h= avctx->priv_data; + int i; + for(i=0; i<16; i++) { + if(h->delayed_pic[i]) + h->delayed_pic[i]->reference= 0; + h->delayed_pic[i]= NULL; + } + if(h->delayed_output_pic) + h->delayed_output_pic->reference= 0; + h->delayed_output_pic= NULL; + idr(h); + if(h->s.current_picture_ptr) + h->s.current_picture_ptr->reference= 0; +} + +/** + * + * @return the removed picture or NULL if an error occurs + */ +static Picture * remove_short(H264Context *h, int frame_num){ + MpegEncContext * const s = &h->s; + int i; + + if(s->avctx->debug&FF_DEBUG_MMCO) + av_log(h->s.avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count); + + for(i=0; ishort_ref_count; i++){ + Picture *pic= h->short_ref[i]; + if(s->avctx->debug&FF_DEBUG_MMCO) + av_log(h->s.avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic); + if(pic->frame_num == frame_num){ + h->short_ref[i]= NULL; + memmove(&h->short_ref[i], &h->short_ref[i+1], (h->short_ref_count - i - 1)*sizeof(Picture*)); + h->short_ref_count--; + return pic; + } + } + return NULL; +} + +/** + * + * @return the removed picture or NULL if an error occurs + */ +static Picture * remove_long(H264Context *h, int i){ + Picture *pic; + + pic= h->long_ref[i]; + h->long_ref[i]= NULL; + if(pic) h->long_ref_count--; + + return pic; +} + +/** + * print short term list + */ +static void print_short_term(H264Context *h) { + uint32_t i; + if(h->s.avctx->debug&FF_DEBUG_MMCO) { + av_log(h->s.avctx, AV_LOG_DEBUG, "short term list:\n"); + for(i=0; ishort_ref_count; i++){ + Picture *pic= h->short_ref[i]; + av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", i, pic->frame_num, pic->poc, pic->data[0]); + } + } +} + +/** + * print long term list + */ +static void print_long_term(H264Context *h) { + uint32_t i; + if(h->s.avctx->debug&FF_DEBUG_MMCO) { + av_log(h->s.avctx, AV_LOG_DEBUG, "long term list:\n"); + for(i = 0; i < 16; i++){ + Picture *pic= h->long_ref[i]; + if (pic) { + av_log(h->s.avctx, AV_LOG_DEBUG, "%d fn:%d poc:%d %p\n", i, pic->frame_num, pic->poc, pic->data[0]); + } + } + } +} + +/** + * Executes the reference picture marking (memory management control operations). + */ +static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ + MpegEncContext * const s = &h->s; + int i, j; + int current_is_long=0; + Picture *pic; + + if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0) + av_log(h->s.avctx, AV_LOG_DEBUG, "no mmco here\n"); + + for(i=0; iavctx->debug&FF_DEBUG_MMCO) + av_log(h->s.avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_frame_num, h->mmco[i].long_index); + + switch(mmco[i].opcode){ + case MMCO_SHORT2UNUSED: + pic= remove_short(h, mmco[i].short_frame_num); + if(pic) + unreference_pic(h, pic); + else if(s->avctx->debug&FF_DEBUG_MMCO) + av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_short() failure\n"); + break; + case MMCO_SHORT2LONG: + pic= remove_long(h, mmco[i].long_index); + if(pic) unreference_pic(h, pic); + + h->long_ref[ mmco[i].long_index ]= remove_short(h, mmco[i].short_frame_num); + h->long_ref[ mmco[i].long_index ]->long_ref=1; + h->long_ref_count++; + break; + case MMCO_LONG2UNUSED: + pic= remove_long(h, mmco[i].long_index); + if(pic) + unreference_pic(h, pic); + else if(s->avctx->debug&FF_DEBUG_MMCO) + av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_long() failure\n"); + break; + case MMCO_LONG: + pic= remove_long(h, mmco[i].long_index); + if(pic) unreference_pic(h, pic); + + h->long_ref[ mmco[i].long_index ]= s->current_picture_ptr; + h->long_ref[ mmco[i].long_index ]->long_ref=1; + h->long_ref_count++; + + current_is_long=1; + break; + case MMCO_SET_MAX_LONG: + assert(mmco[i].long_index <= 16); + // just remove the long term which index is greater than new max + for(j = mmco[i].long_index; j<16; j++){ + pic = remove_long(h, j); + if (pic) unreference_pic(h, pic); + } + break; + case MMCO_RESET: + while(h->short_ref_count){ + pic= remove_short(h, h->short_ref[0]->frame_num); + unreference_pic(h, pic); + } + for(j = 0; j < 16; j++) { + pic= remove_long(h, j); + if(pic) unreference_pic(h, pic); + } + break; + default: assert(0); + } + } + + if(!current_is_long){ + pic= remove_short(h, s->current_picture_ptr->frame_num); + if(pic){ + unreference_pic(h, pic); + av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); + } + + if(h->short_ref_count) + memmove(&h->short_ref[1], &h->short_ref[0], h->short_ref_count*sizeof(Picture*)); + + h->short_ref[0]= s->current_picture_ptr; + h->short_ref[0]->long_ref=0; + h->short_ref_count++; + } + + print_short_term(h); + print_long_term(h); + return 0; +} + +static int decode_ref_pic_marking(H264Context *h){ + MpegEncContext * const s = &h->s; + int i; + + if(h->nal_unit_type == NAL_IDR_SLICE){ //FIXME fields + s->broken_link= get_bits1(&s->gb) -1; + h->mmco[0].long_index= get_bits1(&s->gb) - 1; // current_long_term_idx + if(h->mmco[0].long_index == -1) + h->mmco_index= 0; + else{ + h->mmco[0].opcode= MMCO_LONG; + h->mmco_index= 1; + } + }else{ + if(get_bits1(&s->gb)){ // adaptive_ref_pic_marking_mode_flag + for(i= 0; igb);; + + h->mmco[i].opcode= opcode; + if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG){ + h->mmco[i].short_frame_num= (h->frame_num - get_ue_golomb(&s->gb) - 1) & ((1<sps.log2_max_frame_num)-1); //FIXME fields +/* if(h->mmco[i].short_frame_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_frame_num ] == NULL){ + av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control operation %d\n", mmco); + return -1; + }*/ + } + if(opcode==MMCO_SHORT2LONG || opcode==MMCO_LONG2UNUSED || opcode==MMCO_LONG || opcode==MMCO_SET_MAX_LONG){ + h->mmco[i].long_index= get_ue_golomb(&s->gb); + if(/*h->mmco[i].long_index >= h->long_ref_count || h->long_ref[ h->mmco[i].long_index ] == NULL*/ h->mmco[i].long_index >= 16){ + av_log(h->s.avctx, AV_LOG_ERROR, "illegal long ref in memory management control operation %d\n", opcode); + return -1; + } + } + + if(opcode > MMCO_LONG){ + av_log(h->s.avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); + return -1; + } + if(opcode == MMCO_END) + break; + } + h->mmco_index= i; + }else{ + assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count); + + if(h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count){ //FIXME fields + h->mmco[0].opcode= MMCO_SHORT2UNUSED; + h->mmco[0].short_frame_num= h->short_ref[ h->short_ref_count - 1 ]->frame_num; + h->mmco_index= 1; + }else + h->mmco_index= 0; + } + } + + return 0; +} + +static int init_poc(H264Context *h){ + MpegEncContext * const s = &h->s; + const int max_frame_num= 1<sps.log2_max_frame_num; + int field_poc[2]; + + if(h->nal_unit_type == NAL_IDR_SLICE){ + h->frame_num_offset= 0; + }else{ + if(h->frame_num < h->prev_frame_num) + h->frame_num_offset= h->prev_frame_num_offset + max_frame_num; + else + h->frame_num_offset= h->prev_frame_num_offset; + } + + if(h->sps.poc_type==0){ + const int max_poc_lsb= 1<sps.log2_max_poc_lsb; + + if(h->nal_unit_type == NAL_IDR_SLICE){ + h->prev_poc_msb= + h->prev_poc_lsb= 0; + } + + if (h->poc_lsb < h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb/2) + h->poc_msb = h->prev_poc_msb + max_poc_lsb; + else if(h->poc_lsb > h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb/2) + h->poc_msb = h->prev_poc_msb - max_poc_lsb; + else + h->poc_msb = h->prev_poc_msb; +//printf("poc: %d %d\n", h->poc_msb, h->poc_lsb); + field_poc[0] = + field_poc[1] = h->poc_msb + h->poc_lsb; + if(s->picture_structure == PICT_FRAME) + field_poc[1] += h->delta_poc_bottom; + }else if(h->sps.poc_type==1){ + int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc; + int i; + + if(h->sps.poc_cycle_length != 0) + abs_frame_num = h->frame_num_offset + h->frame_num; + else + abs_frame_num = 0; + + if(h->nal_ref_idc==0 && abs_frame_num > 0) + abs_frame_num--; + + expected_delta_per_poc_cycle = 0; + for(i=0; i < h->sps.poc_cycle_length; i++) + expected_delta_per_poc_cycle += h->sps.offset_for_ref_frame[ i ]; //FIXME integrate during sps parse + + if(abs_frame_num > 0){ + int poc_cycle_cnt = (abs_frame_num - 1) / h->sps.poc_cycle_length; + int frame_num_in_poc_cycle = (abs_frame_num - 1) % h->sps.poc_cycle_length; + + expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle; + for(i = 0; i <= frame_num_in_poc_cycle; i++) + expectedpoc = expectedpoc + h->sps.offset_for_ref_frame[ i ]; + } else + expectedpoc = 0; + + if(h->nal_ref_idc == 0) + expectedpoc = expectedpoc + h->sps.offset_for_non_ref_pic; + + field_poc[0] = expectedpoc + h->delta_poc[0]; + field_poc[1] = field_poc[0] + h->sps.offset_for_top_to_bottom_field; + + if(s->picture_structure == PICT_FRAME) + field_poc[1] += h->delta_poc[1]; + }else{ + int poc; + if(h->nal_unit_type == NAL_IDR_SLICE){ + poc= 0; + }else{ + if(h->nal_ref_idc) poc= 2*(h->frame_num_offset + h->frame_num); + else poc= 2*(h->frame_num_offset + h->frame_num) - 1; + } + field_poc[0]= poc; + field_poc[1]= poc; + } + + if(s->picture_structure != PICT_BOTTOM_FIELD) + s->current_picture_ptr->field_poc[0]= field_poc[0]; + if(s->picture_structure != PICT_TOP_FIELD) + s->current_picture_ptr->field_poc[1]= field_poc[1]; + if(s->picture_structure == PICT_FRAME) // FIXME field pix? + s->current_picture_ptr->poc= FFMIN(field_poc[0], field_poc[1]); + + return 0; +} + +/** + * decodes a slice header. + * this will allso call MPV_common_init() and frame_start() as needed + */ +static int decode_slice_header(H264Context *h){ + MpegEncContext * const s = &h->s; + int first_mb_in_slice, pps_id; + int num_ref_idx_active_override_flag; + static const uint8_t slice_type_map[5]= {P_TYPE, B_TYPE, I_TYPE, SP_TYPE, SI_TYPE}; + int slice_type; + int default_ref_list_done = 0; + + s->current_picture.reference= h->nal_ref_idc != 0; + s->dropable= h->nal_ref_idc == 0; + + first_mb_in_slice= get_ue_golomb(&s->gb); + + slice_type= get_ue_golomb(&s->gb); + if(slice_type > 9){ + av_log(h->s.avctx, AV_LOG_ERROR, "slice type too large (%d) at %d %d\n", h->slice_type, s->mb_x, s->mb_y); + return -1; + } + if(slice_type > 4){ + slice_type -= 5; + h->slice_type_fixed=1; + }else + h->slice_type_fixed=0; + + slice_type= slice_type_map[ slice_type ]; + if (slice_type == I_TYPE + || (h->slice_num != 0 && slice_type == h->slice_type) ) { + default_ref_list_done = 1; + } + h->slice_type= slice_type; + + s->pict_type= h->slice_type; // to make a few old func happy, it's wrong though + + pps_id= get_ue_golomb(&s->gb); + if(pps_id>255){ + av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); + return -1; + } + h->pps= h->pps_buffer[pps_id]; + if(h->pps.slice_group_count == 0){ + av_log(h->s.avctx, AV_LOG_ERROR, "non existing PPS referenced\n"); + return -1; + } + + h->sps= h->sps_buffer[ h->pps.sps_id ]; + if(h->sps.log2_max_frame_num == 0){ + av_log(h->s.avctx, AV_LOG_ERROR, "non existing SPS referenced\n"); + return -1; + } + + if(h->dequant_coeff_pps != pps_id){ + h->dequant_coeff_pps = pps_id; + init_dequant_tables(h); + } + + s->mb_width= h->sps.mb_width; + s->mb_height= h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag); + + h->b_stride= s->mb_width*4; + h->b8_stride= s->mb_width*2; + + s->width = 16*s->mb_width - 2*(h->sps.crop_left + h->sps.crop_right ); + if(h->sps.frame_mbs_only_flag) + s->height= 16*s->mb_height - 2*(h->sps.crop_top + h->sps.crop_bottom); + else + s->height= 16*s->mb_height - 4*(h->sps.crop_top + h->sps.crop_bottom); //FIXME recheck + + if (s->context_initialized + && ( s->width != s->avctx->width || s->height != s->avctx->height)) { + free_tables(h); + MPV_common_end(s); + } + if (!s->context_initialized) { + if (MPV_common_init(s) < 0) + return -1; + + if(s->dsp.h264_idct_add == ff_h264_idct_add_c){ //FIXME little ugly + memcpy(h->zigzag_scan, zigzag_scan, 16*sizeof(uint8_t)); + memcpy(h-> field_scan, field_scan, 16*sizeof(uint8_t)); + }else{ + int i; + for(i=0; i<16; i++){ +#define T(x) (x>>2) | ((x<<2) & 0xF) + h->zigzag_scan[i] = T(zigzag_scan[i]); + h-> field_scan[i] = T( field_scan[i]); +#undef T + } + } + if(s->dsp.h264_idct8_add == ff_h264_idct8_add_c){ + memcpy(h->zigzag_scan8x8, zigzag_scan8x8, 64*sizeof(uint8_t)); + memcpy(h->zigzag_scan8x8_cavlc, zigzag_scan8x8_cavlc, 64*sizeof(uint8_t)); + }else{ + int i; + for(i=0; i<64; i++){ +#define T(x) (x>>3) | ((x&7)<<3) + h->zigzag_scan8x8[i] = T(zigzag_scan8x8[i]); + h->zigzag_scan8x8_cavlc[i] = T(zigzag_scan8x8_cavlc[i]); +#undef T + } + } + if(h->sps.transform_bypass){ //FIXME same ugly + h->zigzag_scan_q0 = zigzag_scan; + h->field_scan_q0 = field_scan; + h->zigzag_scan8x8_q0 = zigzag_scan8x8; + h->zigzag_scan8x8_cavlc_q0 = zigzag_scan8x8_cavlc; + }else{ + h->zigzag_scan_q0 = h->zigzag_scan; + h->field_scan_q0 = h->field_scan; + h->zigzag_scan8x8_q0 = h->zigzag_scan8x8; + h->zigzag_scan8x8_cavlc_q0 = h->zigzag_scan8x8_cavlc; + } + + alloc_tables(h); + + s->avctx->width = s->width; + s->avctx->height = s->height; + s->avctx->sample_aspect_ratio= h->sps.sar; + if(!s->avctx->sample_aspect_ratio.den) + s->avctx->sample_aspect_ratio.den = 1; + + if(h->sps.timing_info_present_flag){ + s->avctx->time_base= (AVRational){h->sps.num_units_in_tick * 2, h->sps.time_scale}; + if(h->x264_build > 0 && h->x264_build < 44) + s->avctx->time_base.den *= 2; + av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den, + s->avctx->time_base.num, s->avctx->time_base.den, 1<<30); + } + } + + if(h->slice_num == 0){ + if(frame_start(h) < 0) + return -1; + } + + s->current_picture_ptr->frame_num= //FIXME frame_num cleanup + h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num); + + h->mb_aff_frame = 0; + if(h->sps.frame_mbs_only_flag){ + s->picture_structure= PICT_FRAME; + }else{ + if(get_bits1(&s->gb)) { //field_pic_flag + s->picture_structure= PICT_TOP_FIELD + get_bits1(&s->gb); //bottom_field_flag + } else { + s->picture_structure= PICT_FRAME; + first_mb_in_slice <<= h->sps.mb_aff; + h->mb_aff_frame = h->sps.mb_aff; + } + } + + s->resync_mb_x = s->mb_x = first_mb_in_slice % s->mb_width; + s->resync_mb_y = s->mb_y = first_mb_in_slice / s->mb_width; + if(s->mb_y >= s->mb_height){ + return -1; + } + + if(s->picture_structure==PICT_FRAME){ + h->curr_pic_num= h->frame_num; + h->max_pic_num= 1<< h->sps.log2_max_frame_num; + }else{ + h->curr_pic_num= 2*h->frame_num; + h->max_pic_num= 1<<(h->sps.log2_max_frame_num + 1); + } + + if(h->nal_unit_type == NAL_IDR_SLICE){ + get_ue_golomb(&s->gb); /* idr_pic_id */ + } + + if(h->sps.poc_type==0){ + h->poc_lsb= get_bits(&s->gb, h->sps.log2_max_poc_lsb); + + if(h->pps.pic_order_present==1 && s->picture_structure==PICT_FRAME){ + h->delta_poc_bottom= get_se_golomb(&s->gb); + } + } + + if(h->sps.poc_type==1 && !h->sps.delta_pic_order_always_zero_flag){ + h->delta_poc[0]= get_se_golomb(&s->gb); + + if(h->pps.pic_order_present==1 && s->picture_structure==PICT_FRAME) + h->delta_poc[1]= get_se_golomb(&s->gb); + } + + init_poc(h); + + if(h->pps.redundant_pic_cnt_present){ + h->redundant_pic_count= get_ue_golomb(&s->gb); + } + + //set defaults, might be overriden a few line later + h->ref_count[0]= h->pps.ref_count[0]; + h->ref_count[1]= h->pps.ref_count[1]; + + if(h->slice_type == P_TYPE || h->slice_type == SP_TYPE || h->slice_type == B_TYPE){ + if(h->slice_type == B_TYPE){ + h->direct_spatial_mv_pred= get_bits1(&s->gb); + } + num_ref_idx_active_override_flag= get_bits1(&s->gb); + + if(num_ref_idx_active_override_flag){ + h->ref_count[0]= get_ue_golomb(&s->gb) + 1; + if(h->slice_type==B_TYPE) + h->ref_count[1]= get_ue_golomb(&s->gb) + 1; + + if(h->ref_count[0] > 32 || h->ref_count[1] > 32){ + av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); + return -1; + } + } + } + + if(!default_ref_list_done){ + fill_default_ref_list(h); + } + + if(decode_ref_pic_list_reordering(h) < 0) + return -1; + + if( (h->pps.weighted_pred && (h->slice_type == P_TYPE || h->slice_type == SP_TYPE )) + || (h->pps.weighted_bipred_idc==1 && h->slice_type==B_TYPE ) ) + pred_weight_table(h); + else if(h->pps.weighted_bipred_idc==2 && h->slice_type==B_TYPE) + implicit_weight_table(h); + else + h->use_weight = 0; + + if(s->current_picture.reference) + decode_ref_pic_marking(h); + + if( h->slice_type != I_TYPE && h->slice_type != SI_TYPE && h->pps.cabac ) + h->cabac_init_idc = get_ue_golomb(&s->gb); + + h->last_qscale_diff = 0; + s->qscale = h->pps.init_qp + get_se_golomb(&s->gb); + if(s->qscale<0 || s->qscale>51){ + av_log(s->avctx, AV_LOG_ERROR, "QP %d out of range\n", s->qscale); + return -1; + } + h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, s->qscale); + //FIXME qscale / qp ... stuff + if(h->slice_type == SP_TYPE){ + get_bits1(&s->gb); /* sp_for_switch_flag */ + } + if(h->slice_type==SP_TYPE || h->slice_type == SI_TYPE){ + get_se_golomb(&s->gb); /* slice_qs_delta */ + } + + h->deblocking_filter = 1; + h->slice_alpha_c0_offset = 0; + h->slice_beta_offset = 0; + if( h->pps.deblocking_filter_parameters_present ) { + h->deblocking_filter= get_ue_golomb(&s->gb); + if(h->deblocking_filter < 2) + h->deblocking_filter^= 1; // 1<->0 + + if( h->deblocking_filter ) { + h->slice_alpha_c0_offset = get_se_golomb(&s->gb) << 1; + h->slice_beta_offset = get_se_golomb(&s->gb) << 1; + } + } + if( s->avctx->skip_loop_filter >= AVDISCARD_ALL + ||(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY && h->slice_type != I_TYPE) + ||(s->avctx->skip_loop_filter >= AVDISCARD_BIDIR && h->slice_type == B_TYPE) + ||(s->avctx->skip_loop_filter >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) + h->deblocking_filter= 0; + +#if 0 //FMO + if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5) + slice_group_change_cycle= get_bits(&s->gb, ?); +#endif + + h->slice_num++; + + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c pps:%d frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s\n", + h->slice_num, + (s->picture_structure==PICT_FRAME ? "F" : s->picture_structure==PICT_TOP_FIELD ? "T" : "B"), + first_mb_in_slice, + av_get_pict_type_char(h->slice_type), + pps_id, h->frame_num, + s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1], + h->ref_count[0], h->ref_count[1], + s->qscale, + h->deblocking_filter, h->slice_alpha_c0_offset/2, h->slice_beta_offset/2, + h->use_weight, + h->use_weight==1 && h->use_weight_chroma ? "c" : "" + ); + } + + return 0; +} + +/** + * + */ +static inline int get_level_prefix(GetBitContext *gb){ + unsigned int buf; + int log; + + OPEN_READER(re, gb); + UPDATE_CACHE(re, gb); + buf=GET_CACHE(re, gb); + + log= 32 - av_log2(buf); +#ifdef TRACE + print_bin(buf>>(32-log), log); + av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d lpr @%5d in %s get_level_prefix\n", buf>>(32-log), log, log-1, get_bits_count(gb), __FILE__); +#endif + + LAST_SKIP_BITS(re, gb, log); + CLOSE_READER(re, gb); + + return log-1; +} + +static inline int get_dct8x8_allowed(H264Context *h){ + int i; + for(i=0; i<4; i++){ + if(!IS_SUB_8X8(h->sub_mb_type[i]) + || (!h->sps.direct_8x8_inference_flag && IS_DIRECT(h->sub_mb_type[i]))) + return 0; + } + return 1; +} + +/** + * decodes a residual block. + * @param n block index + * @param scantable scantable + * @param max_coeff number of coefficients in the block + * @return <0 if an error occured + */ +static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff){ + MpegEncContext * const s = &h->s; + static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; + int level[16]; + int zeros_left, coeff_num, coeff_token, total_coeff, i, j, trailing_ones, run_before; + + //FIXME put trailing_onex into the context + + if(n == CHROMA_DC_BLOCK_INDEX){ + coeff_token= get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1); + total_coeff= coeff_token>>2; + }else{ + if(n == LUMA_DC_BLOCK_INDEX){ + total_coeff= pred_non_zero_count(h, 0); + coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2); + total_coeff= coeff_token>>2; + }else{ + total_coeff= pred_non_zero_count(h, n); + coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2); + total_coeff= coeff_token>>2; + h->non_zero_count_cache[ scan8[n] ]= total_coeff; + } + } + + //FIXME set last_non_zero? + + if(total_coeff==0) + return 0; + + trailing_ones= coeff_token&3; + tprintf("trailing:%d, total:%d\n", trailing_ones, total_coeff); + assert(total_coeff<=16); + + for(i=0; i 10 && trailing_ones < 3; + int prefix= get_level_prefix(gb); + + //first coefficient has suffix_length equal to 0 or 1 + if(prefix<14){ //FIXME try to build a large unified VLC table for all this + if(suffix_length) + level_code= (prefix<s.avctx, AV_LOG_ERROR, "prefix too large at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + if(trailing_ones < 3) level_code += 2; + + suffix_length = 1; + if(level_code > 5) + suffix_length++; + mask= -(level_code&1); + level[i]= (((2+level_code)>>1) ^ mask) - mask; + i++; + + //remaining coefficients have suffix_length > 0 + for(;is.avctx, AV_LOG_ERROR, "prefix too large at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + mask= -(level_code&1); + level[i]= (((2+level_code)>>1) ^ mask) - mask; + if(level_code > suffix_limit[suffix_length]) + suffix_length++; + } + } + + if(total_coeff == max_coeff) + zeros_left=0; + else{ + if(n == CHROMA_DC_BLOCK_INDEX) + zeros_left= get_vlc2(gb, chroma_dc_total_zeros_vlc[ total_coeff-1 ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1); + else + zeros_left= get_vlc2(gb, total_zeros_vlc[ total_coeff-1 ].table, TOTAL_ZEROS_VLC_BITS, 1); + } + + coeff_num = zeros_left + total_coeff - 1; + j = scantable[coeff_num]; + if(n > 24){ + block[j] = level[0]; + for(i=1;i>6; + for(i=1;i>6; + } + } + + if(zeros_left<0){ + av_log(h->s.avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + + return 0; +} + +/** + * decodes a P_SKIP or B_SKIP macroblock + */ +static void decode_mb_skip(H264Context *h){ + MpegEncContext * const s = &h->s; + const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; + int mb_type=0; + + memset(h->non_zero_count[mb_xy], 0, 16); + memset(h->non_zero_count_cache + 8, 0, 8*5); //FIXME ugly, remove pfui + + if(h->mb_aff_frame && s->mb_skip_run==0 && (s->mb_y&1)==0){ + h->mb_field_decoding_flag= get_bits1(&s->gb); + } + if(h->mb_field_decoding_flag) + mb_type|= MB_TYPE_INTERLACED; + + if( h->slice_type == B_TYPE ) + { + // just for fill_caches. pred_direct_motion will set the real mb_type + mb_type|= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2|MB_TYPE_SKIP; + + fill_caches(h, mb_type, 0); //FIXME check what is needed and what not ... + pred_direct_motion(h, &mb_type); + if(h->pps.cabac){ + fill_rectangle(h->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 4); + fill_rectangle(h->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 4); + } + } + else + { + int mx, my; + mb_type|= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P1L0|MB_TYPE_SKIP; + + fill_caches(h, mb_type, 0); //FIXME check what is needed and what not ... + pred_pskip_motion(h, &mx, &my); + fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1); + fill_rectangle( h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx,my), 4); + if(h->pps.cabac) + fill_rectangle(h->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 4); + } + + write_back_motion(h, mb_type); + s->current_picture.mb_type[mb_xy]= mb_type|MB_TYPE_SKIP; + s->current_picture.qscale_table[mb_xy]= s->qscale; + h->slice_table[ mb_xy ]= h->slice_num; + h->prev_mb_skipped= 1; +} + +/** + * decodes a macroblock + * @returns 0 if ok, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed + */ +static int decode_mb_cavlc(H264Context *h){ + MpegEncContext * const s = &h->s; + const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; + int mb_type, partition_count, cbp; + int dct8x8_allowed= h->pps.transform_8x8_mode; + + s->dsp.clear_blocks(h->mb); //FIXME avoid if already clear (move after skip handlong? + + tprintf("pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y); + cbp = 0; /* avoid warning. FIXME: find a solution without slowing + down the code */ + if(h->slice_type != I_TYPE && h->slice_type != SI_TYPE){ + if(s->mb_skip_run==-1) + s->mb_skip_run= get_ue_golomb(&s->gb); + + if (s->mb_skip_run--) { + decode_mb_skip(h); + return 0; + } + } + if(h->mb_aff_frame){ + if ( ((s->mb_y&1) == 0) || h->prev_mb_skipped) + h->mb_field_decoding_flag = get_bits1(&s->gb); + }else + h->mb_field_decoding_flag= (s->picture_structure!=PICT_FRAME); + + h->prev_mb_skipped= 0; + + mb_type= get_ue_golomb(&s->gb); + if(h->slice_type == B_TYPE){ + if(mb_type < 23){ + partition_count= b_mb_type_info[mb_type].partition_count; + mb_type= b_mb_type_info[mb_type].type; + }else{ + mb_type -= 23; + goto decode_intra_mb; + } + }else if(h->slice_type == P_TYPE /*|| h->slice_type == SP_TYPE */){ + if(mb_type < 5){ + partition_count= p_mb_type_info[mb_type].partition_count; + mb_type= p_mb_type_info[mb_type].type; + }else{ + mb_type -= 5; + goto decode_intra_mb; + } + }else{ + assert(h->slice_type == I_TYPE); +decode_intra_mb: + if(mb_type > 25){ + av_log(h->s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice to large at %d %d\n", mb_type, av_get_pict_type_char(h->slice_type), s->mb_x, s->mb_y); + return -1; + } + partition_count=0; + cbp= i_mb_type_info[mb_type].cbp; + h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode; + mb_type= i_mb_type_info[mb_type].type; + } + + if(h->mb_field_decoding_flag) + mb_type |= MB_TYPE_INTERLACED; + + h->slice_table[ mb_xy ]= h->slice_num; + + if(IS_INTRA_PCM(mb_type)){ + unsigned int x, y; + + // we assume these blocks are very rare so we dont optimize it + align_get_bits(&s->gb); + + // The pixels are stored in the same order as levels in h->mb array. + for(y=0; y<16; y++){ + const int index= 4*(y&3) + 32*((y>>2)&1) + 128*(y>>3); + for(x=0; x<16; x++){ + tprintf("LUMA ICPM LEVEL (%3d)\n", show_bits(&s->gb, 8)); + h->mb[index + (x&3) + 16*((x>>2)&1) + 64*(x>>3)]= get_bits(&s->gb, 8); + } + } + for(y=0; y<8; y++){ + const int index= 256 + 4*(y&3) + 32*(y>>2); + for(x=0; x<8; x++){ + tprintf("CHROMA U ICPM LEVEL (%3d)\n", show_bits(&s->gb, 8)); + h->mb[index + (x&3) + 16*(x>>2)]= get_bits(&s->gb, 8); + } + } + for(y=0; y<8; y++){ + const int index= 256 + 64 + 4*(y&3) + 32*(y>>2); + for(x=0; x<8; x++){ + tprintf("CHROMA V ICPM LEVEL (%3d)\n", show_bits(&s->gb, 8)); + h->mb[index + (x&3) + 16*(x>>2)]= get_bits(&s->gb, 8); + } + } + + // In deblocking, the quantizer is 0 + s->current_picture.qscale_table[mb_xy]= 0; + h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, 0); + // All coeffs are present + memset(h->non_zero_count[mb_xy], 16, 16); + + s->current_picture.mb_type[mb_xy]= mb_type; + return 0; + } + + fill_caches(h, mb_type, 0); + + //mb_pred + if(IS_INTRA(mb_type)){ +// init_top_left_availability(h); + if(IS_INTRA4x4(mb_type)){ + int i; + int di = 1; + if(dct8x8_allowed && get_bits1(&s->gb)){ + mb_type |= MB_TYPE_8x8DCT; + di = 4; + } + +// fill_intra4x4_pred_table(h); + for(i=0; i<16; i+=di){ + const int mode_coded= !get_bits1(&s->gb); + const int predicted_mode= pred_intra_mode(h, i); + int mode; + + if(mode_coded){ + const int rem_mode= get_bits(&s->gb, 3); + if(rem_modeintra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 ); + else + h->intra4x4_pred_mode_cache[ scan8[i] ] = mode; + } + write_back_intra_pred_mode(h); + if( check_intra4x4_pred_mode(h) < 0) + return -1; + }else{ + h->intra16x16_pred_mode= check_intra_pred_mode(h, h->intra16x16_pred_mode); + if(h->intra16x16_pred_mode < 0) + return -1; + } + h->chroma_pred_mode= get_ue_golomb(&s->gb); + + h->chroma_pred_mode= check_intra_pred_mode(h, h->chroma_pred_mode); + if(h->chroma_pred_mode < 0) + return -1; + }else if(partition_count==4){ + int i, j, sub_partition_count[4], list, ref[2][4]; + + if(h->slice_type == B_TYPE){ + for(i=0; i<4; i++){ + h->sub_mb_type[i]= get_ue_golomb(&s->gb); + if(h->sub_mb_type[i] >=13){ + av_log(h->s.avctx, AV_LOG_ERROR, "B sub_mb_type %d out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y); + return -1; + } + sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count; + h->sub_mb_type[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].type; + } + if( IS_DIRECT(h->sub_mb_type[0]) || IS_DIRECT(h->sub_mb_type[1]) + || IS_DIRECT(h->sub_mb_type[2]) || IS_DIRECT(h->sub_mb_type[3])) { + pred_direct_motion(h, &mb_type); + h->ref_cache[0][scan8[4]] = + h->ref_cache[1][scan8[4]] = + h->ref_cache[0][scan8[12]] = + h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE; + } + }else{ + assert(h->slice_type == P_TYPE || h->slice_type == SP_TYPE); //FIXME SP correct ? + for(i=0; i<4; i++){ + h->sub_mb_type[i]= get_ue_golomb(&s->gb); + if(h->sub_mb_type[i] >=4){ + av_log(h->s.avctx, AV_LOG_ERROR, "P sub_mb_type %d out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y); + return -1; + } + sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count; + h->sub_mb_type[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].type; + } + } + + for(list=0; list<2; list++){ + int ref_count= IS_REF0(mb_type) ? 1 : h->ref_count[list]; + if(ref_count == 0) continue; + if (h->mb_aff_frame && h->mb_field_decoding_flag) { + ref_count <<= 1; + } + for(i=0; i<4; i++){ + if(IS_DIRECT(h->sub_mb_type[i])) continue; + if(IS_DIR(h->sub_mb_type[i], 0, list)){ + ref[list][i] = get_te0_golomb(&s->gb, ref_count); //FIXME init to 0 before and skip? + }else{ + //FIXME + ref[list][i] = -1; + } + } + } + + if(dct8x8_allowed) + dct8x8_allowed = get_dct8x8_allowed(h); + + for(list=0; list<2; list++){ + const int ref_count= IS_REF0(mb_type) ? 1 : h->ref_count[list]; + if(ref_count == 0) continue; + + for(i=0; i<4; i++){ + if(IS_DIRECT(h->sub_mb_type[i])) { + h->ref_cache[list][ scan8[4*i] ] = h->ref_cache[list][ scan8[4*i]+1 ]; + continue; + } + h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ]= + h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i]; + + if(IS_DIR(h->sub_mb_type[i], 0, list)){ + const int sub_mb_type= h->sub_mb_type[i]; + const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1; + for(j=0; jmv_cache[list][ scan8[index] ]; + pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my); + mx += get_se_golomb(&s->gb); + my += get_se_golomb(&s->gb); + tprintf("final mv:%d %d\n", mx, my); + + if(IS_SUB_8X8(sub_mb_type)){ + mv_cache[ 0 ][0]= mv_cache[ 1 ][0]= + mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx; + mv_cache[ 0 ][1]= mv_cache[ 1 ][1]= + mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my; + }else if(IS_SUB_8X4(sub_mb_type)){ + mv_cache[ 0 ][0]= mv_cache[ 1 ][0]= mx; + mv_cache[ 0 ][1]= mv_cache[ 1 ][1]= my; + }else if(IS_SUB_4X8(sub_mb_type)){ + mv_cache[ 0 ][0]= mv_cache[ 8 ][0]= mx; + mv_cache[ 0 ][1]= mv_cache[ 8 ][1]= my; + }else{ + assert(IS_SUB_4X4(sub_mb_type)); + mv_cache[ 0 ][0]= mx; + mv_cache[ 0 ][1]= my; + } + } + }else{ + uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0]; + p[0] = p[1]= + p[8] = p[9]= 0; + } + } + } + }else if(IS_DIRECT(mb_type)){ + pred_direct_motion(h, &mb_type); + dct8x8_allowed &= h->sps.direct_8x8_inference_flag; + }else{ + int list, mx, my, i; + //FIXME we should set ref_idx_l? to 0 if we use that later ... + if(IS_16X16(mb_type)){ + for(list=0; list<2; list++){ + if(h->ref_count[list]>0){ + if(IS_DIR(mb_type, 0, list)){ + const int val= get_te0_golomb(&s->gb, h->ref_count[list]); + fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1); + }else + fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, (LIST_NOT_USED&0xFF), 1); + } + } + for(list=0; list<2; list++){ + if(IS_DIR(mb_type, 0, list)){ + pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my); + mx += get_se_golomb(&s->gb); + my += get_se_golomb(&s->gb); + tprintf("final mv:%d %d\n", mx, my); + + fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4); + }else + fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, 0, 4); + } + } + else if(IS_16X8(mb_type)){ + for(list=0; list<2; list++){ + if(h->ref_count[list]>0){ + for(i=0; i<2; i++){ + if(IS_DIR(mb_type, i, list)){ + const int val= get_te0_golomb(&s->gb, h->ref_count[list]); + fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1); + }else + fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1); + } + } + } + for(list=0; list<2; list++){ + for(i=0; i<2; i++){ + if(IS_DIR(mb_type, i, list)){ + pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my); + mx += get_se_golomb(&s->gb); + my += get_se_golomb(&s->gb); + tprintf("final mv:%d %d\n", mx, my); + + fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4); + }else + fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4); + } + } + }else{ + assert(IS_8X16(mb_type)); + for(list=0; list<2; list++){ + if(h->ref_count[list]>0){ + for(i=0; i<2; i++){ + if(IS_DIR(mb_type, i, list)){ //FIXME optimize + const int val= get_te0_golomb(&s->gb, h->ref_count[list]); + fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1); + }else + fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1); + } + } + } + for(list=0; list<2; list++){ + for(i=0; i<2; i++){ + if(IS_DIR(mb_type, i, list)){ + pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my); + mx += get_se_golomb(&s->gb); + my += get_se_golomb(&s->gb); + tprintf("final mv:%d %d\n", mx, my); + + fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4); + }else + fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4); + } + } + } + } + + if(IS_INTER(mb_type)) + write_back_motion(h, mb_type); + + if(!IS_INTRA16x16(mb_type)){ + cbp= get_ue_golomb(&s->gb); + if(cbp > 47){ + av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%d) at %d %d\n", cbp, s->mb_x, s->mb_y); + return -1; + } + + if(IS_INTRA4x4(mb_type)) + cbp= golomb_to_intra4x4_cbp[cbp]; + else + cbp= golomb_to_inter_cbp[cbp]; + } + + if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){ + if(get_bits1(&s->gb)) + mb_type |= MB_TYPE_8x8DCT; + } + s->current_picture.mb_type[mb_xy]= mb_type; + + if(cbp || IS_INTRA16x16(mb_type)){ + int i8x8, i4x4, chroma_idx; + int chroma_qp, dquant; + GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr; + const uint8_t *scan, *scan8x8, *dc_scan; + +// fill_non_zero_count_cache(h); + + if(IS_INTERLACED(mb_type)){ + scan= s->qscale ? h->field_scan : h->field_scan_q0; + dc_scan= luma_dc_field_scan; + }else{ + scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0; + dc_scan= luma_dc_zigzag_scan; + } + scan8x8= s->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0; + + dquant= get_se_golomb(&s->gb); + + if( dquant > 25 || dquant < -26 ){ + av_log(h->s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s->mb_x, s->mb_y); + return -1; + } + + s->qscale += dquant; + if(((unsigned)s->qscale) > 51){ + if(s->qscale<0) s->qscale+= 52; + else s->qscale-= 52; + } + + h->chroma_qp= chroma_qp= get_chroma_qp(h->pps.chroma_qp_index_offset, s->qscale); + if(IS_INTRA16x16(mb_type)){ + if( decode_residual(h, h->intra_gb_ptr, h->mb, LUMA_DC_BLOCK_INDEX, dc_scan, h->dequant4_coeff[0][s->qscale], 16) < 0){ + return -1; //FIXME continue if partitioned and other return -1 too + } + + assert((cbp&15) == 0 || (cbp&15) == 15); + + if(cbp&15){ + for(i8x8=0; i8x8<4; i8x8++){ + for(i4x4=0; i4x4<4; i4x4++){ + const int index= i4x4 + 4*i8x8; + if( decode_residual(h, h->intra_gb_ptr, h->mb + 16*index, index, scan + 1, h->dequant4_coeff[0][s->qscale], 15) < 0 ){ + return -1; + } + } + } + }else{ + fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1); + } + }else{ + for(i8x8=0; i8x8<4; i8x8++){ + if(cbp & (1<mb[64*i8x8]; + uint8_t *nnz; + for(i4x4=0; i4x4<4; i4x4++){ + if( decode_residual(h, gb, buf, i4x4+4*i8x8, scan8x8+16*i4x4, + h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 16) <0 ) + return -1; + } + nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ]; + nnz[0] += nnz[1] + nnz[8] + nnz[9]; + }else{ + for(i4x4=0; i4x4<4; i4x4++){ + const int index= i4x4 + 4*i8x8; + + if( decode_residual(h, gb, h->mb + 16*index, index, scan, h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale], 16) <0 ){ + return -1; + } + } + } + }else{ + uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ]; + nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0; + } + } + } + + if(cbp&0x30){ + for(chroma_idx=0; chroma_idx<2; chroma_idx++) + if( decode_residual(h, gb, h->mb + 256 + 16*4*chroma_idx, CHROMA_DC_BLOCK_INDEX, chroma_dc_scan, NULL, 4) < 0){ + return -1; + } + } + + if(cbp&0x20){ + for(chroma_idx=0; chroma_idx<2; chroma_idx++){ + for(i4x4=0; i4x4<4; i4x4++){ + const int index= 16 + 4*chroma_idx + i4x4; + if( decode_residual(h, gb, h->mb + 16*index, index, scan + 1, h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][chroma_qp], 15) < 0){ + return -1; + } + } + } + }else{ + uint8_t * const nnz= &h->non_zero_count_cache[0]; + nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] = + nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0; + } + }else{ + uint8_t * const nnz= &h->non_zero_count_cache[0]; + fill_rectangle(&nnz[scan8[0]], 4, 4, 8, 0, 1); + nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] = + nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0; + } + s->current_picture.qscale_table[mb_xy]= s->qscale; + write_back_non_zero_count(h); + + return 0; +} + +static int decode_cabac_field_decoding_flag(H264Context *h) { + MpegEncContext * const s = &h->s; + const int mb_x = s->mb_x; + const int mb_y = s->mb_y & ~1; + const int mba_xy = mb_x - 1 + mb_y *s->mb_stride; + const int mbb_xy = mb_x + (mb_y-2)*s->mb_stride; + + unsigned int ctx = 0; + + if( h->slice_table[mba_xy] == h->slice_num && IS_INTERLACED( s->current_picture.mb_type[mba_xy] ) ) { + ctx += 1; + } + if( h->slice_table[mbb_xy] == h->slice_num && IS_INTERLACED( s->current_picture.mb_type[mbb_xy] ) ) { + ctx += 1; + } + + return get_cabac( &h->cabac, &h->cabac_state[70 + ctx] ); +} + +static int decode_cabac_intra_mb_type(H264Context *h, int ctx_base, int intra_slice) { + uint8_t *state= &h->cabac_state[ctx_base]; + int mb_type; + + if(intra_slice){ + MpegEncContext * const s = &h->s; + const int mba_xy = h->left_mb_xy[0]; + const int mbb_xy = h->top_mb_xy; + int ctx=0; + if( h->slice_table[mba_xy] == h->slice_num && !IS_INTRA4x4( s->current_picture.mb_type[mba_xy] ) ) + ctx++; + if( h->slice_table[mbb_xy] == h->slice_num && !IS_INTRA4x4( s->current_picture.mb_type[mbb_xy] ) ) + ctx++; + if( get_cabac( &h->cabac, &state[ctx] ) == 0 ) + return 0; /* I4x4 */ + state += 2; + }else{ + if( get_cabac( &h->cabac, &state[0] ) == 0 ) + return 0; /* I4x4 */ + } + + if( get_cabac_terminate( &h->cabac ) ) + return 25; /* PCM */ + + mb_type = 1; /* I16x16 */ + mb_type += 12 * get_cabac( &h->cabac, &state[1] ); /* cbp_luma != 0 */ + if( get_cabac( &h->cabac, &state[2] ) ) /* cbp_chroma */ + mb_type += 4 + 4 * get_cabac( &h->cabac, &state[2+intra_slice] ); + mb_type += 2 * get_cabac( &h->cabac, &state[3+intra_slice] ); + mb_type += 1 * get_cabac( &h->cabac, &state[3+2*intra_slice] ); + return mb_type; +} + +static int decode_cabac_mb_type( H264Context *h ) { + MpegEncContext * const s = &h->s; + + if( h->slice_type == I_TYPE ) { + return decode_cabac_intra_mb_type(h, 3, 1); + } else if( h->slice_type == P_TYPE ) { + if( get_cabac( &h->cabac, &h->cabac_state[14] ) == 0 ) { + /* P-type */ + if( get_cabac( &h->cabac, &h->cabac_state[15] ) == 0 ) { + /* P_L0_D16x16, P_8x8 */ + return 3 * get_cabac( &h->cabac, &h->cabac_state[16] ); + } else { + /* P_L0_D8x16, P_L0_D16x8 */ + return 2 - get_cabac( &h->cabac, &h->cabac_state[17] ); + } + } else { + return decode_cabac_intra_mb_type(h, 17, 0) + 5; + } + } else if( h->slice_type == B_TYPE ) { + const int mba_xy = h->left_mb_xy[0]; + const int mbb_xy = h->top_mb_xy; + int ctx = 0; + int bits; + + if( h->slice_table[mba_xy] == h->slice_num && !IS_DIRECT( s->current_picture.mb_type[mba_xy] ) ) + ctx++; + if( h->slice_table[mbb_xy] == h->slice_num && !IS_DIRECT( s->current_picture.mb_type[mbb_xy] ) ) + ctx++; + + if( !get_cabac( &h->cabac, &h->cabac_state[27+ctx] ) ) + return 0; /* B_Direct_16x16 */ + + if( !get_cabac( &h->cabac, &h->cabac_state[27+3] ) ) { + return 1 + get_cabac( &h->cabac, &h->cabac_state[27+5] ); /* B_L[01]_16x16 */ + } + + bits = get_cabac( &h->cabac, &h->cabac_state[27+4] ) << 3; + bits|= get_cabac( &h->cabac, &h->cabac_state[27+5] ) << 2; + bits|= get_cabac( &h->cabac, &h->cabac_state[27+5] ) << 1; + bits|= get_cabac( &h->cabac, &h->cabac_state[27+5] ); + if( bits < 8 ) + return bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */ + else if( bits == 13 ) { + return decode_cabac_intra_mb_type(h, 32, 0) + 23; + } else if( bits == 14 ) + return 11; /* B_L1_L0_8x16 */ + else if( bits == 15 ) + return 22; /* B_8x8 */ + + bits= ( bits<<1 ) | get_cabac( &h->cabac, &h->cabac_state[27+5] ); + return bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */ + } else { + /* TODO SI/SP frames? */ + return -1; + } +} + +static int decode_cabac_mb_skip( H264Context *h) { + MpegEncContext * const s = &h->s; + const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; + const int mba_xy = mb_xy - 1; + const int mbb_xy = mb_xy - s->mb_stride; + int ctx = 0; + + if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mba_xy] )) + ctx++; + if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP( s->current_picture.mb_type[mbb_xy] )) + ctx++; + + if( h->slice_type == B_TYPE ) + ctx += 13; + return get_cabac( &h->cabac, &h->cabac_state[11+ctx] ); +} + +static int decode_cabac_mb_intra4x4_pred_mode( H264Context *h, int pred_mode ) { + int mode = 0; + + if( get_cabac( &h->cabac, &h->cabac_state[68] ) ) + return pred_mode; + + mode += 1 * get_cabac( &h->cabac, &h->cabac_state[69] ); + mode += 2 * get_cabac( &h->cabac, &h->cabac_state[69] ); + mode += 4 * get_cabac( &h->cabac, &h->cabac_state[69] ); + + if( mode >= pred_mode ) + return mode + 1; + else + return mode; +} + +static int decode_cabac_mb_chroma_pre_mode( H264Context *h) { + const int mba_xy = h->left_mb_xy[0]; + const int mbb_xy = h->top_mb_xy; + + int ctx = 0; + + /* No need to test for IS_INTRA4x4 and IS_INTRA16x16, as we set chroma_pred_mode_table to 0 */ + if( h->slice_table[mba_xy] == h->slice_num && h->chroma_pred_mode_table[mba_xy] != 0 ) + ctx++; + + if( h->slice_table[mbb_xy] == h->slice_num && h->chroma_pred_mode_table[mbb_xy] != 0 ) + ctx++; + + if( get_cabac( &h->cabac, &h->cabac_state[64+ctx] ) == 0 ) + return 0; + + if( get_cabac( &h->cabac, &h->cabac_state[64+3] ) == 0 ) + return 1; + if( get_cabac( &h->cabac, &h->cabac_state[64+3] ) == 0 ) + return 2; + else + return 3; +} + +static const uint8_t block_idx_x[16] = { + 0, 1, 0, 1, 2, 3, 2, 3, 0, 1, 0, 1, 2, 3, 2, 3 +}; +static const uint8_t block_idx_y[16] = { + 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 +}; +static const uint8_t block_idx_xy[4][4] = { + { 0, 2, 8, 10}, + { 1, 3, 9, 11}, + { 4, 6, 12, 14}, + { 5, 7, 13, 15} +}; + +static int decode_cabac_mb_cbp_luma( H264Context *h) { + int cbp = 0; + int cbp_b = -1; + int i8x8; + + if( h->slice_table[h->top_mb_xy] == h->slice_num ) { + cbp_b = h->top_cbp; + tprintf("cbp_b = top_cbp = %x\n", cbp_b); + } + + for( i8x8 = 0; i8x8 < 4; i8x8++ ) { + int cbp_a = -1; + int x, y; + int ctx = 0; + + x = block_idx_x[4*i8x8]; + y = block_idx_y[4*i8x8]; + + if( x > 0 ) + cbp_a = cbp; + else if( h->slice_table[h->left_mb_xy[0]] == h->slice_num ) { + cbp_a = h->left_cbp; + tprintf("cbp_a = left_cbp = %x\n", cbp_a); + } + + if( y > 0 ) + cbp_b = cbp; + + /* No need to test for skip as we put 0 for skip block */ + /* No need to test for IPCM as we put 1 for IPCM block */ + if( cbp_a >= 0 ) { + int i8x8a = block_idx_xy[(x-1)&0x03][y]/4; + if( ((cbp_a >> i8x8a)&0x01) == 0 ) + ctx++; + } + + if( cbp_b >= 0 ) { + int i8x8b = block_idx_xy[x][(y-1)&0x03]/4; + if( ((cbp_b >> i8x8b)&0x01) == 0 ) + ctx += 2; + } + + if( get_cabac( &h->cabac, &h->cabac_state[73 + ctx] ) ) { + cbp |= 1 << i8x8; + } + } + return cbp; +} +static int decode_cabac_mb_cbp_chroma( H264Context *h) { + int ctx; + int cbp_a, cbp_b; + + cbp_a = (h->left_cbp>>4)&0x03; + cbp_b = (h-> top_cbp>>4)&0x03; + + ctx = 0; + if( cbp_a > 0 ) ctx++; + if( cbp_b > 0 ) ctx += 2; + if( get_cabac( &h->cabac, &h->cabac_state[77 + ctx] ) == 0 ) + return 0; + + ctx = 4; + if( cbp_a == 2 ) ctx++; + if( cbp_b == 2 ) ctx += 2; + return 1 + get_cabac( &h->cabac, &h->cabac_state[77 + ctx] ); +} +static int decode_cabac_mb_dqp( H264Context *h) { + MpegEncContext * const s = &h->s; + int mbn_xy; + int ctx = 0; + int val = 0; + + if( s->mb_x > 0 ) + mbn_xy = s->mb_x + s->mb_y*s->mb_stride - 1; + else + mbn_xy = s->mb_width - 1 + (s->mb_y-1)*s->mb_stride; + + if( h->last_qscale_diff != 0 && ( IS_INTRA16x16(s->current_picture.mb_type[mbn_xy] ) || (h->cbp_table[mbn_xy]&0x3f) ) ) + ctx++; + + while( get_cabac( &h->cabac, &h->cabac_state[60 + ctx] ) ) { + if( ctx < 2 ) + ctx = 2; + else + ctx = 3; + val++; + if(val > 102) //prevent infinite loop + return INT_MIN; + } + + if( val&0x01 ) + return (val + 1)/2; + else + return -(val + 1)/2; +} +static int decode_cabac_p_mb_sub_type( H264Context *h ) { + if( get_cabac( &h->cabac, &h->cabac_state[21] ) ) + return 0; /* 8x8 */ + if( !get_cabac( &h->cabac, &h->cabac_state[22] ) ) + return 1; /* 8x4 */ + if( get_cabac( &h->cabac, &h->cabac_state[23] ) ) + return 2; /* 4x8 */ + return 3; /* 4x4 */ +} +static int decode_cabac_b_mb_sub_type( H264Context *h ) { + int type; + if( !get_cabac( &h->cabac, &h->cabac_state[36] ) ) + return 0; /* B_Direct_8x8 */ + if( !get_cabac( &h->cabac, &h->cabac_state[37] ) ) + return 1 + get_cabac( &h->cabac, &h->cabac_state[39] ); /* B_L0_8x8, B_L1_8x8 */ + type = 3; + if( get_cabac( &h->cabac, &h->cabac_state[38] ) ) { + if( get_cabac( &h->cabac, &h->cabac_state[39] ) ) + return 11 + get_cabac( &h->cabac, &h->cabac_state[39] ); /* B_L1_4x4, B_Bi_4x4 */ + type += 4; + } + type += 2*get_cabac( &h->cabac, &h->cabac_state[39] ); + type += get_cabac( &h->cabac, &h->cabac_state[39] ); + return type; +} + +static inline int decode_cabac_mb_transform_size( H264Context *h ) { + return get_cabac( &h->cabac, &h->cabac_state[399 + h->neighbor_transform_size] ); +} + +static int decode_cabac_mb_ref( H264Context *h, int list, int n ) { + int refa = h->ref_cache[list][scan8[n] - 1]; + int refb = h->ref_cache[list][scan8[n] - 8]; + int ref = 0; + int ctx = 0; + + if( h->slice_type == B_TYPE) { + if( refa > 0 && !h->direct_cache[scan8[n] - 1] ) + ctx++; + if( refb > 0 && !h->direct_cache[scan8[n] - 8] ) + ctx += 2; + } else { + if( refa > 0 ) + ctx++; + if( refb > 0 ) + ctx += 2; + } + + while( get_cabac( &h->cabac, &h->cabac_state[54+ctx] ) ) { + ref++; + if( ctx < 4 ) + ctx = 4; + else + ctx = 5; + } + return ref; +} + +static int decode_cabac_mb_mvd( H264Context *h, int list, int n, int l ) { + int amvd = abs( h->mvd_cache[list][scan8[n] - 1][l] ) + + abs( h->mvd_cache[list][scan8[n] - 8][l] ); + int ctxbase = (l == 0) ? 40 : 47; + int ctx, mvd; + + if( amvd < 3 ) + ctx = 0; + else if( amvd > 32 ) + ctx = 2; + else + ctx = 1; + + if(!get_cabac(&h->cabac, &h->cabac_state[ctxbase+ctx])) + return 0; + + mvd= 1; + ctx= 3; + while( mvd < 9 && get_cabac( &h->cabac, &h->cabac_state[ctxbase+ctx] ) ) { + mvd++; + if( ctx < 6 ) + ctx++; + } + + if( mvd >= 9 ) { + int k = 3; + while( get_cabac_bypass( &h->cabac ) ) { + mvd += 1 << k; + k++; + } + while( k-- ) { + if( get_cabac_bypass( &h->cabac ) ) + mvd += 1 << k; + } + } + if( get_cabac_bypass( &h->cabac ) ) return -mvd; + else return mvd; +} + +static int inline get_cabac_cbf_ctx( H264Context *h, int cat, int idx ) { + int nza, nzb; + int ctx = 0; + + if( cat == 0 ) { + nza = h->left_cbp&0x100; + nzb = h-> top_cbp&0x100; + } else if( cat == 1 || cat == 2 ) { + nza = h->non_zero_count_cache[scan8[idx] - 1]; + nzb = h->non_zero_count_cache[scan8[idx] - 8]; + } else if( cat == 3 ) { + nza = (h->left_cbp>>(6+idx))&0x01; + nzb = (h-> top_cbp>>(6+idx))&0x01; + } else { + assert(cat == 4); + nza = h->non_zero_count_cache[scan8[16+idx] - 1]; + nzb = h->non_zero_count_cache[scan8[16+idx] - 8]; + } + + if( nza > 0 ) + ctx++; + + if( nzb > 0 ) + ctx += 2; + + return ctx + 4 * cat; +} + +static int decode_cabac_residual( H264Context *h, DCTELEM *block, int cat, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff) { + const int mb_xy = h->s.mb_x + h->s.mb_y*h->s.mb_stride; + static const int significant_coeff_flag_field_offset[2] = { 105, 277 }; + static const int last_significant_coeff_flag_field_offset[2] = { 166, 338 }; + static const int significant_coeff_flag_offset[6] = { 0, 15, 29, 44, 47, 297 }; + static const int last_significant_coeff_flag_offset[6] = { 0, 15, 29, 44, 47, 251 }; + static const int coeff_abs_level_m1_offset[6] = { 227+0, 227+10, 227+20, 227+30, 227+39, 426 }; + static const int significant_coeff_flag_offset_8x8[63] = { + 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5, + 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9,10, 9, 8, 7, + 7, 6,11,12,13,11, 6, 7, 8, 9,14,10, 9, 8, 6,11, + 12,13,11, 6, 9,14,10, 9,11,12,13,11,14,10,12 + }; + static const int last_coeff_flag_offset_8x8[63] = { + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8 + }; + + int index[64]; + + int i, last; + int coeff_count = 0; + + int abslevel1 = 1; + int abslevelgt1 = 0; + + uint8_t *significant_coeff_ctx_base; + uint8_t *last_coeff_ctx_base; + uint8_t *abs_level_m1_ctx_base; + + /* cat: 0-> DC 16x16 n = 0 + * 1-> AC 16x16 n = luma4x4idx + * 2-> Luma4x4 n = luma4x4idx + * 3-> DC Chroma n = iCbCr + * 4-> AC Chroma n = 4 * iCbCr + chroma4x4idx + * 5-> Luma8x8 n = 4 * luma8x8idx + */ + + /* read coded block flag */ + if( cat != 5 ) { + if( get_cabac( &h->cabac, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n ) ] ) == 0 ) { + if( cat == 1 || cat == 2 ) + h->non_zero_count_cache[scan8[n]] = 0; + else if( cat == 4 ) + h->non_zero_count_cache[scan8[16+n]] = 0; + + return 0; + } + } + + significant_coeff_ctx_base = h->cabac_state + + significant_coeff_flag_offset[cat] + + significant_coeff_flag_field_offset[h->mb_field_decoding_flag]; + last_coeff_ctx_base = h->cabac_state + + last_significant_coeff_flag_offset[cat] + + last_significant_coeff_flag_field_offset[h->mb_field_decoding_flag]; + abs_level_m1_ctx_base = h->cabac_state + + coeff_abs_level_m1_offset[cat]; + + if( cat == 5 ) { +#define DECODE_SIGNIFICANCE( coefs, sig_off, last_off ) \ + for(last= 0; last < coefs; last++) { \ + uint8_t *sig_ctx = significant_coeff_ctx_base + sig_off; \ + if( get_cabac( &h->cabac, sig_ctx )) { \ + uint8_t *last_ctx = last_coeff_ctx_base + last_off; \ + index[coeff_count++] = last; \ + if( get_cabac( &h->cabac, last_ctx ) ) { \ + last= max_coeff; \ + break; \ + } \ + } \ + } + DECODE_SIGNIFICANCE( 63, significant_coeff_flag_offset_8x8[last], + last_coeff_flag_offset_8x8[last] ); + } else { + DECODE_SIGNIFICANCE( max_coeff - 1, last, last ); + } + if( last == max_coeff -1 ) { + index[coeff_count++] = last; + } + assert(coeff_count > 0); + + if( cat == 0 ) + h->cbp_table[mb_xy] |= 0x100; + else if( cat == 1 || cat == 2 ) + h->non_zero_count_cache[scan8[n]] = coeff_count; + else if( cat == 3 ) + h->cbp_table[mb_xy] |= 0x40 << n; + else if( cat == 4 ) + h->non_zero_count_cache[scan8[16+n]] = coeff_count; + else { + assert( cat == 5 ); + fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1); + } + + for( i = coeff_count - 1; i >= 0; i-- ) { + uint8_t *ctx = (abslevelgt1 != 0 ? 0 : FFMIN( 4, abslevel1 )) + abs_level_m1_ctx_base; + int j= scantable[index[i]]; + + if( get_cabac( &h->cabac, ctx ) == 0 ) { + if( !qmul ) { + if( get_cabac_bypass( &h->cabac ) ) block[j] = -1; + else block[j] = 1; + }else{ + if( get_cabac_bypass( &h->cabac ) ) block[j] = (-qmul[j] + 32) >> 6; + else block[j] = ( qmul[j] + 32) >> 6; + } + + abslevel1++; + } else { + int coeff_abs = 2; + ctx = 5 + FFMIN( 4, abslevelgt1 ) + abs_level_m1_ctx_base; + while( coeff_abs < 15 && get_cabac( &h->cabac, ctx ) ) { + coeff_abs++; + } + + if( coeff_abs >= 15 ) { + int j = 0; + while( get_cabac_bypass( &h->cabac ) ) { + coeff_abs += 1 << j; + j++; + } + + while( j-- ) { + if( get_cabac_bypass( &h->cabac ) ) + coeff_abs += 1 << j ; + } + } + + if( !qmul ) { + if( get_cabac_bypass( &h->cabac ) ) block[j] = -coeff_abs; + else block[j] = coeff_abs; + }else{ + if( get_cabac_bypass( &h->cabac ) ) block[j] = (-coeff_abs * qmul[j] + 32) >> 6; + else block[j] = ( coeff_abs * qmul[j] + 32) >> 6; + } + + abslevelgt1++; + } + } + return 0; +} + +static void inline compute_mb_neighbors(H264Context *h) +{ + MpegEncContext * const s = &h->s; + const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; + h->top_mb_xy = mb_xy - s->mb_stride; + h->left_mb_xy[0] = mb_xy - 1; + if(h->mb_aff_frame){ + const int pair_xy = s->mb_x + (s->mb_y & ~1)*s->mb_stride; + const int top_pair_xy = pair_xy - s->mb_stride; + const int top_mb_frame_flag = !IS_INTERLACED(s->current_picture.mb_type[top_pair_xy]); + const int left_mb_frame_flag = !IS_INTERLACED(s->current_picture.mb_type[pair_xy-1]); + const int curr_mb_frame_flag = !h->mb_field_decoding_flag; + const int bottom = (s->mb_y & 1); + if (bottom + ? !curr_mb_frame_flag // bottom macroblock + : (!curr_mb_frame_flag && !top_mb_frame_flag) // top macroblock + ) { + h->top_mb_xy -= s->mb_stride; + } + if (left_mb_frame_flag != curr_mb_frame_flag) { + h->left_mb_xy[0] = pair_xy - 1; + } + } + return; +} + +/** + * decodes a macroblock + * @returns 0 if ok, AC_ERROR / DC_ERROR / MV_ERROR if an error is noticed + */ +static int decode_mb_cabac(H264Context *h) { + MpegEncContext * const s = &h->s; + const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; + int mb_type, partition_count, cbp = 0; + int dct8x8_allowed= h->pps.transform_8x8_mode; + + s->dsp.clear_blocks(h->mb); //FIXME avoid if already clear (move after skip handlong?) + + tprintf("pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y); + if( h->slice_type != I_TYPE && h->slice_type != SI_TYPE ) { + /* read skip flags */ + if( decode_cabac_mb_skip( h ) ) { + decode_mb_skip(h); + + h->cbp_table[mb_xy] = 0; + h->chroma_pred_mode_table[mb_xy] = 0; + h->last_qscale_diff = 0; + + return 0; + + } + } + if(h->mb_aff_frame){ + if ( ((s->mb_y&1) == 0) || h->prev_mb_skipped) + h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h); + }else + h->mb_field_decoding_flag= (s->picture_structure!=PICT_FRAME); + + h->prev_mb_skipped = 0; + + compute_mb_neighbors(h); + if( ( mb_type = decode_cabac_mb_type( h ) ) < 0 ) { + av_log( h->s.avctx, AV_LOG_ERROR, "decode_cabac_mb_type failed\n" ); + return -1; + } + + if( h->slice_type == B_TYPE ) { + if( mb_type < 23 ){ + partition_count= b_mb_type_info[mb_type].partition_count; + mb_type= b_mb_type_info[mb_type].type; + }else{ + mb_type -= 23; + goto decode_intra_mb; + } + } else if( h->slice_type == P_TYPE ) { + if( mb_type < 5) { + partition_count= p_mb_type_info[mb_type].partition_count; + mb_type= p_mb_type_info[mb_type].type; + } else { + mb_type -= 5; + goto decode_intra_mb; + } + } else { + assert(h->slice_type == I_TYPE); +decode_intra_mb: + partition_count = 0; + cbp= i_mb_type_info[mb_type].cbp; + h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode; + mb_type= i_mb_type_info[mb_type].type; + } + if(h->mb_field_decoding_flag) + mb_type |= MB_TYPE_INTERLACED; + + h->slice_table[ mb_xy ]= h->slice_num; + + if(IS_INTRA_PCM(mb_type)) { + const uint8_t *ptr; + unsigned int x, y; + + // We assume these blocks are very rare so we dont optimize it. + // FIXME The two following lines get the bitstream position in the cabac + // decode, I think it should be done by a function in cabac.h (or cabac.c). + ptr= h->cabac.bytestream; + if (h->cabac.low&0x1) ptr-=CABAC_BITS/8; + + // The pixels are stored in the same order as levels in h->mb array. + for(y=0; y<16; y++){ + const int index= 4*(y&3) + 32*((y>>2)&1) + 128*(y>>3); + for(x=0; x<16; x++){ + tprintf("LUMA ICPM LEVEL (%3d)\n", *ptr); + h->mb[index + (x&3) + 16*((x>>2)&1) + 64*(x>>3)]= *ptr++; + } + } + for(y=0; y<8; y++){ + const int index= 256 + 4*(y&3) + 32*(y>>2); + for(x=0; x<8; x++){ + tprintf("CHROMA U ICPM LEVEL (%3d)\n", *ptr); + h->mb[index + (x&3) + 16*(x>>2)]= *ptr++; + } + } + for(y=0; y<8; y++){ + const int index= 256 + 64 + 4*(y&3) + 32*(y>>2); + for(x=0; x<8; x++){ + tprintf("CHROMA V ICPM LEVEL (%3d)\n", *ptr); + h->mb[index + (x&3) + 16*(x>>2)]= *ptr++; + } + } + + ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr); + + // All blocks are present + h->cbp_table[mb_xy] = 0x1ef; + h->chroma_pred_mode_table[mb_xy] = 0; + // In deblocking, the quantizer is 0 + s->current_picture.qscale_table[mb_xy]= 0; + h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, 0); + // All coeffs are present + memset(h->non_zero_count[mb_xy], 16, 16); + s->current_picture.mb_type[mb_xy]= mb_type; + return 0; + } + + fill_caches(h, mb_type, 0); + + if( IS_INTRA( mb_type ) ) { + int i; + if( IS_INTRA4x4( mb_type ) ) { + if( dct8x8_allowed && decode_cabac_mb_transform_size( h ) ) { + mb_type |= MB_TYPE_8x8DCT; + for( i = 0; i < 16; i+=4 ) { + int pred = pred_intra_mode( h, i ); + int mode = decode_cabac_mb_intra4x4_pred_mode( h, pred ); + fill_rectangle( &h->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 ); + } + } else { + for( i = 0; i < 16; i++ ) { + int pred = pred_intra_mode( h, i ); + h->intra4x4_pred_mode_cache[ scan8[i] ] = decode_cabac_mb_intra4x4_pred_mode( h, pred ); + + //av_log( s->avctx, AV_LOG_ERROR, "i4x4 pred=%d mode=%d\n", pred, h->intra4x4_pred_mode_cache[ scan8[i] ] ); + } + } + write_back_intra_pred_mode(h); + if( check_intra4x4_pred_mode(h) < 0 ) return -1; + } else { + h->intra16x16_pred_mode= check_intra_pred_mode( h, h->intra16x16_pred_mode ); + if( h->intra16x16_pred_mode < 0 ) return -1; + } + h->chroma_pred_mode_table[mb_xy] = + h->chroma_pred_mode = decode_cabac_mb_chroma_pre_mode( h ); + + h->chroma_pred_mode= check_intra_pred_mode( h, h->chroma_pred_mode ); + if( h->chroma_pred_mode < 0 ) return -1; + } else if( partition_count == 4 ) { + int i, j, sub_partition_count[4], list, ref[2][4]; + + if( h->slice_type == B_TYPE ) { + for( i = 0; i < 4; i++ ) { + h->sub_mb_type[i] = decode_cabac_b_mb_sub_type( h ); + sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count; + h->sub_mb_type[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].type; + } + if( IS_DIRECT(h->sub_mb_type[0]) || IS_DIRECT(h->sub_mb_type[1]) + || IS_DIRECT(h->sub_mb_type[2]) || IS_DIRECT(h->sub_mb_type[3])) { + pred_direct_motion(h, &mb_type); + if( h->ref_count[0] > 1 || h->ref_count[1] > 1 ) { + for( i = 0; i < 4; i++ ) + if( IS_DIRECT(h->sub_mb_type[i]) ) + fill_rectangle( &h->direct_cache[scan8[4*i]], 2, 2, 8, 1, 1 ); + } + } + } else { + for( i = 0; i < 4; i++ ) { + h->sub_mb_type[i] = decode_cabac_p_mb_sub_type( h ); + sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count; + h->sub_mb_type[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].type; + } + } + + for( list = 0; list < 2; list++ ) { + if( h->ref_count[list] > 0 ) { + for( i = 0; i < 4; i++ ) { + if(IS_DIRECT(h->sub_mb_type[i])) continue; + if(IS_DIR(h->sub_mb_type[i], 0, list)){ + if( h->ref_count[list] > 1 ) + ref[list][i] = decode_cabac_mb_ref( h, list, 4*i ); + else + ref[list][i] = 0; + } else { + ref[list][i] = -1; + } + h->ref_cache[list][ scan8[4*i]+1 ]= + h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i]; + } + } + } + + if(dct8x8_allowed) + dct8x8_allowed = get_dct8x8_allowed(h); + + for(list=0; list<2; list++){ + for(i=0; i<4; i++){ + if(IS_DIRECT(h->sub_mb_type[i])){ + fill_rectangle(h->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 4); + continue; + } + h->ref_cache[list][ scan8[4*i] ]=h->ref_cache[list][ scan8[4*i]+1 ]; + + if(IS_DIR(h->sub_mb_type[i], 0, list) && !IS_DIRECT(h->sub_mb_type[i])){ + const int sub_mb_type= h->sub_mb_type[i]; + const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1; + for(j=0; jmv_cache[list][ scan8[index] ]; + int16_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ]; + pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mpx, &mpy); + + mx = mpx + decode_cabac_mb_mvd( h, list, index, 0 ); + my = mpy + decode_cabac_mb_mvd( h, list, index, 1 ); + tprintf("final mv:%d %d\n", mx, my); + + if(IS_SUB_8X8(sub_mb_type)){ + mv_cache[ 0 ][0]= mv_cache[ 1 ][0]= + mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx; + mv_cache[ 0 ][1]= mv_cache[ 1 ][1]= + mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my; + + mvd_cache[ 0 ][0]= mvd_cache[ 1 ][0]= + mvd_cache[ 8 ][0]= mvd_cache[ 9 ][0]= mx - mpx; + mvd_cache[ 0 ][1]= mvd_cache[ 1 ][1]= + mvd_cache[ 8 ][1]= mvd_cache[ 9 ][1]= my - mpy; + }else if(IS_SUB_8X4(sub_mb_type)){ + mv_cache[ 0 ][0]= mv_cache[ 1 ][0]= mx; + mv_cache[ 0 ][1]= mv_cache[ 1 ][1]= my; + + mvd_cache[ 0 ][0]= mvd_cache[ 1 ][0]= mx- mpx; + mvd_cache[ 0 ][1]= mvd_cache[ 1 ][1]= my - mpy; + }else if(IS_SUB_4X8(sub_mb_type)){ + mv_cache[ 0 ][0]= mv_cache[ 8 ][0]= mx; + mv_cache[ 0 ][1]= mv_cache[ 8 ][1]= my; + + mvd_cache[ 0 ][0]= mvd_cache[ 8 ][0]= mx - mpx; + mvd_cache[ 0 ][1]= mvd_cache[ 8 ][1]= my - mpy; + }else{ + assert(IS_SUB_4X4(sub_mb_type)); + mv_cache[ 0 ][0]= mx; + mv_cache[ 0 ][1]= my; + + mvd_cache[ 0 ][0]= mx - mpx; + mvd_cache[ 0 ][1]= my - mpy; + } + } + }else{ + uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0]; + uint32_t *pd= (uint32_t *)&h->mvd_cache[list][ scan8[4*i] ][0]; + p[0] = p[1] = p[8] = p[9] = 0; + pd[0]= pd[1]= pd[8]= pd[9]= 0; + } + } + } + } else if( IS_DIRECT(mb_type) ) { + pred_direct_motion(h, &mb_type); + fill_rectangle(h->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 4); + fill_rectangle(h->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 4); + dct8x8_allowed &= h->sps.direct_8x8_inference_flag; + } else { + int list, mx, my, i, mpx, mpy; + if(IS_16X16(mb_type)){ + for(list=0; list<2; list++){ + if(IS_DIR(mb_type, 0, list)){ + if(h->ref_count[list] > 0 ){ + const int ref = h->ref_count[list] > 1 ? decode_cabac_mb_ref( h, list, 0 ) : 0; + fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1); + } + }else + fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, (uint8_t)LIST_NOT_USED, 1); + } + for(list=0; list<2; list++){ + if(IS_DIR(mb_type, 0, list)){ + pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mpx, &mpy); + + mx = mpx + decode_cabac_mb_mvd( h, list, 0, 0 ); + my = mpy + decode_cabac_mb_mvd( h, list, 0, 1 ); + tprintf("final mv:%d %d\n", mx, my); + + fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx-mpx,my-mpy), 4); + fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4); + }else + fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, 0, 4); + } + } + else if(IS_16X8(mb_type)){ + for(list=0; list<2; list++){ + if(h->ref_count[list]>0){ + for(i=0; i<2; i++){ + if(IS_DIR(mb_type, i, list)){ + const int ref= h->ref_count[list] > 1 ? decode_cabac_mb_ref( h, list, 8*i ) : 0; + fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, ref, 1); + }else + fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1); + } + } + } + for(list=0; list<2; list++){ + for(i=0; i<2; i++){ + if(IS_DIR(mb_type, i, list)){ + pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mpx, &mpy); + mx = mpx + decode_cabac_mb_mvd( h, list, 8*i, 0 ); + my = mpy + decode_cabac_mb_mvd( h, list, 8*i, 1 ); + tprintf("final mv:%d %d\n", mx, my); + + fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx-mpx,my-mpy), 4); + fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4); + }else{ + fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4); + fill_rectangle(h-> mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4); + } + } + } + }else{ + assert(IS_8X16(mb_type)); + for(list=0; list<2; list++){ + if(h->ref_count[list]>0){ + for(i=0; i<2; i++){ + if(IS_DIR(mb_type, i, list)){ //FIXME optimize + const int ref= h->ref_count[list] > 1 ? decode_cabac_mb_ref( h, list, 4*i ) : 0; + fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, ref, 1); + }else + fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1); + } + } + } + for(list=0; list<2; list++){ + for(i=0; i<2; i++){ + if(IS_DIR(mb_type, i, list)){ + pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mpx, &mpy); + mx = mpx + decode_cabac_mb_mvd( h, list, 4*i, 0 ); + my = mpy + decode_cabac_mb_mvd( h, list, 4*i, 1 ); + + tprintf("final mv:%d %d\n", mx, my); + fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx-mpx,my-mpy), 4); + fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4); + }else{ + fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4); + fill_rectangle(h-> mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4); + } + } + } + } + } + + if( IS_INTER( mb_type ) ) { + h->chroma_pred_mode_table[mb_xy] = 0; + write_back_motion( h, mb_type ); + } + + if( !IS_INTRA16x16( mb_type ) ) { + cbp = decode_cabac_mb_cbp_luma( h ); + cbp |= decode_cabac_mb_cbp_chroma( h ) << 4; + } + + h->cbp_table[mb_xy] = cbp; + + if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) { + if( decode_cabac_mb_transform_size( h ) ) + mb_type |= MB_TYPE_8x8DCT; + } + s->current_picture.mb_type[mb_xy]= mb_type; + + if( cbp || IS_INTRA16x16( mb_type ) ) { + const uint8_t *scan, *scan8x8, *dc_scan; + int dqp; + + if(IS_INTERLACED(mb_type)){ + scan= s->qscale ? h->field_scan : h->field_scan_q0; + dc_scan= luma_dc_field_scan; + }else{ + scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0; + dc_scan= luma_dc_zigzag_scan; + } + scan8x8= s->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0; + + h->last_qscale_diff = dqp = decode_cabac_mb_dqp( h ); + if( dqp == INT_MIN ){ + av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y); + return -1; + } + s->qscale += dqp; + if(((unsigned)s->qscale) > 51){ + if(s->qscale<0) s->qscale+= 52; + else s->qscale-= 52; + } + h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, s->qscale); + + if( IS_INTRA16x16( mb_type ) ) { + int i; + //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 DC\n" ); + if( decode_cabac_residual( h, h->mb, 0, 0, dc_scan, NULL, 16) < 0) + return -1; + if( cbp&15 ) { + for( i = 0; i < 16; i++ ) { + //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 AC:%d\n", i ); + if( decode_cabac_residual(h, h->mb + 16*i, 1, i, scan + 1, h->dequant4_coeff[0][s->qscale], 15) < 0 ) + return -1; + } + } else { + fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1); + } + } else { + int i8x8, i4x4; + for( i8x8 = 0; i8x8 < 4; i8x8++ ) { + if( cbp & (1<mb + 64*i8x8, 5, 4*i8x8, + scan8x8, h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 64) < 0 ) + return -1; + } else + for( i4x4 = 0; i4x4 < 4; i4x4++ ) { + const int index = 4*i8x8 + i4x4; + //av_log( s->avctx, AV_LOG_ERROR, "Luma4x4: %d\n", index ); + if( decode_cabac_residual(h, h->mb + 16*index, 2, index, scan, h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale], 16) < 0 ) + return -1; + } + } else { + uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ]; + nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0; + } + } + } + + if( cbp&0x30 ){ + int c; + for( c = 0; c < 2; c++ ) { + //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c ); + if( decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, NULL, 4) < 0) + return -1; + } + } + + if( cbp&0x20 ) { + int c, i; + for( c = 0; c < 2; c++ ) { + for( i = 0; i < 4; i++ ) { + const int index = 16 + 4 * c + i; + //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-AC %d\n",c, index - 16 ); + if( decode_cabac_residual(h, h->mb + 16*index, 4, index - 16, scan + 1, h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp], 15) < 0) + return -1; + } + } + } else { + uint8_t * const nnz= &h->non_zero_count_cache[0]; + nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] = + nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0; + } + } else { + uint8_t * const nnz= &h->non_zero_count_cache[0]; + fill_rectangle(&nnz[scan8[0]], 4, 4, 8, 0, 1); + nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] = + nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0; + } + + s->current_picture.qscale_table[mb_xy]= s->qscale; + write_back_non_zero_count(h); + + return 0; +} + + +static void filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) { + int i, d; + const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 ); + const int alpha = alpha_table[index_a]; + const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; + + if( bS[0] < 4 ) { + int8_t tc[4]; + for(i=0; i<4; i++) + tc[i] = bS[i] ? tc0_table[index_a][bS[i] - 1] : -1; + h->s.dsp.h264_h_loop_filter_luma(pix, stride, alpha, beta, tc); + } else { + /* 16px edge length, because bS=4 is triggered by being at + * the edge of an intra MB, so all 4 bS are the same */ + for( d = 0; d < 16; d++ ) { + const int p0 = pix[-1]; + const int p1 = pix[-2]; + const int p2 = pix[-3]; + + const int q0 = pix[0]; + const int q1 = pix[1]; + const int q2 = pix[2]; + + if( ABS( p0 - q0 ) < alpha && + ABS( p1 - p0 ) < beta && + ABS( q1 - q0 ) < beta ) { + + if(ABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){ + if( ABS( p2 - p0 ) < beta) + { + const int p3 = pix[-4]; + /* p0', p1', p2' */ + pix[-1] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; + pix[-2] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; + pix[-3] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; + } else { + /* p0' */ + pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; + } + if( ABS( q2 - q0 ) < beta) + { + const int q3 = pix[3]; + /* q0', q1', q2' */ + pix[0] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3; + pix[1] = ( p0 + q0 + q1 + q2 + 2 ) >> 2; + pix[2] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3; + } else { + /* q0' */ + pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; + } + }else{ + /* p0', q0' */ + pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; + pix[ 0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; + } + tprintf("filter_mb_edgev i:%d d:%d\n# bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, d, p2, p1, p0, q0, q1, q2, pix[-2], pix[-1], pix[0], pix[1]); + } + pix += stride; + } + } +} +static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) { + int i; + const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 ); + const int alpha = alpha_table[index_a]; + const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; + + if( bS[0] < 4 ) { + int8_t tc[4]; + for(i=0; i<4; i++) + tc[i] = bS[i] ? tc0_table[index_a][bS[i] - 1] + 1 : 0; + h->s.dsp.h264_h_loop_filter_chroma(pix, stride, alpha, beta, tc); + } else { + h->s.dsp.h264_h_loop_filter_chroma_intra(pix, stride, alpha, beta); + } +} + +static void filter_mb_mbaff_edgev( H264Context *h, uint8_t *pix, int stride, int bS[8], int qp[2] ) { + int i; + for( i = 0; i < 16; i++, pix += stride) { + int index_a; + int alpha; + int beta; + + int qp_index; + int bS_index = (i >> 1); + if (h->mb_field_decoding_flag) { + bS_index &= ~1; + bS_index |= (i & 1); + } + + if( bS[bS_index] == 0 ) { + continue; + } + + qp_index = h->mb_field_decoding_flag ? (i & 1) : (i >> 3); + index_a = clip( qp[qp_index] + h->slice_alpha_c0_offset, 0, 51 ); + alpha = alpha_table[index_a]; + beta = beta_table[clip( qp[qp_index] + h->slice_beta_offset, 0, 51 )]; + + + if( bS[bS_index] < 4 ) { + const int tc0 = tc0_table[index_a][bS[bS_index] - 1]; + /* 4px edge length */ + const int p0 = pix[-1]; + const int p1 = pix[-2]; + const int p2 = pix[-3]; + const int q0 = pix[0]; + const int q1 = pix[1]; + const int q2 = pix[2]; + + if( ABS( p0 - q0 ) < alpha && + ABS( p1 - p0 ) < beta && + ABS( q1 - q0 ) < beta ) { + int tc = tc0; + int i_delta; + + if( ABS( p2 - p0 ) < beta ) { + pix[-2] = p1 + clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 ); + tc++; + } + if( ABS( q2 - q0 ) < beta ) { + pix[1] = q1 + clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 ); + tc++; + } + + i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); + pix[-1] = clip_uint8( p0 + i_delta ); /* p0' */ + pix[0] = clip_uint8( q0 - i_delta ); /* q0' */ + tprintf("filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, qp[qp_index], index_a, alpha, beta, tc, bS[bS_index], pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1); + } + }else{ + /* 4px edge length */ + const int p0 = pix[-1]; + const int p1 = pix[-2]; + const int p2 = pix[-3]; + + const int q0 = pix[0]; + const int q1 = pix[1]; + const int q2 = pix[2]; + + if( ABS( p0 - q0 ) < alpha && + ABS( p1 - p0 ) < beta && + ABS( q1 - q0 ) < beta ) { + + if(ABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){ + if( ABS( p2 - p0 ) < beta) + { + const int p3 = pix[-4]; + /* p0', p1', p2' */ + pix[-1] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; + pix[-2] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; + pix[-3] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; + } else { + /* p0' */ + pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; + } + if( ABS( q2 - q0 ) < beta) + { + const int q3 = pix[3]; + /* q0', q1', q2' */ + pix[0] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3; + pix[1] = ( p0 + q0 + q1 + q2 + 2 ) >> 2; + pix[2] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3; + } else { + /* q0' */ + pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; + } + }else{ + /* p0', q0' */ + pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; + pix[ 0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; + } + tprintf("filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d\n# bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x, %02x, %02x]\n", i, qp[qp_index], index_a, alpha, beta, p2, p1, p0, q0, q1, q2, pix[-3], pix[-2], pix[-1], pix[0], pix[1], pix[2]); + } + } + } +} +static void filter_mb_mbaff_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp[2] ) { + int i; + for( i = 0; i < 8; i++, pix += stride) { + int index_a; + int alpha; + int beta; + + int qp_index; + int bS_index = i; + + if( bS[bS_index] == 0 ) { + continue; + } + + qp_index = h->mb_field_decoding_flag ? (i & 1) : (i >> 3); + index_a = clip( qp[qp_index] + h->slice_alpha_c0_offset, 0, 51 ); + alpha = alpha_table[index_a]; + beta = beta_table[clip( qp[qp_index] + h->slice_beta_offset, 0, 51 )]; + if( bS[bS_index] < 4 ) { + const int tc = tc0_table[index_a][bS[bS_index] - 1] + 1; + /* 2px edge length (because we use same bS than the one for luma) */ + const int p0 = pix[-1]; + const int p1 = pix[-2]; + const int q0 = pix[0]; + const int q1 = pix[1]; + + if( ABS( p0 - q0 ) < alpha && + ABS( p1 - p0 ) < beta && + ABS( q1 - q0 ) < beta ) { + const int i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); + + pix[-1] = clip_uint8( p0 + i_delta ); /* p0' */ + pix[0] = clip_uint8( q0 - i_delta ); /* q0' */ + tprintf("filter_mb_mbaff_edgecv i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, qp[qp_index], index_a, alpha, beta, tc, bS[bS_index], pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1); + } + }else{ + const int p0 = pix[-1]; + const int p1 = pix[-2]; + const int q0 = pix[0]; + const int q1 = pix[1]; + + if( ABS( p0 - q0 ) < alpha && + ABS( p1 - p0 ) < beta && + ABS( q1 - q0 ) < beta ) { + + pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */ + pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */ + tprintf("filter_mb_mbaff_edgecv i:%d\n# bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x, %02x, %02x]\n", i, pix[-3], p1, p0, q0, q1, pix[2], pix[-3], pix[-2], pix[-1], pix[0], pix[1], pix[2]); + } + } + } +} + +static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) { + int i, d; + const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 ); + const int alpha = alpha_table[index_a]; + const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; + const int pix_next = stride; + + if( bS[0] < 4 ) { + int8_t tc[4]; + for(i=0; i<4; i++) + tc[i] = bS[i] ? tc0_table[index_a][bS[i] - 1] : -1; + h->s.dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc); + } else { + /* 16px edge length, see filter_mb_edgev */ + for( d = 0; d < 16; d++ ) { + const int p0 = pix[-1*pix_next]; + const int p1 = pix[-2*pix_next]; + const int p2 = pix[-3*pix_next]; + const int q0 = pix[0]; + const int q1 = pix[1*pix_next]; + const int q2 = pix[2*pix_next]; + + if( ABS( p0 - q0 ) < alpha && + ABS( p1 - p0 ) < beta && + ABS( q1 - q0 ) < beta ) { + + const int p3 = pix[-4*pix_next]; + const int q3 = pix[ 3*pix_next]; + + if(ABS( p0 - q0 ) < (( alpha >> 2 ) + 2 )){ + if( ABS( p2 - p0 ) < beta) { + /* p0', p1', p2' */ + pix[-1*pix_next] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; + pix[-2*pix_next] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; + pix[-3*pix_next] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; + } else { + /* p0' */ + pix[-1*pix_next] = ( 2*p1 + p0 + q1 + 2 ) >> 2; + } + if( ABS( q2 - q0 ) < beta) { + /* q0', q1', q2' */ + pix[0*pix_next] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3; + pix[1*pix_next] = ( p0 + q0 + q1 + q2 + 2 ) >> 2; + pix[2*pix_next] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3; + } else { + /* q0' */ + pix[0*pix_next] = ( 2*q1 + q0 + p1 + 2 ) >> 2; + } + }else{ + /* p0', q0' */ + pix[-1*pix_next] = ( 2*p1 + p0 + q1 + 2 ) >> 2; + pix[ 0*pix_next] = ( 2*q1 + q0 + p1 + 2 ) >> 2; + } + tprintf("filter_mb_edgeh i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, d, qp, index_a, alpha, beta, bS[i], p2, p1, p0, q0, q1, q2, pix[-2*pix_next], pix[-pix_next], pix[0], pix[pix_next]); + } + pix++; + } + } +} + +static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) { + int i; + const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 ); + const int alpha = alpha_table[index_a]; + const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )]; + + if( bS[0] < 4 ) { + int8_t tc[4]; + for(i=0; i<4; i++) + tc[i] = bS[i] ? tc0_table[index_a][bS[i] - 1] + 1 : 0; + h->s.dsp.h264_v_loop_filter_chroma(pix, stride, alpha, beta, tc); + } else { + h->s.dsp.h264_v_loop_filter_chroma_intra(pix, stride, alpha, beta); + } +} + +static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) { + MpegEncContext * const s = &h->s; + const int mb_xy= mb_x + mb_y*s->mb_stride; + int first_vertical_edge_done = 0; + int dir; + /* FIXME: A given frame may occupy more than one position in + * the reference list. So ref2frm should be populated with + * frame numbers, not indices. */ + static const int ref2frm[18] = {-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + //for sufficiently low qp, filtering wouldn't do anything + //this is a conservative estimate: could also check beta_offset and more accurate chroma_qp + if(!h->mb_aff_frame){ + int qp_thresh = 15 - h->slice_alpha_c0_offset - FFMAX(0, h->pps.chroma_qp_index_offset); + int qp = s->current_picture.qscale_table[mb_xy]; + if(qp <= qp_thresh + && (mb_x == 0 || ((qp + s->current_picture.qscale_table[mb_xy-1] + 1)>>1) <= qp_thresh) + && (mb_y == 0 || ((qp + s->current_picture.qscale_table[h->top_mb_xy] + 1)>>1) <= qp_thresh)){ + return; + } + } + + if (h->mb_aff_frame + // left mb is in picture + && h->slice_table[mb_xy-1] != 255 + // and current and left pair do not have the same interlaced type + && (IS_INTERLACED(s->current_picture.mb_type[mb_xy]) != IS_INTERLACED(s->current_picture.mb_type[mb_xy-1])) + // and left mb is in the same slice if deblocking_filter == 2 + && (h->deblocking_filter!=2 || h->slice_table[mb_xy-1] == h->slice_table[mb_xy])) { + /* First vertical edge is different in MBAFF frames + * There are 8 different bS to compute and 2 different Qp + */ + int bS[8]; + int qp[2]; + int chroma_qp[2]; + + int i; + first_vertical_edge_done = 1; + for( i = 0; i < 8; i++ ) { + int y = i>>1; + int b_idx= 8 + 4 + 8*y; + int bn_idx= b_idx - 1; + + int mbn_xy = h->mb_field_decoding_flag ? h->left_mb_xy[i>>2] : h->left_mb_xy[i&1]; + + if( IS_INTRA( s->current_picture.mb_type[mb_xy] ) || + IS_INTRA( s->current_picture.mb_type[mbn_xy] ) ) { + bS[i] = 4; + } else if( h->non_zero_count_cache[b_idx] != 0 || + /* FIXME: with 8x8dct + cavlc, should check cbp instead of nnz */ + h->non_zero_count_cache[bn_idx] != 0 ) { + bS[i] = 2; + } else { + int l; + bS[i] = 0; + for( l = 0; l < 1 + (h->slice_type == B_TYPE); l++ ) { + if( ref2frm[h->ref_cache[l][b_idx]+2] != ref2frm[h->ref_cache[l][bn_idx]+2] || + ABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 || + ABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= 4 ) { + bS[i] = 1; + break; + } + } + } + } + if(bS[0]+bS[1]+bS[2]+bS[3] != 0) { + // Do not use s->qscale as luma quantizer because it has not the same + // value in IPCM macroblocks. + qp[0] = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[h->left_mb_xy[0]] + 1 ) >> 1; + chroma_qp[0] = ( get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mb_xy] ) + + get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[h->left_mb_xy[0]] ) + 1 ) >> 1; + qp[1] = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[h->left_mb_xy[1]] + 1 ) >> 1; + chroma_qp[1] = ( get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mb_xy] ) + + get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[h->left_mb_xy[1]] ) + 1 ) >> 1; + + /* Filter edge */ + tprintf("filter mb:%d/%d MBAFF, QPy:%d/%d, QPc:%d/%d ls:%d uvls:%d", mb_x, mb_y, qp[0], qp[1], chroma_qp[0], chroma_qp[1], linesize, uvlinesize); + { int i; for (i = 0; i < 8; i++) tprintf(" bS[%d]:%d", i, bS[i]); tprintf("\n"); } + filter_mb_mbaff_edgev ( h, &img_y [0], linesize, bS, qp ); + filter_mb_mbaff_edgecv( h, &img_cb[0], uvlinesize, bS, chroma_qp ); + filter_mb_mbaff_edgecv( h, &img_cr[0], uvlinesize, bS, chroma_qp ); + } + } + /* dir : 0 -> vertical edge, 1 -> horizontal edge */ + for( dir = 0; dir < 2; dir++ ) + { + int edge; + const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy; + const int mb_type = s->current_picture.mb_type[mb_xy]; + const int mbm_type = s->current_picture.mb_type[mbm_xy]; + int start = h->slice_table[mbm_xy] == 255 ? 1 : 0; + + const int edges = (mb_type & (MB_TYPE_16x16|MB_TYPE_SKIP)) + == (MB_TYPE_16x16|MB_TYPE_SKIP) ? 1 : 4; + // how often to recheck mv-based bS when iterating between edges + const int mask_edge = (mb_type & (MB_TYPE_16x16 | (MB_TYPE_16x8 << dir))) ? 3 : + (mb_type & (MB_TYPE_8x16 >> dir)) ? 1 : 0; + // how often to recheck mv-based bS when iterating along each edge + const int mask_par0 = mb_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir)); + + if (first_vertical_edge_done) { + start = 1; + first_vertical_edge_done = 0; + } + + if (h->deblocking_filter==2 && h->slice_table[mbm_xy] != h->slice_table[mb_xy]) + start = 1; + + /* Calculate bS */ + for( edge = start; edge < edges; edge++ ) { + /* mbn_xy: neighbor macroblock */ + const int mbn_xy = edge > 0 ? mb_xy : mbm_xy; + const int mbn_type = s->current_picture.mb_type[mbn_xy]; + int bS[4]; + int qp; + + if( (edge&1) && IS_8x8DCT(mb_type) ) + continue; + + if (h->mb_aff_frame && (dir == 1) && (edge == 0) && ((mb_y & 1) == 0) + && !IS_INTERLACED(mb_type) + && IS_INTERLACED(mbn_type) + ) { + // This is a special case in the norm where the filtering must + // be done twice (one each of the field) even if we are in a + // frame macroblock. + // + unsigned int tmp_linesize = 2 * linesize; + unsigned int tmp_uvlinesize = 2 * uvlinesize; + int mbn_xy = mb_xy - 2 * s->mb_stride; + int qp, chroma_qp; + + // first filtering + if( IS_INTRA(mb_type) || + IS_INTRA(s->current_picture.mb_type[mbn_xy]) ) { + bS[0] = bS[1] = bS[2] = bS[3] = 3; + } else { + // TODO + av_log(h->s.avctx, AV_LOG_ERROR, "both non intra (TODO)\n"); + } + /* Filter edge */ + // Do not use s->qscale as luma quantizer because it has not the same + // value in IPCM macroblocks. + qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1; + tprintf("filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); + { int i; for (i = 0; i < 4; i++) tprintf(" bS[%d]:%d", i, bS[i]); tprintf("\n"); } + filter_mb_edgeh( h, &img_y[0], tmp_linesize, bS, qp ); + chroma_qp = ( h->chroma_qp + + get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; + filter_mb_edgech( h, &img_cb[0], tmp_uvlinesize, bS, chroma_qp ); + filter_mb_edgech( h, &img_cr[0], tmp_uvlinesize, bS, chroma_qp ); + + // second filtering + mbn_xy += s->mb_stride; + if( IS_INTRA(mb_type) || + IS_INTRA(mbn_type) ) { + bS[0] = bS[1] = bS[2] = bS[3] = 3; + } else { + // TODO + av_log(h->s.avctx, AV_LOG_ERROR, "both non intra (TODO)\n"); + } + /* Filter edge */ + // Do not use s->qscale as luma quantizer because it has not the same + // value in IPCM macroblocks. + qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1; + tprintf("filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); + { int i; for (i = 0; i < 4; i++) tprintf(" bS[%d]:%d", i, bS[i]); tprintf("\n"); } + filter_mb_edgeh( h, &img_y[linesize], tmp_linesize, bS, qp ); + chroma_qp = ( h->chroma_qp + + get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; + filter_mb_edgech( h, &img_cb[uvlinesize], tmp_uvlinesize, bS, chroma_qp ); + filter_mb_edgech( h, &img_cr[uvlinesize], tmp_uvlinesize, bS, chroma_qp ); + continue; + } + if( IS_INTRA(mb_type) || + IS_INTRA(mbn_type) ) { + int value; + if (edge == 0) { + if ( (!IS_INTERLACED(mb_type) && !IS_INTERLACED(mbm_type)) + || ((h->mb_aff_frame || (s->picture_structure != PICT_FRAME)) && (dir == 0)) + ) { + value = 4; + } else { + value = 3; + } + } else { + value = 3; + } + bS[0] = bS[1] = bS[2] = bS[3] = value; + } else { + int i, l; + int mv_done; + + if( edge & mask_edge ) { + bS[0] = bS[1] = bS[2] = bS[3] = 0; + mv_done = 1; + } + else if( mask_par0 && (edge || (mbn_type & (MB_TYPE_16x16 | (MB_TYPE_8x16 >> dir)))) ) { + int b_idx= 8 + 4 + edge * (dir ? 8:1); + int bn_idx= b_idx - (dir ? 8:1); + int v = 0; + for( l = 0; !v && l < 1 + (h->slice_type == B_TYPE); l++ ) { + v |= ref2frm[h->ref_cache[l][b_idx]+2] != ref2frm[h->ref_cache[l][bn_idx]+2] || + ABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 || + ABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= 4; + } + bS[0] = bS[1] = bS[2] = bS[3] = v; + mv_done = 1; + } + else + mv_done = 0; + + for( i = 0; i < 4; i++ ) { + int x = dir == 0 ? edge : i; + int y = dir == 0 ? i : edge; + int b_idx= 8 + 4 + x + 8*y; + int bn_idx= b_idx - (dir ? 8:1); + + if( h->non_zero_count_cache[b_idx] != 0 || + h->non_zero_count_cache[bn_idx] != 0 ) { + bS[i] = 2; + } + else if(!mv_done) + { + bS[i] = 0; + for( l = 0; l < 1 + (h->slice_type == B_TYPE); l++ ) { + if( ref2frm[h->ref_cache[l][b_idx]+2] != ref2frm[h->ref_cache[l][bn_idx]+2] || + ABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 || + ABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= 4 ) { + bS[i] = 1; + break; + } + } + } + } + + if(bS[0]+bS[1]+bS[2]+bS[3] == 0) + continue; + } + + /* Filter edge */ + // Do not use s->qscale as luma quantizer because it has not the same + // value in IPCM macroblocks. + qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1; + //tprintf("filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp, s->current_picture.qscale_table[mbn_xy]); + tprintf("filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize); + { int i; for (i = 0; i < 4; i++) tprintf(" bS[%d]:%d", i, bS[i]); tprintf("\n"); } + if( dir == 0 ) { + filter_mb_edgev( h, &img_y[4*edge], linesize, bS, qp ); + if( (edge&1) == 0 ) { + int chroma_qp = ( h->chroma_qp + + get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; + filter_mb_edgecv( h, &img_cb[2*edge], uvlinesize, bS, chroma_qp ); + filter_mb_edgecv( h, &img_cr[2*edge], uvlinesize, bS, chroma_qp ); + } + } else { + filter_mb_edgeh( h, &img_y[4*edge*linesize], linesize, bS, qp ); + if( (edge&1) == 0 ) { + int chroma_qp = ( h->chroma_qp + + get_chroma_qp( h->pps.chroma_qp_index_offset, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; + filter_mb_edgech( h, &img_cb[2*edge*uvlinesize], uvlinesize, bS, chroma_qp ); + filter_mb_edgech( h, &img_cr[2*edge*uvlinesize], uvlinesize, bS, chroma_qp ); + } + } + } + } +} + +static int decode_slice(H264Context *h){ + MpegEncContext * const s = &h->s; + const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F; + + s->mb_skip_run= -1; + + if( h->pps.cabac ) { + int i; + + /* realign */ + align_get_bits( &s->gb ); + + /* init cabac */ + ff_init_cabac_states( &h->cabac, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64 ); + ff_init_cabac_decoder( &h->cabac, + s->gb.buffer + get_bits_count(&s->gb)/8, + ( s->gb.size_in_bits - get_bits_count(&s->gb) + 7)/8); + /* calculate pre-state */ + for( i= 0; i < 460; i++ ) { + int pre; + if( h->slice_type == I_TYPE ) + pre = clip( ((cabac_context_init_I[i][0] * s->qscale) >>4 ) + cabac_context_init_I[i][1], 1, 126 ); + else + pre = clip( ((cabac_context_init_PB[h->cabac_init_idc][i][0] * s->qscale) >>4 ) + cabac_context_init_PB[h->cabac_init_idc][i][1], 1, 126 ); + + if( pre <= 63 ) + h->cabac_state[i] = 2 * ( 63 - pre ) + 0; + else + h->cabac_state[i] = 2 * ( pre - 64 ) + 1; + } + + for(;;){ + int ret = decode_mb_cabac(h); + int eos; + + if(ret>=0) hl_decode_mb(h); + + /* XXX: useless as decode_mb_cabac it doesn't support that ... */ + if( ret >= 0 && h->mb_aff_frame ) { //FIXME optimal? or let mb_decode decode 16x32 ? + s->mb_y++; + + if(ret>=0) ret = decode_mb_cabac(h); + + if(ret>=0) hl_decode_mb(h); + s->mb_y--; + } + eos = get_cabac_terminate( &h->cabac ); + + if( ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 1) { + av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y); + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask); + return -1; + } + + if( ++s->mb_x >= s->mb_width ) { + s->mb_x = 0; + ff_draw_horiz_band(s, 16*s->mb_y, 16); + ++s->mb_y; + if(h->mb_aff_frame) { + ++s->mb_y; + } + } + + if( eos || s->mb_y >= s->mb_height ) { + tprintf("slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits); + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + return 0; + } + } + + } else { + for(;;){ + int ret = decode_mb_cavlc(h); + + if(ret>=0) hl_decode_mb(h); + + if(ret>=0 && h->mb_aff_frame){ //FIXME optimal? or let mb_decode decode 16x32 ? + s->mb_y++; + ret = decode_mb_cavlc(h); + + if(ret>=0) hl_decode_mb(h); + s->mb_y--; + } + + if(ret<0){ + av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y); + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask); + + return -1; + } + + if(++s->mb_x >= s->mb_width){ + s->mb_x=0; + ff_draw_horiz_band(s, 16*s->mb_y, 16); + ++s->mb_y; + if(h->mb_aff_frame) { + ++s->mb_y; + } + if(s->mb_y >= s->mb_height){ + tprintf("slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits); + + if(get_bits_count(&s->gb) == s->gb.size_in_bits ) { + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + + return 0; + }else{ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + + return -1; + } + } + } + + if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->mb_skip_run<=0){ + tprintf("slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits); + if(get_bits_count(&s->gb) == s->gb.size_in_bits ){ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + + return 0; + }else{ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask); + + return -1; + } + } + } + } + +#if 0 + for(;s->mb_y < s->mb_height; s->mb_y++){ + for(;s->mb_x < s->mb_width; s->mb_x++){ + int ret= decode_mb(h); + + hl_decode_mb(h); + + if(ret<0){ + av_log(s->avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y); + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask); + + return -1; + } + + if(++s->mb_x >= s->mb_width){ + s->mb_x=0; + if(++s->mb_y >= s->mb_height){ + if(get_bits_count(s->gb) == s->gb.size_in_bits){ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + + return 0; + }else{ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + + return -1; + } + } + } + + if(get_bits_count(s->?gb) >= s->gb?.size_in_bits){ + if(get_bits_count(s->gb) == s->gb.size_in_bits){ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); + + return 0; + }else{ + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask); + + return -1; + } + } + } + s->mb_x=0; + ff_draw_horiz_band(s, 16*s->mb_y, 16); + } +#endif + return -1; //not reached +} + +static int decode_unregistered_user_data(H264Context *h, int size){ + MpegEncContext * const s = &h->s; + uint8_t user_data[16+256]; + int e, build, i; + + if(size<16) + return -1; + + for(i=0; igb, 8); + } + + user_data[i]= 0; + e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build); + if(e==1 && build>=0) + h->x264_build= build; + + if(s->avctx->debug & FF_DEBUG_BUGS) + av_log(s->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data+16); + + for(; igb, 8); + + return 0; +} + +static int decode_sei(H264Context *h){ + MpegEncContext * const s = &h->s; + + while(get_bits_count(&s->gb) + 16 < s->gb.size_in_bits){ + int size, type; + + type=0; + do{ + type+= show_bits(&s->gb, 8); + }while(get_bits(&s->gb, 8) == 255); + + size=0; + do{ + size+= show_bits(&s->gb, 8); + }while(get_bits(&s->gb, 8) == 255); + + switch(type){ + case 5: + if(decode_unregistered_user_data(h, size) < 0); + return -1; + break; + default: + skip_bits(&s->gb, 8*size); + } + + //FIXME check bits here + align_get_bits(&s->gb); + } + + return 0; +} + +static inline void decode_hrd_parameters(H264Context *h, SPS *sps){ + MpegEncContext * const s = &h->s; + int cpb_count, i; + cpb_count = get_ue_golomb(&s->gb) + 1; + get_bits(&s->gb, 4); /* bit_rate_scale */ + get_bits(&s->gb, 4); /* cpb_size_scale */ + for(i=0; igb); /* bit_rate_value_minus1 */ + get_ue_golomb(&s->gb); /* cpb_size_value_minus1 */ + get_bits1(&s->gb); /* cbr_flag */ + } + get_bits(&s->gb, 5); /* initial_cpb_removal_delay_length_minus1 */ + get_bits(&s->gb, 5); /* cpb_removal_delay_length_minus1 */ + get_bits(&s->gb, 5); /* dpb_output_delay_length_minus1 */ + get_bits(&s->gb, 5); /* time_offset_length */ +} + +static inline int decode_vui_parameters(H264Context *h, SPS *sps){ + MpegEncContext * const s = &h->s; + int aspect_ratio_info_present_flag, aspect_ratio_idc; + int nal_hrd_parameters_present_flag, vcl_hrd_parameters_present_flag; + + aspect_ratio_info_present_flag= get_bits1(&s->gb); + + if( aspect_ratio_info_present_flag ) { + aspect_ratio_idc= get_bits(&s->gb, 8); + if( aspect_ratio_idc == EXTENDED_SAR ) { + sps->sar.num= get_bits(&s->gb, 16); + sps->sar.den= get_bits(&s->gb, 16); + }else if(aspect_ratio_idc < 14){ + sps->sar= pixel_aspect[aspect_ratio_idc]; + }else{ + av_log(h->s.avctx, AV_LOG_ERROR, "illegal aspect ratio\n"); + return -1; + } + }else{ + sps->sar.num= + sps->sar.den= 0; + } +// s->avctx->aspect_ratio= sar_width*s->width / (float)(s->height*sar_height); + + if(get_bits1(&s->gb)){ /* overscan_info_present_flag */ + get_bits1(&s->gb); /* overscan_appropriate_flag */ + } + + if(get_bits1(&s->gb)){ /* video_signal_type_present_flag */ + get_bits(&s->gb, 3); /* video_format */ + get_bits1(&s->gb); /* video_full_range_flag */ + if(get_bits1(&s->gb)){ /* colour_description_present_flag */ + get_bits(&s->gb, 8); /* colour_primaries */ + get_bits(&s->gb, 8); /* transfer_characteristics */ + get_bits(&s->gb, 8); /* matrix_coefficients */ + } + } + + if(get_bits1(&s->gb)){ /* chroma_location_info_present_flag */ + get_ue_golomb(&s->gb); /* chroma_sample_location_type_top_field */ + get_ue_golomb(&s->gb); /* chroma_sample_location_type_bottom_field */ + } + + sps->timing_info_present_flag = get_bits1(&s->gb); + if(sps->timing_info_present_flag){ + sps->num_units_in_tick = get_bits_long(&s->gb, 32); + sps->time_scale = get_bits_long(&s->gb, 32); + sps->fixed_frame_rate_flag = get_bits1(&s->gb); + } + + nal_hrd_parameters_present_flag = get_bits1(&s->gb); + if(nal_hrd_parameters_present_flag) + decode_hrd_parameters(h, sps); + vcl_hrd_parameters_present_flag = get_bits1(&s->gb); + if(vcl_hrd_parameters_present_flag) + decode_hrd_parameters(h, sps); + if(nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) + get_bits1(&s->gb); /* low_delay_hrd_flag */ + get_bits1(&s->gb); /* pic_struct_present_flag */ + + sps->bitstream_restriction_flag = get_bits1(&s->gb); + if(sps->bitstream_restriction_flag){ + get_bits1(&s->gb); /* motion_vectors_over_pic_boundaries_flag */ + get_ue_golomb(&s->gb); /* max_bytes_per_pic_denom */ + get_ue_golomb(&s->gb); /* max_bits_per_mb_denom */ + get_ue_golomb(&s->gb); /* log2_max_mv_length_horizontal */ + get_ue_golomb(&s->gb); /* log2_max_mv_length_vertical */ + sps->num_reorder_frames = get_ue_golomb(&s->gb); + get_ue_golomb(&s->gb); /* max_dec_frame_buffering */ + } + + return 0; +} + +static void decode_scaling_list(H264Context *h, uint8_t *factors, int size, + const uint8_t *jvt_list, const uint8_t *fallback_list){ + MpegEncContext * const s = &h->s; + int i, last = 8, next = 8; + const uint8_t *scan = size == 16 ? zigzag_scan : zigzag_scan8x8; + if(!get_bits1(&s->gb)) /* matrix not written, we use the predicted one */ + memcpy(factors, fallback_list, size*sizeof(uint8_t)); + else + for(i=0;igb)) & 0xff; + if(!i && !next){ /* matrix not written, we use the preset one */ + memcpy(factors, jvt_list, size*sizeof(uint8_t)); + break; + } + last = factors[scan[i]] = next ? next : last; + } +} + +static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_sps, + uint8_t (*scaling_matrix4)[16], uint8_t (*scaling_matrix8)[64]){ + MpegEncContext * const s = &h->s; + int fallback_sps = !is_sps && sps->scaling_matrix_present; + const uint8_t *fallback[4] = { + fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0], + fallback_sps ? sps->scaling_matrix4[3] : default_scaling4[1], + fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0], + fallback_sps ? sps->scaling_matrix8[1] : default_scaling8[1] + }; + if(get_bits1(&s->gb)){ + sps->scaling_matrix_present |= is_sps; + decode_scaling_list(h,scaling_matrix4[0],16,default_scaling4[0],fallback[0]); // Intra, Y + decode_scaling_list(h,scaling_matrix4[1],16,default_scaling4[0],scaling_matrix4[0]); // Intra, Cr + decode_scaling_list(h,scaling_matrix4[2],16,default_scaling4[0],scaling_matrix4[1]); // Intra, Cb + decode_scaling_list(h,scaling_matrix4[3],16,default_scaling4[1],fallback[1]); // Inter, Y + decode_scaling_list(h,scaling_matrix4[4],16,default_scaling4[1],scaling_matrix4[3]); // Inter, Cr + decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb + if(is_sps || pps->transform_8x8_mode){ + decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]); // Intra, Y + decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[1],fallback[3]); // Inter, Y + } + } else if(fallback_sps) { + memcpy(scaling_matrix4, sps->scaling_matrix4, 6*16*sizeof(uint8_t)); + memcpy(scaling_matrix8, sps->scaling_matrix8, 2*64*sizeof(uint8_t)); + } +} + +static inline int decode_seq_parameter_set(H264Context *h){ + MpegEncContext * const s = &h->s; + int profile_idc, level_idc; + int sps_id, i; + SPS *sps; + + profile_idc= get_bits(&s->gb, 8); + get_bits1(&s->gb); //constraint_set0_flag + get_bits1(&s->gb); //constraint_set1_flag + get_bits1(&s->gb); //constraint_set2_flag + get_bits1(&s->gb); //constraint_set3_flag + get_bits(&s->gb, 4); // reserved + level_idc= get_bits(&s->gb, 8); + sps_id= get_ue_golomb(&s->gb); + + sps= &h->sps_buffer[ sps_id ]; + sps->profile_idc= profile_idc; + sps->level_idc= level_idc; + + if(sps->profile_idc >= 100){ //high profile + if(get_ue_golomb(&s->gb) == 3) //chroma_format_idc + get_bits1(&s->gb); //residual_color_transform_flag + get_ue_golomb(&s->gb); //bit_depth_luma_minus8 + get_ue_golomb(&s->gb); //bit_depth_chroma_minus8 + sps->transform_bypass = get_bits1(&s->gb); + decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); + }else + sps->scaling_matrix_present = 0; + + sps->log2_max_frame_num= get_ue_golomb(&s->gb) + 4; + sps->poc_type= get_ue_golomb(&s->gb); + + if(sps->poc_type == 0){ //FIXME #define + sps->log2_max_poc_lsb= get_ue_golomb(&s->gb) + 4; + } else if(sps->poc_type == 1){//FIXME #define + sps->delta_pic_order_always_zero_flag= get_bits1(&s->gb); + sps->offset_for_non_ref_pic= get_se_golomb(&s->gb); + sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb); + sps->poc_cycle_length= get_ue_golomb(&s->gb); + + for(i=0; ipoc_cycle_length; i++) + sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb); + } + if(sps->poc_type > 2){ + av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type); + return -1; + } + + sps->ref_frame_count= get_ue_golomb(&s->gb); + if(sps->ref_frame_count > MAX_PICTURE_COUNT-2){ + av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); + } + sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb); + sps->mb_width= get_ue_golomb(&s->gb) + 1; + sps->mb_height= get_ue_golomb(&s->gb) + 1; + if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 || + avcodec_check_dimensions(NULL, 16*sps->mb_width, 16*sps->mb_height)) + return -1; + + sps->frame_mbs_only_flag= get_bits1(&s->gb); + if(!sps->frame_mbs_only_flag) + sps->mb_aff= get_bits1(&s->gb); + else + sps->mb_aff= 0; + + sps->direct_8x8_inference_flag= get_bits1(&s->gb); + + sps->crop= get_bits1(&s->gb); + if(sps->crop){ + sps->crop_left = get_ue_golomb(&s->gb); + sps->crop_right = get_ue_golomb(&s->gb); + sps->crop_top = get_ue_golomb(&s->gb); + sps->crop_bottom= get_ue_golomb(&s->gb); + if(sps->crop_left || sps->crop_top){ + av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); + } + }else{ + sps->crop_left = + sps->crop_right = + sps->crop_top = + sps->crop_bottom= 0; + } + + sps->vui_parameters_present_flag= get_bits1(&s->gb); + if( sps->vui_parameters_present_flag ) + decode_vui_parameters(h, sps); + + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%d profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s\n", + sps_id, sps->profile_idc, sps->level_idc, + sps->poc_type, + sps->ref_frame_count, + sps->mb_width, sps->mb_height, + sps->frame_mbs_only_flag ? "FRM" : (sps->mb_aff ? "MB-AFF" : "PIC-AFF"), + sps->direct_8x8_inference_flag ? "8B8" : "", + sps->crop_left, sps->crop_right, + sps->crop_top, sps->crop_bottom, + sps->vui_parameters_present_flag ? "VUI" : "" + ); + } + return 0; +} + +static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ + MpegEncContext * const s = &h->s; + int pps_id= get_ue_golomb(&s->gb); + PPS *pps= &h->pps_buffer[pps_id]; + + pps->sps_id= get_ue_golomb(&s->gb); + pps->cabac= get_bits1(&s->gb); + pps->pic_order_present= get_bits1(&s->gb); + pps->slice_group_count= get_ue_golomb(&s->gb) + 1; + if(pps->slice_group_count > 1 ){ + pps->mb_slice_group_map_type= get_ue_golomb(&s->gb); + av_log(h->s.avctx, AV_LOG_ERROR, "FMO not supported\n"); + switch(pps->mb_slice_group_map_type){ + case 0: +#if 0 +| for( i = 0; i <= num_slice_groups_minus1; i++ ) | | | +| run_length[ i ] |1 |ue(v) | +#endif + break; + case 2: +#if 0 +| for( i = 0; i < num_slice_groups_minus1; i++ ) | | | +|{ | | | +| top_left_mb[ i ] |1 |ue(v) | +| bottom_right_mb[ i ] |1 |ue(v) | +| } | | | +#endif + break; + case 3: + case 4: + case 5: +#if 0 +| slice_group_change_direction_flag |1 |u(1) | +| slice_group_change_rate_minus1 |1 |ue(v) | +#endif + break; + case 6: +#if 0 +| slice_group_id_cnt_minus1 |1 |ue(v) | +| for( i = 0; i <= slice_group_id_cnt_minus1; i++ | | | +|) | | | +| slice_group_id[ i ] |1 |u(v) | +#endif + break; + } + } + pps->ref_count[0]= get_ue_golomb(&s->gb) + 1; + pps->ref_count[1]= get_ue_golomb(&s->gb) + 1; + if(pps->ref_count[0] > 32 || pps->ref_count[1] > 32){ + av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow (pps)\n"); + return -1; + } + + pps->weighted_pred= get_bits1(&s->gb); + pps->weighted_bipred_idc= get_bits(&s->gb, 2); + pps->init_qp= get_se_golomb(&s->gb) + 26; + pps->init_qs= get_se_golomb(&s->gb) + 26; + pps->chroma_qp_index_offset= get_se_golomb(&s->gb); + pps->deblocking_filter_parameters_present= get_bits1(&s->gb); + pps->constrained_intra_pred= get_bits1(&s->gb); + pps->redundant_pic_cnt_present = get_bits1(&s->gb); + + memset(pps->scaling_matrix4, 16, 6*16*sizeof(uint8_t)); + memset(pps->scaling_matrix8, 16, 2*64*sizeof(uint8_t)); + + if(get_bits_count(&s->gb) < bit_length){ + pps->transform_8x8_mode= get_bits1(&s->gb); + decode_scaling_matrices(h, &h->sps_buffer[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); + get_se_golomb(&s->gb); //second_chroma_qp_index_offset + } + + if(s->avctx->debug&FF_DEBUG_PICT_INFO){ + av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%d sps:%d %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d %s %s %s %s\n", + pps_id, pps->sps_id, + pps->cabac ? "CABAC" : "CAVLC", + pps->slice_group_count, + pps->ref_count[0], pps->ref_count[1], + pps->weighted_pred ? "weighted" : "", + pps->init_qp, pps->init_qs, pps->chroma_qp_index_offset, + pps->deblocking_filter_parameters_present ? "LPAR" : "", + pps->constrained_intra_pred ? "CONSTR" : "", + pps->redundant_pic_cnt_present ? "REDU" : "", + pps->transform_8x8_mode ? "8x8DCT" : "" + ); + } + + return 0; +} + +/** + * finds the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or -1 + */ +static int find_frame_end(H264Context *h, const uint8_t *buf, int buf_size){ + int i; + uint32_t state; + ParseContext *pc = &(h->s.parse_context); +//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]); +// mb_addr= pc->mb_addr - 1; + state= pc->state; + for(i=0; i<=buf_size; i++){ + if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){ + tprintf("find_frame_end new startcode = %08x, frame_start_found = %d, pos = %d\n", state, pc->frame_start_found, i); + if(pc->frame_start_found){ + // If there isn't one more byte in the buffer + // the test on first_mb_in_slice cannot be done yet + // do it at next call. + if (i >= buf_size) break; + if (buf[i] & 0x80) { + // first_mb_in_slice is 0, probably the first nal of a new + // slice + tprintf("find_frame_end frame_end_found, state = %08x, pos = %d\n", state, i); + pc->state=-1; + pc->frame_start_found= 0; + return i-4; + } + } + pc->frame_start_found = 1; + } + if((state&0xFFFFFF1F) == 0x107 || (state&0xFFFFFF1F) == 0x108 || (state&0xFFFFFF1F) == 0x109){ + if(pc->frame_start_found){ + pc->state=-1; + pc->frame_start_found= 0; + return i-4; + } + } + if (istate= state; + return END_NOT_FOUND; +} + +static int h264_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + H264Context *h = s->priv_data; + ParseContext *pc = &h->s.parse_context; + int next; + + next= find_frame_end(h, buf, buf_size); + + if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + return buf_size; + } + + *poutbuf = (uint8_t *)buf; + *poutbuf_size = buf_size; + return next; +} + +static int h264_split(AVCodecContext *avctx, + const uint8_t *buf, int buf_size) +{ + int i; + uint32_t state = -1; + int has_sps= 0; + + for(i=0; i<=buf_size; i++){ + if((state&0xFFFFFF1F) == 0x107) + has_sps=1; +/* if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){ + }*/ + if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){ + if(has_sps){ + while(i>4 && buf[i-5]==0) i--; + return i-4; + } + } + if (is; + AVCodecContext * const avctx= s->avctx; + int buf_index=0; +#if 0 + int i; + for(i=0; i<50; i++){ + av_log(NULL, AV_LOG_ERROR,"%02X ", buf[i]); + } +#endif + h->slice_num = 0; + s->current_picture_ptr= NULL; + for(;;){ + int consumed; + int dst_length; + int bit_length; + uint8_t *ptr; + int i, nalsize = 0; + + if(h->is_avc) { + if(buf_index >= buf_size) break; + nalsize = 0; + for(i = 0; i < h->nal_length_size; i++) + nalsize = (nalsize << 8) | buf[buf_index++]; + if(nalsize <= 1){ + if(nalsize == 1){ + buf_index++; + continue; + }else{ + av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize); + break; + } + } + } else { + // start code prefix search + for(; buf_index + 3 < buf_size; buf_index++){ + // this should allways succeed in the first iteration + if(buf[buf_index] == 0 && buf[buf_index+1] == 0 && buf[buf_index+2] == 1) + break; + } + + if(buf_index+3 >= buf_size) break; + + buf_index+=3; + } + + ptr= decode_nal(h, buf + buf_index, &dst_length, &consumed, h->is_avc ? nalsize : buf_size - buf_index); + if(ptr[dst_length - 1] == 0) dst_length--; + bit_length= 8*dst_length - decode_rbsp_trailing(ptr + dst_length - 1); + + if(s->avctx->debug&FF_DEBUG_STARTCODE){ + av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d at %d/%d length %d\n", h->nal_unit_type, buf_index, buf_size, dst_length); + } + + if (h->is_avc && (nalsize != consumed)) + av_log(h->s.avctx, AV_LOG_ERROR, "AVC: Consumed only %d bytes instead of %d\n", consumed, nalsize); + + buf_index += consumed; + + if( (s->hurry_up == 1 && h->nal_ref_idc == 0) //FIXME dont discard SEI id + ||(avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0)) + continue; + + switch(h->nal_unit_type){ + case NAL_IDR_SLICE: + idr(h); //FIXME ensure we don't loose some frames if there is reordering + case NAL_SLICE: + init_get_bits(&s->gb, ptr, bit_length); + h->intra_gb_ptr= + h->inter_gb_ptr= &s->gb; + s->data_partitioning = 0; + + if(decode_slice_header(h) < 0){ + av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n"); + break; + } + s->current_picture_ptr->key_frame= (h->nal_unit_type == NAL_IDR_SLICE); + if(h->redundant_pic_count==0 && s->hurry_up < 5 + && (avctx->skip_frame < AVDISCARD_NONREF || h->nal_ref_idc) + && (avctx->skip_frame < AVDISCARD_BIDIR || h->slice_type!=B_TYPE) + && (avctx->skip_frame < AVDISCARD_NONKEY || h->slice_type==I_TYPE) + && avctx->skip_frame < AVDISCARD_ALL) + decode_slice(h); + break; + case NAL_DPA: + init_get_bits(&s->gb, ptr, bit_length); + h->intra_gb_ptr= + h->inter_gb_ptr= NULL; + s->data_partitioning = 1; + + if(decode_slice_header(h) < 0){ + av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n"); + } + break; + case NAL_DPB: + init_get_bits(&h->intra_gb, ptr, bit_length); + h->intra_gb_ptr= &h->intra_gb; + break; + case NAL_DPC: + init_get_bits(&h->inter_gb, ptr, bit_length); + h->inter_gb_ptr= &h->inter_gb; + + if(h->redundant_pic_count==0 && h->intra_gb_ptr && s->data_partitioning + && s->hurry_up < 5 + && (avctx->skip_frame < AVDISCARD_NONREF || h->nal_ref_idc) + && (avctx->skip_frame < AVDISCARD_BIDIR || h->slice_type!=B_TYPE) + && (avctx->skip_frame < AVDISCARD_NONKEY || h->slice_type==I_TYPE) + && avctx->skip_frame < AVDISCARD_ALL) + decode_slice(h); + break; + case NAL_SEI: + init_get_bits(&s->gb, ptr, bit_length); + decode_sei(h); + break; + case NAL_SPS: + init_get_bits(&s->gb, ptr, bit_length); + decode_seq_parameter_set(h); + + if(s->flags& CODEC_FLAG_LOW_DELAY) + s->low_delay=1; + + if(avctx->has_b_frames < 2) + avctx->has_b_frames= !s->low_delay; + break; + case NAL_PPS: + init_get_bits(&s->gb, ptr, bit_length); + + decode_picture_parameter_set(h, bit_length); + + break; + case NAL_AUD: + case NAL_END_SEQUENCE: + case NAL_END_STREAM: + case NAL_FILLER_DATA: + case NAL_SPS_EXT: + case NAL_AUXILIARY_SLICE: + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown NAL code: %d\n", h->nal_unit_type); + } + } + + if(!s->current_picture_ptr) return buf_index; //no frame + + s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264; + s->current_picture_ptr->pict_type= s->pict_type; + + h->prev_frame_num_offset= h->frame_num_offset; + h->prev_frame_num= h->frame_num; + if(s->current_picture_ptr->reference){ + h->prev_poc_msb= h->poc_msb; + h->prev_poc_lsb= h->poc_lsb; + } + if(s->current_picture_ptr->reference) + execute_ref_pic_marking(h, h->mmco, h->mmco_index); + + ff_er_frame_end(s); + + MPV_frame_end(s); + + return buf_index; +} + +/** + * returns the number of bytes consumed for building the current frame + */ +static int get_consumed_bytes(MpegEncContext *s, int pos, int buf_size){ + if(s->flags&CODEC_FLAG_TRUNCATED){ + pos -= s->parse_context.last_index; + if(pos<0) pos=0; // FIXME remove (unneeded?) + + return pos; + }else{ + if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...) + if(pos+10>buf_size) pos=buf_size; // oops ;) + + return pos; + } +} + +static int decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + H264Context *h = avctx->priv_data; + MpegEncContext *s = &h->s; + AVFrame *pict = data; + int buf_index; + + s->flags= avctx->flags; + s->flags2= avctx->flags2; + + /* no supplementary picture */ + if (buf_size == 0) { + return 0; + } + + if(s->flags&CODEC_FLAG_TRUNCATED){ + int next= find_frame_end(h, buf, buf_size); + + if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 ) + return buf_size; +//printf("next:%d buf_size:%d last_index:%d\n", next, buf_size, s->parse_context.last_index); + } + + if(h->is_avc && !h->got_avcC) { + int i, cnt, nalsize; + unsigned char *p = avctx->extradata; + if(avctx->extradata_size < 7) { + av_log(avctx, AV_LOG_ERROR, "avcC too short\n"); + return -1; + } + if(*p != 1) { + av_log(avctx, AV_LOG_ERROR, "Unknown avcC version %d\n", *p); + return -1; + } + /* sps and pps in the avcC always have length coded with 2 bytes, + so put a fake nal_length_size = 2 while parsing them */ + h->nal_length_size = 2; + // Decode sps from avcC + cnt = *(p+5) & 0x1f; // Number of sps + p += 6; + for (i = 0; i < cnt; i++) { + nalsize = BE_16(p) + 2; + if(decode_nal_units(h, p, nalsize) < 0) { + av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i); + return -1; + } + p += nalsize; + } + // Decode pps from avcC + cnt = *(p++); // Number of pps + for (i = 0; i < cnt; i++) { + nalsize = BE_16(p) + 2; + if(decode_nal_units(h, p, nalsize) != nalsize) { + av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i); + return -1; + } + p += nalsize; + } + // Now store right nal length size, that will be use to parse all other nals + h->nal_length_size = ((*(((char*)(avctx->extradata))+4))&0x03)+1; + // Do not reparse avcC + h->got_avcC = 1; + } + + if(!h->is_avc && s->avctx->extradata_size && s->picture_number==0){ + if(decode_nal_units(h, s->avctx->extradata, s->avctx->extradata_size) < 0) + return -1; + } + + buf_index=decode_nal_units(h, buf, buf_size); + if(buf_index < 0) + return -1; + + //FIXME do something with unavailable reference frames + +// if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_index, buf_size); + if(!s->current_picture_ptr){ + av_log(h->s.avctx, AV_LOG_DEBUG, "error, NO frame\n"); + return -1; + } + + { + Picture *out = s->current_picture_ptr; +#if 0 //decode order + *data_size = sizeof(AVFrame); +#else + /* Sort B-frames into display order */ + Picture *cur = s->current_picture_ptr; + Picture *prev = h->delayed_output_pic; + int out_idx = 0; + int pics = 0; + int out_of_order; + int cross_idr = 0; + int dropped_frame = 0; + int i; + + if(h->sps.bitstream_restriction_flag + && s->avctx->has_b_frames < h->sps.num_reorder_frames){ + s->avctx->has_b_frames = h->sps.num_reorder_frames; + s->low_delay = 0; + } + + while(h->delayed_pic[pics]) pics++; + h->delayed_pic[pics++] = cur; + if(cur->reference == 0) + cur->reference = 1; + + for(i=0; h->delayed_pic[i]; i++) + if(h->delayed_pic[i]->key_frame || h->delayed_pic[i]->poc==0) + cross_idr = 1; + + out = h->delayed_pic[0]; + for(i=1; h->delayed_pic[i] && !h->delayed_pic[i]->key_frame; i++) + if(h->delayed_pic[i]->poc < out->poc){ + out = h->delayed_pic[i]; + out_idx = i; + } + + out_of_order = !cross_idr && prev && out->poc < prev->poc; + if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >= h->sps.num_reorder_frames) + { } + else if(prev && pics <= s->avctx->has_b_frames) + out = prev; + else if((out_of_order && pics-1 == s->avctx->has_b_frames && pics < 15) + || (s->low_delay && + ((!cross_idr && prev && out->poc > prev->poc + 2) + || cur->pict_type == B_TYPE))) + { + s->low_delay = 0; + s->avctx->has_b_frames++; + out = prev; + } + else if(out_of_order) + out = prev; + + if(out_of_order || pics > s->avctx->has_b_frames){ + dropped_frame = (out != h->delayed_pic[out_idx]); + for(i=out_idx; h->delayed_pic[i]; i++) + h->delayed_pic[i] = h->delayed_pic[i+1]; + } + + if(prev == out && !dropped_frame) + *data_size = 0; + else + *data_size = sizeof(AVFrame); + if(prev && prev != out && prev->reference == 1) + prev->reference = 0; + h->delayed_output_pic = out; +#endif + + if(out) + *pict= *(AVFrame*)out; + else + av_log(avctx, AV_LOG_DEBUG, "no picture\n"); + } + + assert(pict->data[0] || !*data_size); + ff_print_debug_info(s, pict); +//printf("out %d\n", (int)pict->data[0]); +#if 0 //? + + /* Return the Picture timestamp as the frame number */ + /* we substract 1 because it is added on utils.c */ + avctx->frame_number = s->picture_number - 1; +#endif + return get_consumed_bytes(s, buf_index, buf_size); +} +#if 0 +static inline void fill_mb_avail(H264Context *h){ + MpegEncContext * const s = &h->s; + const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; + + if(s->mb_y){ + h->mb_avail[0]= s->mb_x && h->slice_table[mb_xy - s->mb_stride - 1] == h->slice_num; + h->mb_avail[1]= h->slice_table[mb_xy - s->mb_stride ] == h->slice_num; + h->mb_avail[2]= s->mb_x+1 < s->mb_width && h->slice_table[mb_xy - s->mb_stride + 1] == h->slice_num; + }else{ + h->mb_avail[0]= + h->mb_avail[1]= + h->mb_avail[2]= 0; + } + h->mb_avail[3]= s->mb_x && h->slice_table[mb_xy - 1] == h->slice_num; + h->mb_avail[4]= 1; //FIXME move out + h->mb_avail[5]= 0; //FIXME move out +} +#endif + +#if 0 //selftest +#define COUNT 8000 +#define SIZE (COUNT*40) +int main(){ + int i; + uint8_t temp[SIZE]; + PutBitContext pb; + GetBitContext gb; +// int int_temp[10000]; + DSPContext dsp; + AVCodecContext avctx; + + dsputil_init(&dsp, &avctx); + + init_put_bits(&pb, temp, SIZE); + printf("testing unsigned exp golomb\n"); + for(i=0; idsp.h264_idct_add(ref, block, 4); +/* for(j=0; j<16; j++){ + printf("%d ", ref[j]); + } + printf("\n");*/ + + for(j=0; j<16; j++){ + int diff= ABS(src[j] - ref[j]); + + error+= diff*diff; + max_error= FFMAX(max_error, diff); + } + } + printf("error=%f max_error=%d\n", ((float)error)/COUNT/16, (int)max_error ); +#if 0 + printf("testing quantizer\n"); + for(qp=0; qp<52; qp++){ + for(i=0; i<16; i++) + src1_block[i]= src2_block[i]= random()%255; + + } +#endif + printf("Testing NAL layer\n"); + + uint8_t bitstream[COUNT]; + uint8_t nal[COUNT*2]; + H264Context h; + memset(&h, 0, sizeof(H264Context)); + + for(i=0; ipriv_data; + MpegEncContext *s = &h->s; + + av_freep(&h->rbsp_buffer); + free_tables(h); //FIXME cleanup init stuff perhaps + MPV_common_end(s); + +// memset(h, 0, sizeof(H264Context)); + + return 0; +} + + +AVCodec h264_decoder = { + "h264", + CODEC_TYPE_VIDEO, + CODEC_ID_H264, + sizeof(H264Context), + decode_init, + NULL, + decode_end, + decode_frame, + /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, + .flush= flush_dpb, +}; + +AVCodecParser h264_parser = { + { CODEC_ID_H264 }, + sizeof(H264Context), + NULL, + h264_parse, + ff_parse_close, + h264_split, +}; + +#include "svq3.c" diff --git a/mpeg4/src/libavcodec/h264data.h b/mpeg4/src/libavcodec/h264data.h new file mode 100644 index 00000000..3132102d --- /dev/null +++ b/mpeg4/src/libavcodec/h264data.h @@ -0,0 +1,1240 @@ +/* + * H26L/H264/AVC/JVT/14496-10/... encoder/decoder + * Copyright (c) 2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file h264data.h + * @brief + * H264 / AVC / MPEG4 part10 codec data table + * @author Michael Niedermayer + */ + +#define VERT_PRED 0 +#define HOR_PRED 1 +#define DC_PRED 2 +#define DIAG_DOWN_LEFT_PRED 3 +#define DIAG_DOWN_RIGHT_PRED 4 +#define VERT_RIGHT_PRED 5 +#define HOR_DOWN_PRED 6 +#define VERT_LEFT_PRED 7 +#define HOR_UP_PRED 8 + +#define LEFT_DC_PRED 9 +#define TOP_DC_PRED 10 +#define DC_128_PRED 11 + + +#define DC_PRED8x8 0 +#define HOR_PRED8x8 1 +#define VERT_PRED8x8 2 +#define PLANE_PRED8x8 3 + +#define LEFT_DC_PRED8x8 4 +#define TOP_DC_PRED8x8 5 +#define DC_128_PRED8x8 6 + +#define EXTENDED_SAR 255 + +static const AVRational pixel_aspect[14]={ + {0, 1}, + {1, 1}, + {12, 11}, + {10, 11}, + {16, 11}, + {40, 33}, + {24, 11}, + {20, 11}, + {32, 11}, + {80, 33}, + {18, 11}, + {15, 11}, + {64, 33}, + {160,99}, +}; + +static const uint8_t golomb_to_pict_type[5]= +{P_TYPE, B_TYPE, I_TYPE, SP_TYPE, SI_TYPE}; + +static const uint8_t pict_type_to_golomb[7]= +{-1, 2, 0, 1, -1, 4, 3}; + +static const uint8_t chroma_qp[52]={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, + 12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, + 28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37, + 37,38,38,38,39,39,39,39 + +}; + +static const uint8_t golomb_to_intra4x4_cbp[48]={ + 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46, + 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4, + 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41 +}; + +static const uint8_t golomb_to_inter_cbp[48]={ + 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13, + 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46, + 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41 +}; + +static const uint8_t intra4x4_cbp_to_golomb[48]={ + 3, 29, 30, 17, 31, 18, 37, 8, 32, 38, 19, 9, 20, 10, 11, 2, + 16, 33, 34, 21, 35, 22, 39, 4, 36, 40, 23, 5, 24, 6, 7, 1, + 41, 42, 43, 25, 44, 26, 46, 12, 45, 47, 27, 13, 28, 14, 15, 0 +}; + +static const uint8_t inter_cbp_to_golomb[48]={ + 0, 2, 3, 7, 4, 8, 17, 13, 5, 18, 9, 14, 10, 15, 16, 11, + 1, 32, 33, 36, 34, 37, 44, 40, 35, 45, 38, 41, 39, 42, 43, 19, + 6, 24, 25, 20, 26, 21, 46, 28, 27, 47, 22, 29, 23, 30, 31, 12 +}; + +static const uint8_t chroma_dc_coeff_token_len[4*5]={ + 2, 0, 0, 0, + 6, 1, 0, 0, + 6, 6, 3, 0, + 6, 7, 7, 6, + 6, 8, 8, 7, +}; + +static const uint8_t chroma_dc_coeff_token_bits[4*5]={ + 1, 0, 0, 0, + 7, 1, 0, 0, + 4, 6, 1, 0, + 3, 3, 2, 5, + 2, 3, 2, 0, +}; + +static const uint8_t coeff_token_len[4][4*17]={ +{ + 1, 0, 0, 0, + 6, 2, 0, 0, 8, 6, 3, 0, 9, 8, 7, 5, 10, 9, 8, 6, + 11,10, 9, 7, 13,11,10, 8, 13,13,11, 9, 13,13,13,10, + 14,14,13,11, 14,14,14,13, 15,15,14,14, 15,15,15,14, + 16,15,15,15, 16,16,16,15, 16,16,16,16, 16,16,16,16, +}, +{ + 2, 0, 0, 0, + 6, 2, 0, 0, 6, 5, 3, 0, 7, 6, 6, 4, 8, 6, 6, 4, + 8, 7, 7, 5, 9, 8, 8, 6, 11, 9, 9, 6, 11,11,11, 7, + 12,11,11, 9, 12,12,12,11, 12,12,12,11, 13,13,13,12, + 13,13,13,13, 13,14,13,13, 14,14,14,13, 14,14,14,14, +}, +{ + 4, 0, 0, 0, + 6, 4, 0, 0, 6, 5, 4, 0, 6, 5, 5, 4, 7, 5, 5, 4, + 7, 5, 5, 4, 7, 6, 6, 4, 7, 6, 6, 4, 8, 7, 7, 5, + 8, 8, 7, 6, 9, 8, 8, 7, 9, 9, 8, 8, 9, 9, 9, 8, + 10, 9, 9, 9, 10,10,10,10, 10,10,10,10, 10,10,10,10, +}, +{ + 6, 0, 0, 0, + 6, 6, 0, 0, 6, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +} +}; + +static const uint8_t coeff_token_bits[4][4*17]={ +{ + 1, 0, 0, 0, + 5, 1, 0, 0, 7, 4, 1, 0, 7, 6, 5, 3, 7, 6, 5, 3, + 7, 6, 5, 4, 15, 6, 5, 4, 11,14, 5, 4, 8,10,13, 4, + 15,14, 9, 4, 11,10,13,12, 15,14, 9,12, 11,10,13, 8, + 15, 1, 9,12, 11,14,13, 8, 7,10, 9,12, 4, 6, 5, 8, +}, +{ + 3, 0, 0, 0, + 11, 2, 0, 0, 7, 7, 3, 0, 7,10, 9, 5, 7, 6, 5, 4, + 4, 6, 5, 6, 7, 6, 5, 8, 15, 6, 5, 4, 11,14,13, 4, + 15,10, 9, 4, 11,14,13,12, 8,10, 9, 8, 15,14,13,12, + 11,10, 9,12, 7,11, 6, 8, 9, 8,10, 1, 7, 6, 5, 4, +}, +{ + 15, 0, 0, 0, + 15,14, 0, 0, 11,15,13, 0, 8,12,14,12, 15,10,11,11, + 11, 8, 9,10, 9,14,13, 9, 8,10, 9, 8, 15,14,13,13, + 11,14,10,12, 15,10,13,12, 11,14, 9,12, 8,10,13, 8, + 13, 7, 9,12, 9,12,11,10, 5, 8, 7, 6, 1, 4, 3, 2, +}, +{ + 3, 0, 0, 0, + 0, 1, 0, 0, 4, 5, 6, 0, 8, 9,10,11, 12,13,14,15, + 16,17,18,19, 20,21,22,23, 24,25,26,27, 28,29,30,31, + 32,33,34,35, 36,37,38,39, 40,41,42,43, 44,45,46,47, + 48,49,50,51, 52,53,54,55, 56,57,58,59, 60,61,62,63, +} +}; + +static const uint8_t total_zeros_len[16][16]= { + {1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9}, + {3,3,3,3,3,4,4,4,4,5,5,6,6,6,6}, + {4,3,3,3,4,4,3,3,4,5,5,6,5,6}, + {5,3,4,4,3,3,3,4,3,4,5,5,5}, + {4,4,4,3,3,3,3,3,4,5,4,5}, + {6,5,3,3,3,3,3,3,4,3,6}, + {6,5,3,3,3,2,3,4,3,6}, + {6,4,5,3,2,2,3,3,6}, + {6,6,4,2,2,3,2,5}, + {5,5,3,2,2,2,4}, + {4,4,3,3,1,3}, + {4,4,2,1,3}, + {3,3,1,2}, + {2,2,1}, + {1,1}, +}; + +static const uint8_t total_zeros_bits[16][16]= { + {1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1}, + {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0}, + {5,7,6,5,4,3,4,3,2,3,2,1,1,0}, + {3,7,5,4,6,5,4,3,3,2,2,1,0}, + {5,4,3,7,6,5,4,3,2,1,1,0}, + {1,1,7,6,5,4,3,2,1,1,0}, + {1,1,5,4,3,3,2,1,1,0}, + {1,1,1,3,3,2,2,1,0}, + {1,0,1,3,2,1,1,1}, + {1,0,1,3,2,1,1}, + {0,1,1,2,1,3}, + {0,1,1,1,1}, + {0,1,1,1}, + {0,1,1}, + {0,1}, +}; + +static const uint8_t chroma_dc_total_zeros_len[3][4]= { + { 1, 2, 3, 3,}, + { 1, 2, 2, 0,}, + { 1, 1, 0, 0,}, +}; + +static const uint8_t chroma_dc_total_zeros_bits[3][4]= { + { 1, 1, 1, 0,}, + { 1, 1, 0, 0,}, + { 1, 0, 0, 0,}, +}; + +static const uint8_t run_len[7][16]={ + {1,1}, + {1,2,2}, + {2,2,2,2}, + {2,2,2,3,3}, + {2,2,3,3,3,3}, + {2,3,3,3,3,3,3}, + {3,3,3,3,3,3,3,4,5,6,7,8,9,10,11}, +}; + +static const uint8_t run_bits[7][16]={ + {1,0}, + {1,1,0}, + {3,2,1,0}, + {3,2,1,1,0}, + {3,2,3,2,1,0}, + {3,0,1,3,2,5,4}, + {7,6,5,4,3,2,1,1,1,1,1,1,1,1,1}, +}; + +/* +o-o o-o + / / / +o-o o-o + ,---' +o-o o-o + / / / +o-o o-o +*/ + +static const uint8_t scan8[16 + 2*4]={ + 4+1*8, 5+1*8, 4+2*8, 5+2*8, + 6+1*8, 7+1*8, 6+2*8, 7+2*8, + 4+3*8, 5+3*8, 4+4*8, 5+4*8, + 6+3*8, 7+3*8, 6+4*8, 7+4*8, + 1+1*8, 2+1*8, + 1+2*8, 2+2*8, + 1+4*8, 2+4*8, + 1+5*8, 2+5*8, +}; + +static const uint8_t zigzag_scan[16]={ + 0+0*4, 1+0*4, 0+1*4, 0+2*4, + 1+1*4, 2+0*4, 3+0*4, 2+1*4, + 1+2*4, 0+3*4, 1+3*4, 2+2*4, + 3+1*4, 3+2*4, 2+3*4, 3+3*4, +}; + +static const uint8_t field_scan[16]={ + 0+0*4, 0+1*4, 1+0*4, 0+2*4, + 0+3*4, 1+1*4, 1+2*4, 1+3*4, + 2+0*4, 2+1*4, 2+2*4, 2+3*4, + 3+0*4, 3+1*4, 3+2*4, 3+3*4, +}; + +static const uint8_t luma_dc_zigzag_scan[16]={ + 0*16 + 0*64, 1*16 + 0*64, 2*16 + 0*64, 0*16 + 2*64, + 3*16 + 0*64, 0*16 + 1*64, 1*16 + 1*64, 2*16 + 1*64, + 1*16 + 2*64, 2*16 + 2*64, 3*16 + 2*64, 0*16 + 3*64, + 3*16 + 1*64, 1*16 + 3*64, 2*16 + 3*64, 3*16 + 3*64, +}; + +static const uint8_t luma_dc_field_scan[16]={ + 0*16 + 0*64, 2*16 + 0*64, 1*16 + 0*64, 0*16 + 2*64, + 2*16 + 2*64, 3*16 + 0*64, 1*16 + 2*64, 3*16 + 2*64, + 0*16 + 1*64, 2*16 + 1*64, 0*16 + 3*64, 2*16 + 3*64, + 1*16 + 1*64, 3*16 + 1*64, 1*16 + 3*64, 3*16 + 3*64, +}; + +static const uint8_t chroma_dc_scan[4]={ + (0+0*2)*16, (1+0*2)*16, + (0+1*2)*16, (1+1*2)*16, //FIXME +}; + +static const uint8_t zigzag_scan8x8[64]={ + 0+0*8, 1+0*8, 0+1*8, 0+2*8, + 1+1*8, 2+0*8, 3+0*8, 2+1*8, + 1+2*8, 0+3*8, 0+4*8, 1+3*8, + 2+2*8, 3+1*8, 4+0*8, 5+0*8, + 4+1*8, 3+2*8, 2+3*8, 1+4*8, + 0+5*8, 0+6*8, 1+5*8, 2+4*8, + 3+3*8, 4+2*8, 5+1*8, 6+0*8, + 7+0*8, 6+1*8, 5+2*8, 4+3*8, + 3+4*8, 2+5*8, 1+6*8, 0+7*8, + 1+7*8, 2+6*8, 3+5*8, 4+4*8, + 5+3*8, 6+2*8, 7+1*8, 7+2*8, + 6+3*8, 5+4*8, 4+5*8, 3+6*8, + 2+7*8, 3+7*8, 4+6*8, 5+5*8, + 6+4*8, 7+3*8, 7+4*8, 6+5*8, + 5+6*8, 4+7*8, 5+7*8, 6+6*8, + 7+5*8, 7+6*8, 6+7*8, 7+7*8, +}; + +// zigzag_scan8x8_cavlc[i] = zigzag_scan8x8[(i/4) + 16*(i%4)] +static const uint8_t zigzag_scan8x8_cavlc[64]={ + 0+0*8, 1+1*8, 1+2*8, 2+2*8, + 4+1*8, 0+5*8, 3+3*8, 7+0*8, + 3+4*8, 1+7*8, 5+3*8, 6+3*8, + 2+7*8, 6+4*8, 5+6*8, 7+5*8, + 1+0*8, 2+0*8, 0+3*8, 3+1*8, + 3+2*8, 0+6*8, 4+2*8, 6+1*8, + 2+5*8, 2+6*8, 6+2*8, 5+4*8, + 3+7*8, 7+3*8, 4+7*8, 7+6*8, + 0+1*8, 3+0*8, 0+4*8, 4+0*8, + 2+3*8, 1+5*8, 5+1*8, 5+2*8, + 1+6*8, 3+5*8, 7+1*8, 4+5*8, + 4+6*8, 7+4*8, 5+7*8, 6+7*8, + 0+2*8, 2+1*8, 1+3*8, 5+0*8, + 1+4*8, 2+4*8, 6+0*8, 4+3*8, + 0+7*8, 4+4*8, 7+2*8, 3+6*8, + 5+5*8, 6+5*8, 6+6*8, 7+7*8, +}; + +#define MB_TYPE_REF0 MB_TYPE_ACPRED //dirty but it fits in 16bit +#define MB_TYPE_8x8DCT 0x01000000 +#define IS_REF0(a) ((a)&MB_TYPE_REF0) +#define IS_8x8DCT(a) ((a)&MB_TYPE_8x8DCT) + + +typedef struct IMbInfo{ + uint16_t type; + uint8_t pred_mode; + uint8_t cbp; +} IMbInfo; + +static const IMbInfo i_mb_type_info[26]={ +{MB_TYPE_INTRA4x4 , -1, -1}, +{MB_TYPE_INTRA16x16, 2, 0}, +{MB_TYPE_INTRA16x16, 1, 0}, +{MB_TYPE_INTRA16x16, 0, 0}, +{MB_TYPE_INTRA16x16, 3, 0}, +{MB_TYPE_INTRA16x16, 2, 16}, +{MB_TYPE_INTRA16x16, 1, 16}, +{MB_TYPE_INTRA16x16, 0, 16}, +{MB_TYPE_INTRA16x16, 3, 16}, +{MB_TYPE_INTRA16x16, 2, 32}, +{MB_TYPE_INTRA16x16, 1, 32}, +{MB_TYPE_INTRA16x16, 0, 32}, +{MB_TYPE_INTRA16x16, 3, 32}, +{MB_TYPE_INTRA16x16, 2, 15+0}, +{MB_TYPE_INTRA16x16, 1, 15+0}, +{MB_TYPE_INTRA16x16, 0, 15+0}, +{MB_TYPE_INTRA16x16, 3, 15+0}, +{MB_TYPE_INTRA16x16, 2, 15+16}, +{MB_TYPE_INTRA16x16, 1, 15+16}, +{MB_TYPE_INTRA16x16, 0, 15+16}, +{MB_TYPE_INTRA16x16, 3, 15+16}, +{MB_TYPE_INTRA16x16, 2, 15+32}, +{MB_TYPE_INTRA16x16, 1, 15+32}, +{MB_TYPE_INTRA16x16, 0, 15+32}, +{MB_TYPE_INTRA16x16, 3, 15+32}, +{MB_TYPE_INTRA_PCM , -1, -1}, +}; + +typedef struct PMbInfo{ + uint16_t type; + uint8_t partition_count; +} PMbInfo; + +static const PMbInfo p_mb_type_info[5]={ +{MB_TYPE_16x16|MB_TYPE_P0L0 , 1}, +{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P1L0, 2}, +{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P1L0, 2}, +{MB_TYPE_8x8 |MB_TYPE_P0L0|MB_TYPE_P1L0, 4}, +{MB_TYPE_8x8 |MB_TYPE_P0L0|MB_TYPE_P1L0|MB_TYPE_REF0, 4}, +}; + +static const PMbInfo p_sub_mb_type_info[4]={ +{MB_TYPE_16x16|MB_TYPE_P0L0 , 1}, +{MB_TYPE_16x8 |MB_TYPE_P0L0 , 2}, +{MB_TYPE_8x16 |MB_TYPE_P0L0 , 2}, +{MB_TYPE_8x8 |MB_TYPE_P0L0 , 4}, +}; + +static const PMbInfo b_mb_type_info[23]={ +{MB_TYPE_DIRECT2 , 1, }, +{MB_TYPE_16x16|MB_TYPE_P0L0 , 1, }, +{MB_TYPE_16x16 |MB_TYPE_P0L1 , 1, }, +{MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1 , 1, }, +{MB_TYPE_16x8 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L0 |MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L0 |MB_TYPE_P1L1, 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L1|MB_TYPE_P1L0 , 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L1|MB_TYPE_P1L0 , 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L0 |MB_TYPE_P1L0|MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L0 |MB_TYPE_P1L0|MB_TYPE_P1L1, 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0 , 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0 , 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 4, }, +}; + +static const PMbInfo b_sub_mb_type_info[13]={ +{MB_TYPE_DIRECT2 , 1, }, +{MB_TYPE_16x16|MB_TYPE_P0L0 , 1, }, +{MB_TYPE_16x16 |MB_TYPE_P0L1 , 1, }, +{MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1 , 1, }, +{MB_TYPE_16x8 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 2, }, +{MB_TYPE_16x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x16 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 2, }, +{MB_TYPE_8x8 |MB_TYPE_P0L0 |MB_TYPE_P1L0 , 4, }, +{MB_TYPE_8x8 |MB_TYPE_P0L1 |MB_TYPE_P1L1, 4, }, +{MB_TYPE_8x8 |MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_P1L0|MB_TYPE_P1L1, 4, }, +}; + + +static const uint8_t rem6[52]={ +0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, +}; + +static const uint8_t div6[52]={ +0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, +}; + +static const uint8_t default_scaling4[2][16]={ +{ 6,13,20,28, + 13,20,28,32, + 20,28,32,37, + 28,32,37,42 +},{ + 10,14,20,24, + 14,20,24,27, + 20,24,27,30, + 24,27,30,34 +}}; + +static const uint8_t default_scaling8[2][64]={ +{ 6,10,13,16,18,23,25,27, + 10,11,16,18,23,25,27,29, + 13,16,18,23,25,27,29,31, + 16,18,23,25,27,29,31,33, + 18,23,25,27,29,31,33,36, + 23,25,27,29,31,33,36,38, + 25,27,29,31,33,36,38,40, + 27,29,31,33,36,38,40,42 +},{ + 9,13,15,17,19,21,22,24, + 13,13,17,19,21,22,24,25, + 15,17,19,21,22,24,25,27, + 17,19,21,22,24,25,27,28, + 19,21,22,24,25,27,28,30, + 21,22,24,25,27,28,30,32, + 22,24,25,27,28,30,32,33, + 24,25,27,28,30,32,33,35 +}}; + +static const int dequant4_coeff_init[6][3]={ + {10,13,16}, + {11,14,18}, + {13,16,20}, + {14,18,23}, + {16,20,25}, + {18,23,29}, +}; + +static const int dequant8_coeff_init_scan[16] = { + 0,3,4,3, 3,1,5,1, 4,5,2,5, 3,1,5,1 +}; +static const int dequant8_coeff_init[6][6]={ + {20,18,32,19,25,24}, + {22,19,35,21,28,26}, + {26,23,42,24,33,31}, + {28,25,45,26,35,33}, + {32,28,51,30,40,38}, + {36,32,58,34,46,43}, +}; + +#define QUANT_SHIFT 22 + +static const int quant_coeff[52][16]={ + { 419430,258111,419430,258111,258111,167772,258111,167772,419430,258111,419430,258111,258111,167772,258111,167772,}, + { 381300,239675,381300,239675,239675,149131,239675,149131,381300,239675,381300,239675,239675,149131,239675,149131,}, + { 322639,209715,322639,209715,209715,134218,209715,134218,322639,209715,322639,209715,209715,134218,209715,134218,}, + { 299593,186414,299593,186414,186414,116711,186414,116711,299593,186414,299593,186414,186414,116711,186414,116711,}, + { 262144,167772,262144,167772,167772,107374,167772,107374,262144,167772,262144,167772,167772,107374,167772,107374,}, + { 233017,145889,233017,145889,145889, 92564,145889, 92564,233017,145889,233017,145889,145889, 92564,145889, 92564,}, + { 209715,129056,209715,129056,129056, 83886,129056, 83886,209715,129056,209715,129056,129056, 83886,129056, 83886,}, + { 190650,119837,190650,119837,119837, 74565,119837, 74565,190650,119837,190650,119837,119837, 74565,119837, 74565,}, + { 161319,104858,161319,104858,104858, 67109,104858, 67109,161319,104858,161319,104858,104858, 67109,104858, 67109,}, + { 149797, 93207,149797, 93207, 93207, 58356, 93207, 58356,149797, 93207,149797, 93207, 93207, 58356, 93207, 58356,}, + { 131072, 83886,131072, 83886, 83886, 53687, 83886, 53687,131072, 83886,131072, 83886, 83886, 53687, 83886, 53687,}, + { 116508, 72944,116508, 72944, 72944, 46282, 72944, 46282,116508, 72944,116508, 72944, 72944, 46282, 72944, 46282,}, + { 104858, 64528,104858, 64528, 64528, 41943, 64528, 41943,104858, 64528,104858, 64528, 64528, 41943, 64528, 41943,}, + { 95325, 59919, 95325, 59919, 59919, 37283, 59919, 37283, 95325, 59919, 95325, 59919, 59919, 37283, 59919, 37283,}, + { 80660, 52429, 80660, 52429, 52429, 33554, 52429, 33554, 80660, 52429, 80660, 52429, 52429, 33554, 52429, 33554,}, + { 74898, 46603, 74898, 46603, 46603, 29178, 46603, 29178, 74898, 46603, 74898, 46603, 46603, 29178, 46603, 29178,}, + { 65536, 41943, 65536, 41943, 41943, 26844, 41943, 26844, 65536, 41943, 65536, 41943, 41943, 26844, 41943, 26844,}, + { 58254, 36472, 58254, 36472, 36472, 23141, 36472, 23141, 58254, 36472, 58254, 36472, 36472, 23141, 36472, 23141,}, + { 52429, 32264, 52429, 32264, 32264, 20972, 32264, 20972, 52429, 32264, 52429, 32264, 32264, 20972, 32264, 20972,}, + { 47663, 29959, 47663, 29959, 29959, 18641, 29959, 18641, 47663, 29959, 47663, 29959, 29959, 18641, 29959, 18641,}, + { 40330, 26214, 40330, 26214, 26214, 16777, 26214, 16777, 40330, 26214, 40330, 26214, 26214, 16777, 26214, 16777,}, + { 37449, 23302, 37449, 23302, 23302, 14589, 23302, 14589, 37449, 23302, 37449, 23302, 23302, 14589, 23302, 14589,}, + { 32768, 20972, 32768, 20972, 20972, 13422, 20972, 13422, 32768, 20972, 32768, 20972, 20972, 13422, 20972, 13422,}, + { 29127, 18236, 29127, 18236, 18236, 11570, 18236, 11570, 29127, 18236, 29127, 18236, 18236, 11570, 18236, 11570,}, + { 26214, 16132, 26214, 16132, 16132, 10486, 16132, 10486, 26214, 16132, 26214, 16132, 16132, 10486, 16132, 10486,}, + { 23831, 14980, 23831, 14980, 14980, 9321, 14980, 9321, 23831, 14980, 23831, 14980, 14980, 9321, 14980, 9321,}, + { 20165, 13107, 20165, 13107, 13107, 8389, 13107, 8389, 20165, 13107, 20165, 13107, 13107, 8389, 13107, 8389,}, + { 18725, 11651, 18725, 11651, 11651, 7294, 11651, 7294, 18725, 11651, 18725, 11651, 11651, 7294, 11651, 7294,}, + { 16384, 10486, 16384, 10486, 10486, 6711, 10486, 6711, 16384, 10486, 16384, 10486, 10486, 6711, 10486, 6711,}, + { 14564, 9118, 14564, 9118, 9118, 5785, 9118, 5785, 14564, 9118, 14564, 9118, 9118, 5785, 9118, 5785,}, + { 13107, 8066, 13107, 8066, 8066, 5243, 8066, 5243, 13107, 8066, 13107, 8066, 8066, 5243, 8066, 5243,}, + { 11916, 7490, 11916, 7490, 7490, 4660, 7490, 4660, 11916, 7490, 11916, 7490, 7490, 4660, 7490, 4660,}, + { 10082, 6554, 10082, 6554, 6554, 4194, 6554, 4194, 10082, 6554, 10082, 6554, 6554, 4194, 6554, 4194,}, + { 9362, 5825, 9362, 5825, 5825, 3647, 5825, 3647, 9362, 5825, 9362, 5825, 5825, 3647, 5825, 3647,}, + { 8192, 5243, 8192, 5243, 5243, 3355, 5243, 3355, 8192, 5243, 8192, 5243, 5243, 3355, 5243, 3355,}, + { 7282, 4559, 7282, 4559, 4559, 2893, 4559, 2893, 7282, 4559, 7282, 4559, 4559, 2893, 4559, 2893,}, + { 6554, 4033, 6554, 4033, 4033, 2621, 4033, 2621, 6554, 4033, 6554, 4033, 4033, 2621, 4033, 2621,}, + { 5958, 3745, 5958, 3745, 3745, 2330, 3745, 2330, 5958, 3745, 5958, 3745, 3745, 2330, 3745, 2330,}, + { 5041, 3277, 5041, 3277, 3277, 2097, 3277, 2097, 5041, 3277, 5041, 3277, 3277, 2097, 3277, 2097,}, + { 4681, 2913, 4681, 2913, 2913, 1824, 2913, 1824, 4681, 2913, 4681, 2913, 2913, 1824, 2913, 1824,}, + { 4096, 2621, 4096, 2621, 2621, 1678, 2621, 1678, 4096, 2621, 4096, 2621, 2621, 1678, 2621, 1678,}, + { 3641, 2280, 3641, 2280, 2280, 1446, 2280, 1446, 3641, 2280, 3641, 2280, 2280, 1446, 2280, 1446,}, + { 3277, 2016, 3277, 2016, 2016, 1311, 2016, 1311, 3277, 2016, 3277, 2016, 2016, 1311, 2016, 1311,}, + { 2979, 1872, 2979, 1872, 1872, 1165, 1872, 1165, 2979, 1872, 2979, 1872, 1872, 1165, 1872, 1165,}, + { 2521, 1638, 2521, 1638, 1638, 1049, 1638, 1049, 2521, 1638, 2521, 1638, 1638, 1049, 1638, 1049,}, + { 2341, 1456, 2341, 1456, 1456, 912, 1456, 912, 2341, 1456, 2341, 1456, 1456, 912, 1456, 912,}, + { 2048, 1311, 2048, 1311, 1311, 839, 1311, 839, 2048, 1311, 2048, 1311, 1311, 839, 1311, 839,}, + { 1820, 1140, 1820, 1140, 1140, 723, 1140, 723, 1820, 1140, 1820, 1140, 1140, 723, 1140, 723,}, + { 1638, 1008, 1638, 1008, 1008, 655, 1008, 655, 1638, 1008, 1638, 1008, 1008, 655, 1008, 655,}, + { 1489, 936, 1489, 936, 936, 583, 936, 583, 1489, 936, 1489, 936, 936, 583, 936, 583,}, + { 1260, 819, 1260, 819, 819, 524, 819, 524, 1260, 819, 1260, 819, 819, 524, 819, 524,}, + { 1170, 728, 1170, 728, 728, 456, 728, 456, 1170, 728, 1170, 728, 728, 456, 728, 456,}, +}; + + +/* Deblocking filter (p153) */ +static const int alpha_table[52] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 5, 6, + 7, 8, 9, 10, 12, 13, 15, 17, 20, 22, + 25, 28, 32, 36, 40, 45, 50, 56, 63, 71, + 80, 90,101,113,127,144,162,182,203,226, + 255, 255 +}; +static const int beta_table[52] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, + 3, 3, 3, 4, 4, 4, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, + 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, + 18, 18 +}; +static const int tc0_table[52][3] = { + { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, + { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, + { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 }, + { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 1, 1 }, { 0, 1, 1 }, { 1, 1, 1 }, + { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 }, + { 1, 1, 2 }, { 1, 2, 3 }, { 1, 2, 3 }, { 2, 2, 3 }, { 2, 2, 4 }, { 2, 3, 4 }, + { 2, 3, 4 }, { 3, 3, 5 }, { 3, 4, 6 }, { 3, 4, 6 }, { 4, 5, 7 }, { 4, 5, 8 }, + { 4, 6, 9 }, { 5, 7,10 }, { 6, 8,11 }, { 6, 8,13 }, { 7,10,14 }, { 8,11,16 }, + { 9,12,18 }, {10,13,20 }, {11,15,23 }, {13,17,25 } +}; + +/* Cabac pre state table */ + +static const int cabac_context_init_I[460][2] = +{ + /* 0 - 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28,127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 - 23 unsused for I */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, + + /* 24- 39 */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + /* 40 - 53 */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, + + /* 54 - 59 */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, + + /* 60 - 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 -> 87 */ + { 0, 11 }, { 1, 55 }, { 0, 69 }, { -17, 127 }, + { -13, 102 },{ 0, 82 }, { -7, 74 }, { -21, 107 }, + { -27, 127 },{ -31, 127 },{ -24, 127 }, { -18, 95 }, + { -27, 127 },{ -21, 114 },{ -30, 127 }, { -17, 123 }, + { -12, 115 },{ -16, 122 }, + + /* 88 -> 104 */ + { -11, 115 },{ -12, 63 }, { -2, 68 }, { -15, 84 }, + { -13, 104 },{ -3, 70 }, { -8, 93 }, { -10, 90 }, + { -30, 127 },{ -1, 74 }, { -6, 97 }, { -7, 91 }, + { -20, 127 },{ -4, 56 }, { -5, 82 }, { -7, 76 }, + { -22, 125 }, + + /* 105 -> 135 */ + { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 }, + { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 }, + { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 }, + { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 }, + { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 }, + { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 }, + { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 }, + { 14, 62 }, { -13, 108 },{ -15, 100 }, + + /* 136 -> 165 */ + { -13, 101 },{ -13, 91 }, { -12, 94 }, { -10, 88 }, + { -16, 84 }, { -10, 86 }, { -7, 83 }, { -13, 87 }, + { -19, 94 }, { 1, 70 }, { 0, 72 }, { -5, 74 }, + { 18, 59 }, { -8, 102 }, { -15, 100 }, { 0, 95 }, + { -4, 75 }, { 2, 72 }, { -11, 75 }, { -3, 71 }, + { 15, 46 }, { -13, 69 }, { 0, 62 }, { 0, 65 }, + { 21, 37 }, { -15, 72 }, { 9, 57 }, { 16, 54 }, + { 0, 62 }, { 12, 72 }, + + /* 166 -> 196 */ + { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 }, + { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 }, + { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 }, + { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 }, + { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 }, + { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 }, + { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 }, + { 0, 89 }, { 26, -19 }, { 22, -17 }, + + /* 197 -> 226 */ + { 26, -17 }, { 30, -25 }, { 28, -20 }, { 33, -23 }, + { 37, -27 }, { 33, -23 }, { 40, -28 }, { 38, -17 }, + { 33, -11 }, { 40, -15 }, { 41, -6 }, { 38, 1 }, + { 41, 17 }, { 30, -6 }, { 27, 3 }, { 26, 22 }, + { 37, -16 }, { 35, -4 }, { 38, -8 }, { 38, -3 }, + { 37, 3 }, { 38, 5 }, { 42, 0 }, { 35, 16 }, + { 39, 22 }, { 14, 48 }, { 27, 37 }, { 21, 60 }, + { 12, 68 }, { 2, 97 }, + + /* 227 -> 251 */ + { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 }, + { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 }, + { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 }, + { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 }, + { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 }, + { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 }, + { -4, 65 }, + + /* 252 -> 275 */ + { -12, 73 }, { -8, 76 }, { -7, 80 }, { -9, 88 }, + { -17, 110 },{ -11, 97 }, { -20, 84 }, { -11, 79 }, + { -6, 73 }, { -4, 74 }, { -13, 86 }, { -13, 96 }, + { -11, 97 }, { -19, 117 },{ -8, 78 }, { -5, 33 }, + { -4, 48 }, { -2, 53 }, { -3, 62 }, { -13, 71 }, + { -10, 79 }, { -12, 86 }, { -13, 90 }, { -14, 97 }, + + /* 276 a bit special (not used, bypass is used instead) */ + { 0, 0 }, + + /* 277 -> 307 */ + { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 }, + { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 }, + { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 }, + { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 }, + { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 }, + { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 }, + { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 }, + { 9, 64 }, { -12, 104 },{ -11, 97 }, + + /* 308 -> 337 */ + { -16, 96 }, { -7, 88 }, { -8, 85 }, { -7, 85 }, + { -9, 85 }, { -13, 88 }, { 4, 66 }, { -3, 77 }, + { -3, 76 }, { -6, 76 }, { 10, 58 }, { -1, 76 }, + { -1, 83 }, { -7, 99 }, { -14, 95 }, { 2, 95 }, + { 0, 76 }, { -5, 74 }, { 0, 70 }, { -11, 75 }, + { 1, 68 }, { 0, 65 }, { -14, 73 }, { 3, 62 }, + { 4, 62 }, { -1, 68 }, { -13, 75 }, { 11, 55 }, + { 5, 64 }, { 12, 70 }, + + /* 338 -> 368 */ + { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 }, + { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 }, + { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 }, + { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 }, + { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 }, + { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 }, + { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 }, + { -12, 109 },{ 36, -35 }, { 36, -34 }, + + /* 369 -> 398 */ + { 32, -26 }, { 37, -30 }, { 44, -32 }, { 34, -18 }, + { 34, -15 }, { 40, -15 }, { 33, -7 }, { 35, -5 }, + { 33, 0 }, { 38, 2 }, { 33, 13 }, { 23, 35 }, + { 13, 58 }, { 29, -3 }, { 26, 0 }, { 22, 30 }, + { 31, -7 }, { 35, -15 }, { 34, -3 }, { 34, 3 }, + { 36, -1 }, { 34, 5 }, { 32, 11 }, { 35, 5 }, + { 34, 12 }, { 39, 11 }, { 30, 29 }, { 34, 26 }, + { 29, 39 }, { 19, 66 }, + + /* 399 -> 435 */ + { 31, 21 }, { 31, 31 }, { 25, 50 }, + { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 }, + { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 }, + { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 }, + { -23, 68 }, { -24, 50 }, { -11, 74 }, { 23, -13 }, + { 26, -13 }, { 40, -15 }, { 49, -14 }, { 44, 3 }, + { 45, 6 }, { 44, 34 }, { 33, 54 }, { 19, 82 }, + { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 }, + { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 }, + { 0, 68 }, { -9, 92 }, + + /* 436 -> 459 */ + { -14, 106 }, { -13, 97 }, { -15, 90 }, { -12, 90 }, + { -18, 88 }, { -10, 73 }, { -9, 79 }, { -14, 86 }, + { -10, 73 }, { -10, 70 }, { -10, 69 }, { -5, 66 }, + { -9, 64 }, { -5, 58 }, { 2, 59 }, { 21, -10 }, + { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 }, + { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 } +}; + +static const int cabac_context_init_PB[3][460][2] = +{ + /* i_cabac_init_idc == 0 */ + { + /* 0 - 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 - 23 */ + { 23, 33 }, { 23, 2 }, { 21, 0 }, { 1, 9 }, + { 0, 49 }, { -37, 118 }, { 5, 57 }, { -13, 78 }, + { -11, 65 }, { 1, 62 }, { 12, 49 }, { -4, 73 }, + { 17, 50 }, + + /* 24 - 39 */ + { 18, 64 }, { 9, 43 }, { 29, 0 }, { 26, 67 }, + { 16, 90 }, { 9, 104 }, { -46, 127 }, { -20, 104 }, + { 1, 67 }, { -13, 78 }, { -11, 65 }, { 1, 62 }, + { -6, 86 }, { -17, 95 }, { -6, 61 }, { 9, 45 }, + + /* 40 - 53 */ + { -3, 69 }, { -6, 81 }, { -11, 96 }, { 6, 55 }, + { 7, 67 }, { -5, 86 }, { 2, 88 }, { 0, 58 }, + { -3, 76 }, { -10, 94 }, { 5, 54 }, { 4, 69 }, + { -3, 81 }, { 0, 88 }, + + /* 54 - 59 */ + { -7, 67 }, { -5, 74 }, { -4, 74 }, { -5, 80 }, + { -7, 72 }, { 1, 58 }, + + /* 60 - 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 - 87 */ + { 0, 45 }, { -4, 78 }, { -3, 96 }, { -27, 126 }, + { -28, 98 }, { -25, 101 }, { -23, 67 }, { -28, 82 }, + { -20, 94 }, { -16, 83 }, { -22, 110 }, { -21, 91 }, + { -18, 102 }, { -13, 93 }, { -29, 127 }, { -7, 92 }, + { -5, 89 }, { -7, 96 }, { -13, 108 }, { -3, 46 }, + { -1, 65 }, { -1, 57 }, { -9, 93 }, { -3, 74 }, + { -9, 92 }, { -8, 87 }, { -23, 126 }, { 5, 54 }, + { 6, 60 }, { 6, 59 }, { 6, 69 }, { -1, 48 }, + { 0, 68 }, { -4, 69 }, { -8, 88 }, + + /* 105 -> 165 */ + { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 }, + { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 }, + { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 }, + { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 }, + { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 }, + { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 }, + { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 }, + { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 }, + { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 }, + { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 }, + { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 }, + { 3, 64 }, { 1, 61 }, { 9, 63 }, { 7, 50 }, + { 16, 39 }, { 5, 44 }, { 4, 52 }, { 11, 48 }, + { -5, 60 }, { -1, 59 }, { 0, 59 }, { 22, 33 }, + { 5, 44 }, { 14, 43 }, { -1, 78 }, { 0, 60 }, + { 9, 69 }, + + /* 166 - 226 */ + { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 }, + { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 }, + { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 }, + { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 }, + { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 }, + { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 }, + { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 }, + { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 }, + { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 }, + { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 }, + { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 }, + { 1, 67 }, { 5, 59 }, { 9, 67 }, { 16, 30 }, + { 18, 32 }, { 18, 35 }, { 22, 29 }, { 24, 31 }, + { 23, 38 }, { 18, 43 }, { 20, 41 }, { 11, 63 }, + { 9, 59 }, { 9, 64 }, { -1, 94 }, { -2, 89 }, + { -9, 108 }, + + /* 227 - 275 */ + { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 }, + { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 }, + { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 }, + { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 }, + { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 }, + { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 }, + { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 }, + { -3, 74 }, { -10, 90 }, { 0, 70 }, { -4, 29 }, + { 5, 31 }, { 7, 42 }, { 1, 59 }, { -2, 58 }, + { -3, 72 }, { -3, 81 }, { -11, 97 }, { 0, 58 }, + { 8, 5 }, { 10, 14 }, { 14, 18 }, { 13, 27 }, + { 2, 40 }, { 0, 58 }, { -3, 70 }, { -6, 79 }, + { -8, 85 }, + + /* 276 a bit special (not used, bypass is used instead) */ + { 0, 0 }, + + /* 277 - 337 */ + { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 }, + { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 }, + { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 }, + { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 }, + { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 }, + { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 }, + { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 }, + { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 }, + { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 }, + { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 }, + { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 }, + { -2, 69 }, { -2, 59 }, { 6, 70 }, { 10, 44 }, + { 9, 31 }, { 12, 43 }, { 3, 53 }, { 14, 34 }, + { 10, 38 }, { -3, 52 }, { 13, 40 }, { 17, 32 }, + { 7, 44 }, { 7, 38 }, { 13, 50 }, { 10, 57 }, + { 26, 43 }, + + /* 338 - 398 */ + { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 }, + { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 }, + { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 }, + { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 }, + { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 }, + { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 }, + { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 }, + { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 }, + { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 }, + { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 }, + { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 }, + { 8, 60 }, { 6, 63 }, { 17, 65 }, { 21, 24 }, + { 23, 20 }, { 26, 23 }, { 27, 32 }, { 28, 23 }, + { 28, 24 }, { 23, 40 }, { 24, 32 }, { 28, 29 }, + { 23, 42 }, { 19, 57 }, { 22, 53 }, { 22, 61 }, + { 11, 86 }, + + /* 399 - 435 */ + { 12, 40 }, { 11, 51 }, { 14, 59 }, + { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 }, + { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 }, + { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 }, + { -16, 66 }, { -22, 65 }, { -20, 63 }, { 9, -2 }, + { 26, -9 }, { 33, -9 }, { 39, -7 }, { 41, -2 }, + { 45, 3 }, { 49, 9 }, { 45, 27 }, { 36, 59 }, + { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 }, + { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 }, + { -8, 66 }, { -8, 76 }, + + /* 436 - 459 */ + { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, + { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, + { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, + { -14, 66 }, { 0, 59 }, { 2, 59 }, { 21, -13 }, + { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 }, + { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 }, + }, + + /* i_cabac_init_idc == 1 */ + { + /* 0 - 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 - 23 */ + { 22, 25 }, { 34, 0 }, { 16, 0 }, { -2, 9 }, + { 4, 41 }, { -29, 118 }, { 2, 65 }, { -6, 71 }, + { -13, 79 }, { 5, 52 }, { 9, 50 }, { -3, 70 }, + { 10, 54 }, + + /* 24 - 39 */ + { 26, 34 }, { 19, 22 }, { 40, 0 }, { 57, 2 }, + { 41, 36 }, { 26, 69 }, { -45, 127 }, { -15, 101 }, + { -4, 76 }, { -6, 71 }, { -13, 79 }, { 5, 52 }, + { 6, 69 }, { -13, 90 }, { 0, 52 }, { 8, 43 }, + + /* 40 - 53 */ + { -2, 69 },{ -5, 82 },{ -10, 96 },{ 2, 59 }, + { 2, 75 },{ -3, 87 },{ -3, 100 },{ 1, 56 }, + { -3, 74 },{ -6, 85 },{ 0, 59 },{ -3, 81 }, + { -7, 86 },{ -5, 95 }, + + /* 54 - 59 */ + { -1, 66 },{ -1, 77 },{ 1, 70 },{ -2, 86 }, + { -5, 72 },{ 0, 61 }, + + /* 60 - 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 - 104 */ + { 13, 15 }, { 7, 51 }, { 2, 80 }, { -39, 127 }, + { -18, 91 }, { -17, 96 }, { -26, 81 }, { -35, 98 }, + { -24, 102 }, { -23, 97 }, { -27, 119 }, { -24, 99 }, + { -21, 110 }, { -18, 102 }, { -36, 127 }, { 0, 80 }, + { -5, 89 }, { -7, 94 }, { -4, 92 }, { 0, 39 }, + { 0, 65 }, { -15, 84 }, { -35, 127 }, { -2, 73 }, + { -12, 104 }, { -9, 91 }, { -31, 127 }, { 3, 55 }, + { 7, 56 }, { 7, 55 }, { 8, 61 }, { -3, 53 }, + { 0, 68 }, { -7, 74 }, { -9, 88 }, + + /* 105 -> 165 */ + { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 }, + { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 }, + { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 }, + { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 }, + { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 }, + { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 }, + { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 }, + { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 }, + { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 }, + { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 }, + { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 }, + { -4, 71 }, { 0, 58 }, { 7, 61 }, { 9, 41 }, + { 18, 25 }, { 9, 32 }, { 5, 43 }, { 9, 47 }, + { 0, 44 }, { 0, 51 }, { 2, 46 }, { 19, 38 }, + { -4, 66 }, { 15, 38 }, { 12, 42 }, { 9, 34 }, + { 0, 89 }, + + /* 166 - 226 */ + { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 }, + { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 }, + { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 }, + { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 }, + { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 }, + { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 }, + { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 }, + { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 }, + { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 }, + { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 }, + { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 }, + { 0, 75 }, { 2, 72 }, { 8, 77 }, { 14, 35 }, + { 18, 31 }, { 17, 35 }, { 21, 30 }, { 17, 45 }, + { 20, 42 }, { 18, 45 }, { 27, 26 }, { 16, 54 }, + { 7, 66 }, { 16, 56 }, { 11, 73 }, { 10, 67 }, + { -10, 116 }, + + /* 227 - 275 */ + { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 }, + { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 }, + { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 }, + { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 }, + { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 }, + { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 }, + { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 }, + { -5, 74 }, { -9, 86 }, { 2, 66 }, { -9, 34 }, + { 1, 32 }, { 11, 31 }, { 5, 52 }, { -2, 55 }, + { -2, 67 }, { 0, 73 }, { -8, 89 }, { 3, 52 }, + { 7, 4 }, { 10, 8 }, { 17, 8 }, { 16, 19 }, + { 3, 37 }, { -1, 61 }, { -5, 73 }, { -1, 70 }, + { -4, 78 }, + + /* 276 a bit special (not used, bypass is used instead) */ + { 0, 0 }, + + /* 277 - 337 */ + { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 }, + { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 }, + { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 }, + { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 }, + { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 }, + { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 }, + { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 }, + { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 }, + { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 }, + { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 }, + { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 }, + { -1, 70 }, { -9, 72 }, { 14, 60 }, { 16, 37 }, + { 0, 47 }, { 18, 35 }, { 11, 37 }, { 12, 41 }, + { 10, 41 }, { 2, 48 }, { 12, 41 }, { 13, 41 }, + { 0, 59 }, { 3, 50 }, { 19, 40 }, { 3, 66 }, + { 18, 50 }, + + /* 338 - 398 */ + { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 }, + { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 }, + { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 }, + { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 }, + { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 }, + { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 }, + { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 }, + { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 }, + { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 }, + { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 }, + { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 }, + { 12, 48 }, { 11, 49 }, { 26, 45 }, { 22, 22 }, + { 23, 22 }, { 27, 21 }, { 33, 20 }, { 26, 28 }, + { 30, 24 }, { 27, 34 }, { 18, 42 }, { 25, 39 }, + { 18, 50 }, { 12, 70 }, { 21, 54 }, { 14, 71 }, + { 11, 83 }, + + /* 399 - 435 */ + { 25, 32 }, { 21, 49 }, { 21, 54 }, + { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, + { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, + { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, + { -14, 66 }, { 0, 59 }, { 2, 59 }, { 17, -10 }, + { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, + { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, + { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 }, + { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 }, + { -4, 67 }, { -7, 82 }, + + /* 436 - 459 */ + { -3, 81 }, { -3, 76 }, { -7, 72 }, { -6, 78 }, + { -12, 72 }, { -14, 68 }, { -3, 70 }, { -6, 76 }, + { -5, 66 }, { -5, 62 }, { 0, 57 }, { -4, 61 }, + { -9, 60 }, { 1, 54 }, { 2, 58 }, { 17, -10 }, + { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, + { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, + }, + + /* i_cabac_init_idc == 2 */ + { + /* 0 - 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 - 23 */ + { 29, 16 }, { 25, 0 }, { 14, 0 }, { -10, 51 }, + { -3, 62 }, { -27, 99 }, { 26, 16 }, { -4, 85 }, + { -24, 102 }, { 5, 57 }, { 6, 57 }, { -17, 73 }, + { 14, 57 }, + + /* 24 - 39 */ + { 20, 40 }, { 20, 10 }, { 29, 0 }, { 54, 0 }, + { 37, 42 }, { 12, 97 }, { -32, 127 }, { -22, 117 }, + { -2, 74 }, { -4, 85 }, { -24, 102 }, { 5, 57 }, + { -6, 93 }, { -14, 88 }, { -6, 44 }, { 4, 55 }, + + /* 40 - 53 */ + { -11, 89 },{ -15, 103 },{ -21, 116 },{ 19, 57 }, + { 20, 58 },{ 4, 84 },{ 6, 96 },{ 1, 63 }, + { -5, 85 },{ -13, 106 },{ 5, 63 },{ 6, 75 }, + { -3, 90 },{ -1, 101 }, + + /* 54 - 59 */ + { 3, 55 },{ -4, 79 },{ -2, 75 },{ -12, 97 }, + { -7, 50 },{ 1, 60 }, + + /* 60 - 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 - 104 */ + { 7, 34 }, { -9, 88 }, { -20, 127 }, { -36, 127 }, + { -17, 91 }, { -14, 95 }, { -25, 84 }, { -25, 86 }, + { -12, 89 }, { -17, 91 }, { -31, 127 }, { -14, 76 }, + { -18, 103 }, { -13, 90 }, { -37, 127 }, { 11, 80 }, + { 5, 76 }, { 2, 84 }, { 5, 78 }, { -6, 55 }, + { 4, 61 }, { -14, 83 }, { -37, 127 }, { -5, 79 }, + { -11, 104 }, { -11, 91 }, { -30, 127 }, { 0, 65 }, + { -2, 79 }, { 0, 72 }, { -4, 92 }, { -6, 56 }, + { 3, 68 }, { -8, 71 }, { -13, 98 }, + + /* 105 -> 165 */ + { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 }, + { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 }, + { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 }, + { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 }, + { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 }, + { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 }, + { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 }, + { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 }, + { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 }, + { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 }, + { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 }, + { 3, 65 }, { -7, 69 }, { 8, 77 }, { -10, 66 }, + { 3, 62 }, { -3, 68 }, { -20, 81 }, { 0, 30 }, + { 1, 7 }, { -3, 23 }, { -21, 74 }, { 16, 66 }, + { -23, 124 }, { 17, 37 }, { 44, -18 }, { 50, -34 }, + { -22, 127 }, + + /* 166 - 226 */ + { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 }, + { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 }, + { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 }, + { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 }, + { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 }, + { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 }, + { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 }, + { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 }, + { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 }, + { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 }, + { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 }, + { 20, 34 }, { 19, 31 }, { 27, 44 }, { 19, 16 }, + { 15, 36 }, { 15, 36 }, { 21, 28 }, { 25, 21 }, + { 30, 20 }, { 31, 12 }, { 27, 16 }, { 24, 42 }, + { 0, 93 }, { 14, 56 }, { 15, 57 }, { 26, 38 }, + { -24, 127 }, + + /* 227 - 275 */ + { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 }, + { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 }, + { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 }, + { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 }, + { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 }, + { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 }, + { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 }, + { -12, 92 }, { -18, 108 }, { -4, 79 }, { -22, 69 }, + { -16, 75 }, { -2, 58 }, { 1, 58 }, { -13, 78 }, + { -9, 83 }, { -4, 81 }, { -13, 99 }, { -13, 81 }, + { -6, 38 }, { -13, 62 }, { -6, 58 }, { -2, 59 }, + { -16, 73 }, { -10, 76 }, { -13, 86 }, { -9, 83 }, + { -10, 87 }, + + /* 276 a bit special (not used, bypass is used instead) */ + { 0, 0 }, + + /* 277 - 337 */ + { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 }, + { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 }, + { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 }, + { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 }, + { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 }, + { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 }, + { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 }, + { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 }, + { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 }, + { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 }, + { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 }, + { -2, 76 }, { -18, 86 }, { 12, 70 }, { 5, 64 }, + { -12, 70 }, { 11, 55 }, { 5, 56 }, { 0, 69 }, + { 2, 65 }, { -6, 74 }, { 5, 54 }, { 7, 54 }, + { -6, 76 }, { -11, 82 }, { -2, 77 }, { -2, 77 }, + { 25, 42 }, + + /* 338 - 398 */ + { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 }, + { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 }, + { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 }, + { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 }, + { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 }, + { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 }, + { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 }, + { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 }, + { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 }, + { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 }, + { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 }, + { 18, 31 }, { 19, 26 }, { 36, 24 }, { 24, 23 }, + { 27, 16 }, { 24, 30 }, { 31, 29 }, { 22, 41 }, + { 22, 42 }, { 16, 60 }, { 15, 52 }, { 14, 60 }, + { 3, 78 }, { -16, 123 }, { 21, 53 }, { 22, 56 }, + { 25, 61 }, + + /* 399 - 435 */ + { 21, 33 }, { 19, 50 }, { 17, 61 }, + { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, + { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, + { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, + { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, + { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, + { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, + { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 }, + { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 }, + { -6, 68 }, { -10, 79 }, + + /* 436 - 459 */ + { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, + { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, + { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, + { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, + { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, + { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, + } +}; diff --git a/mpeg4/src/libavcodec/h264idct.c b/mpeg4/src/libavcodec/h264idct.c new file mode 100644 index 00000000..3e44385d --- /dev/null +++ b/mpeg4/src/libavcodec/h264idct.c @@ -0,0 +1,166 @@ +/* + * H.264 IDCT + * Copyright (c) 2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file h264-idct.c + * H.264 IDCT. + * @author Michael Niedermayer + */ + +#include "dsputil.h" + +static always_inline void idct_internal(uint8_t *dst, DCTELEM *block, int stride, int block_stride, int shift, int add){ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + block[0] += 1<<(shift-1); + + for(i=0; i<4; i++){ + const int z0= block[0 + block_stride*i] + block[2 + block_stride*i]; + const int z1= block[0 + block_stride*i] - block[2 + block_stride*i]; + const int z2= (block[1 + block_stride*i]>>1) - block[3 + block_stride*i]; + const int z3= block[1 + block_stride*i] + (block[3 + block_stride*i]>>1); + + block[0 + block_stride*i]= z0 + z3; + block[1 + block_stride*i]= z1 + z2; + block[2 + block_stride*i]= z1 - z2; + block[3 + block_stride*i]= z0 - z3; + } + + for(i=0; i<4; i++){ + const int z0= block[i + block_stride*0] + block[i + block_stride*2]; + const int z1= block[i + block_stride*0] - block[i + block_stride*2]; + const int z2= (block[i + block_stride*1]>>1) - block[i + block_stride*3]; + const int z3= block[i + block_stride*1] + (block[i + block_stride*3]>>1); + + dst[i + 0*stride]= cm[ add*dst[i + 0*stride] + ((z0 + z3) >> shift) ]; + dst[i + 1*stride]= cm[ add*dst[i + 1*stride] + ((z1 + z2) >> shift) ]; + dst[i + 2*stride]= cm[ add*dst[i + 2*stride] + ((z1 - z2) >> shift) ]; + dst[i + 3*stride]= cm[ add*dst[i + 3*stride] + ((z0 - z3) >> shift) ]; + } +} + +void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride){ + idct_internal(dst, block, stride, 4, 6, 1); +} + +void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block){ + idct_internal(dst, block, stride, 8, 3, 1); +} + +void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block){ + idct_internal(dst, block, stride, 8, 3, 0); +} + +void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride){ + int i; + DCTELEM (*src)[8] = (DCTELEM(*)[8])block; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + block[0] += 32; + + for( i = 0; i < 8; i++ ) + { + const int a0 = src[i][0] + src[i][4]; + const int a2 = src[i][0] - src[i][4]; + const int a4 = (src[i][2]>>1) - src[i][6]; + const int a6 = (src[i][6]>>1) + src[i][2]; + + const int b0 = a0 + a6; + const int b2 = a2 + a4; + const int b4 = a2 - a4; + const int b6 = a0 - a6; + + const int a1 = -src[i][3] + src[i][5] - src[i][7] - (src[i][7]>>1); + const int a3 = src[i][1] + src[i][7] - src[i][3] - (src[i][3]>>1); + const int a5 = -src[i][1] + src[i][7] + src[i][5] + (src[i][5]>>1); + const int a7 = src[i][3] + src[i][5] + src[i][1] + (src[i][1]>>1); + + const int b1 = (a7>>2) + a1; + const int b3 = a3 + (a5>>2); + const int b5 = (a3>>2) - a5; + const int b7 = a7 - (a1>>2); + + src[i][0] = b0 + b7; + src[i][7] = b0 - b7; + src[i][1] = b2 + b5; + src[i][6] = b2 - b5; + src[i][2] = b4 + b3; + src[i][5] = b4 - b3; + src[i][3] = b6 + b1; + src[i][4] = b6 - b1; + } + for( i = 0; i < 8; i++ ) + { + const int a0 = src[0][i] + src[4][i]; + const int a2 = src[0][i] - src[4][i]; + const int a4 = (src[2][i]>>1) - src[6][i]; + const int a6 = (src[6][i]>>1) + src[2][i]; + + const int b0 = a0 + a6; + const int b2 = a2 + a4; + const int b4 = a2 - a4; + const int b6 = a0 - a6; + + const int a1 = -src[3][i] + src[5][i] - src[7][i] - (src[7][i]>>1); + const int a3 = src[1][i] + src[7][i] - src[3][i] - (src[3][i]>>1); + const int a5 = -src[1][i] + src[7][i] + src[5][i] + (src[5][i]>>1); + const int a7 = src[3][i] + src[5][i] + src[1][i] + (src[1][i]>>1); + + const int b1 = (a7>>2) + a1; + const int b3 = a3 + (a5>>2); + const int b5 = (a3>>2) - a5; + const int b7 = a7 - (a1>>2); + + dst[i + 0*stride] = cm[ dst[i + 0*stride] + ((b0 + b7) >> 6) ]; + dst[i + 1*stride] = cm[ dst[i + 1*stride] + ((b2 + b5) >> 6) ]; + dst[i + 2*stride] = cm[ dst[i + 2*stride] + ((b4 + b3) >> 6) ]; + dst[i + 3*stride] = cm[ dst[i + 3*stride] + ((b6 + b1) >> 6) ]; + dst[i + 4*stride] = cm[ dst[i + 4*stride] + ((b6 - b1) >> 6) ]; + dst[i + 5*stride] = cm[ dst[i + 5*stride] + ((b4 - b3) >> 6) ]; + dst[i + 6*stride] = cm[ dst[i + 6*stride] + ((b2 - b5) >> 6) ]; + dst[i + 7*stride] = cm[ dst[i + 7*stride] + ((b0 - b7) >> 6) ]; + } +} + +// assumes all AC coefs are 0 +void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride){ + int i, j; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + int dc = (block[0] + 32) >> 6; + for( j = 0; j < 4; j++ ) + { + for( i = 0; i < 4; i++ ) + dst[i] = cm[ dst[i] + dc ]; + dst += stride; + } +} + +void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride){ + int i, j; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + int dc = (block[0] + 32) >> 6; + for( j = 0; j < 8; j++ ) + { + for( i = 0; i < 8; i++ ) + dst[i] = cm[ dst[i] + dc ]; + dst += stride; + } +} diff --git a/mpeg4/src/libavcodec/huffyuv.c b/mpeg4/src/libavcodec/huffyuv.c new file mode 100644 index 00000000..d65943fc --- /dev/null +++ b/mpeg4/src/libavcodec/huffyuv.c @@ -0,0 +1,1270 @@ +/* + * huffyuv codec for libavcodec + * + * Copyright (c) 2002-2003 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of + * the algorithm used + */ + +/** + * @file huffyuv.c + * huffyuv codec for libavcodec. + */ + +#include "common.h" +#include "bitstream.h" +#include "avcodec.h" +#include "dsputil.h" + +#define VLC_BITS 11 + +#ifdef WORDS_BIGENDIAN +#define B 3 +#define G 2 +#define R 1 +#else +#define B 0 +#define G 1 +#define R 2 +#endif + +typedef enum Predictor{ + LEFT= 0, + PLANE, + MEDIAN, +} Predictor; + +typedef struct HYuvContext{ + AVCodecContext *avctx; + Predictor predictor; + GetBitContext gb; + PutBitContext pb; + int interlaced; + int decorrelate; + int bitstream_bpp; + int version; + int yuy2; //use yuy2 instead of 422P + int bgr32; //use bgr32 instead of bgr24 + int width, height; + int flags; + int context; + int picture_number; + int last_slice_end; + uint8_t *temp[3]; + uint64_t stats[3][256]; + uint8_t len[3][256]; + uint32_t bits[3][256]; + VLC vlc[3]; + AVFrame picture; + uint8_t *bitstream_buffer; + unsigned int bitstream_buffer_size; + DSPContext dsp; +}HYuvContext; + +static const unsigned char classic_shift_luma[] = { + 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8, + 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70, + 69,68, 0 +}; + +static const unsigned char classic_shift_chroma[] = { + 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183, + 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119, + 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0 +}; + +static const unsigned char classic_add_luma[256] = { + 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37, + 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36, + 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36, + 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39, + 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37, + 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29, + 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16, + 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14, + 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6, + 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15, + 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25, + 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49, + 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60, + 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52, + 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43, + 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8, +}; + +static const unsigned char classic_add_chroma[256] = { + 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9, + 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7, + 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77, + 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63, + 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22, + 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111, + 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1, + 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134, + 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96, + 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41, + 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36, + 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26, + 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13, + 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8, + 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2, +}; + +static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){ + int i; + + for(i=0; idsp.diff_bytes(dst+16, src+16, src+15, w-16); + return src[w-1]; + } +} + +static void read_len_table(uint8_t *dst, GetBitContext *gb){ + int i, val, repeat; + + for(i=0; i<256;){ + repeat= get_bits(gb, 3); + val = get_bits(gb, 5); + if(repeat==0) + repeat= get_bits(gb, 8); +//printf("%d %d\n", val, repeat); + while (repeat--) + dst[i++] = val; + } +} + +static int generate_bits_table(uint32_t *dst, uint8_t *len_table){ + int len, index; + uint32_t bits=0; + + for(len=32; len>0; len--){ + for(index=0; index<256; index++){ + if(len_table[index]==len) + dst[index]= bits++; + } + if(bits & 1){ + av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n"); + return -1; + } + bits >>= 1; + } + return 0; +} + +static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){ + uint64_t counts[2*size]; + int up[2*size]; + int offset, i, next; + + for(offset=1; ; offset<<=1){ + for(i=0; i counts[i]){ + if(min1 > counts[i]){ + min2= min1; + min2_i= min1_i; + min1= counts[i]; + min1_i= i; + }else{ + min2= counts[i]; + min2_i= i; + } + } + } + + if(min2==INT64_MAX) break; + + counts[next]= min1 + min2; + counts[min1_i]= + counts[min2_i]= INT64_MAX; + up[min1_i]= + up[min2_i]= next; + up[next]= -1; + } + + for(i=0; i= 32) break; + + dst[i]= len; + } + if(i==size) break; + } +} + +static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){ + GetBitContext gb; + int i; + + init_get_bits(&gb, src, length*8); + + for(i=0; i<3; i++){ + read_len_table(s->len[i], &gb); + + if(generate_bits_table(s->bits[i], s->len[i])<0){ + return -1; + } +#if 0 +for(j=0; j<256; j++){ +printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j); +} +#endif + free_vlc(&s->vlc[i]); + init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); + } + + return (get_bits_count(&gb)+7)/8; +} + +static int read_old_huffman_tables(HYuvContext *s){ +#if 1 + GetBitContext gb; + int i; + + init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8); + read_len_table(s->len[0], &gb); + init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8); + read_len_table(s->len[1], &gb); + + for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i]; + for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i]; + + if(s->bitstream_bpp >= 24){ + memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t)); + memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t)); + } + memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t)); + memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t)); + + for(i=0; i<3; i++){ + free_vlc(&s->vlc[i]); + init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); + } + + return 0; +#else + av_log(s->avctx, AV_LOG_DEBUG, "v1 huffyuv is not supported \n"); + return -1; +#endif +} + +static void alloc_temp(HYuvContext *s){ + int i; + + if(s->bitstream_bpp<24){ + for(i=0; i<3; i++){ + s->temp[i]= av_malloc(s->width + 16); + } + }else{ + s->temp[0]= av_malloc(4*s->width + 16); + } +} + +static int common_init(AVCodecContext *avctx){ + HYuvContext *s = avctx->priv_data; + + s->avctx= avctx; + s->flags= avctx->flags; + + dsputil_init(&s->dsp, avctx); + + s->width= avctx->width; + s->height= avctx->height; + assert(s->width>0 && s->height>0); + + return 0; +} + +static int decode_init(AVCodecContext *avctx) +{ + HYuvContext *s = avctx->priv_data; + + common_init(avctx); + memset(s->vlc, 0, 3*sizeof(VLC)); + + avctx->coded_frame= &s->picture; + s->interlaced= s->height > 288; + +s->bgr32=1; +//if(avctx->extradata) +// printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size); + if(avctx->extradata_size){ + if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12) + s->version=1; // do such files exist at all? + else + s->version=2; + }else + s->version=0; + + if(s->version==2){ + int method, interlace; + + method= ((uint8_t*)avctx->extradata)[0]; + s->decorrelate= method&64 ? 1 : 0; + s->predictor= method&63; + s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1]; + if(s->bitstream_bpp==0) + s->bitstream_bpp= avctx->bits_per_sample&~7; + interlace= (((uint8_t*)avctx->extradata)[2] & 0x30) >> 4; + s->interlaced= (interlace==1) ? 1 : (interlace==2) ? 0 : s->interlaced; + s->context= ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0; + + if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0) + return -1; + }else{ + switch(avctx->bits_per_sample&7){ + case 1: + s->predictor= LEFT; + s->decorrelate= 0; + break; + case 2: + s->predictor= LEFT; + s->decorrelate= 1; + break; + case 3: + s->predictor= PLANE; + s->decorrelate= avctx->bits_per_sample >= 24; + break; + case 4: + s->predictor= MEDIAN; + s->decorrelate= 0; + break; + default: + s->predictor= LEFT; //OLD + s->decorrelate= 0; + break; + } + s->bitstream_bpp= avctx->bits_per_sample & ~7; + s->context= 0; + + if(read_old_huffman_tables(s) < 0) + return -1; + } + + switch(s->bitstream_bpp){ + case 12: + avctx->pix_fmt = PIX_FMT_YUV420P; + break; + case 16: + if(s->yuy2){ + avctx->pix_fmt = PIX_FMT_YUV422; + }else{ + avctx->pix_fmt = PIX_FMT_YUV422P; + } + break; + case 24: + case 32: + if(s->bgr32){ + avctx->pix_fmt = PIX_FMT_RGBA32; + }else{ + avctx->pix_fmt = PIX_FMT_BGR24; + } + break; + default: + assert(0); + } + + alloc_temp(s); + +// av_log(NULL, AV_LOG_DEBUG, "pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced); + + return 0; +} + +static int store_table(HYuvContext *s, uint8_t *len, uint8_t *buf){ + int i; + int index= 0; + + for(i=0; i<256;){ + int val= len[i]; + int repeat=0; + + for(; i<256 && len[i]==val && repeat<255; i++) + repeat++; + + assert(val < 32 && val >0 && repeat<256 && repeat>0); + if(repeat>7){ + buf[index++]= val; + buf[index++]= repeat; + }else{ + buf[index++]= val | (repeat<<5); + } + } + + return index; +} + +static int encode_init(AVCodecContext *avctx) +{ + HYuvContext *s = avctx->priv_data; + int i, j; + + common_init(avctx); + + avctx->extradata= av_mallocz(1024*30); // 256*3+4 == 772 + avctx->stats_out= av_mallocz(1024*30); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132 + s->version=2; + + avctx->coded_frame= &s->picture; + + switch(avctx->pix_fmt){ + case PIX_FMT_YUV420P: + s->bitstream_bpp= 12; + break; + case PIX_FMT_YUV422P: + s->bitstream_bpp= 16; + break; + default: + av_log(avctx, AV_LOG_ERROR, "format not supported\n"); + return -1; + } + avctx->bits_per_sample= s->bitstream_bpp; + s->decorrelate= s->bitstream_bpp >= 24; + s->predictor= avctx->prediction_method; + s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0; + if(avctx->context_model==1){ + s->context= avctx->context_model; + if(s->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)){ + av_log(avctx, AV_LOG_ERROR, "context=1 is not compatible with 2 pass huffyuv encoding\n"); + return -1; + } + }else s->context= 0; + + if(avctx->codec->id==CODEC_ID_HUFFYUV){ + if(avctx->pix_fmt==PIX_FMT_YUV420P){ + av_log(avctx, AV_LOG_ERROR, "Error: YV12 is not supported by huffyuv; use vcodec=ffvhuff or format=422p\n"); + return -1; + } + if(avctx->context_model){ + av_log(avctx, AV_LOG_ERROR, "Error: per-frame huffman tables are not supported by huffyuv; use vcodec=ffvhuff\n"); + return -1; + } + if(s->interlaced != ( s->height > 288 )) + av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n"); + } + + ((uint8_t*)avctx->extradata)[0]= s->predictor; + ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp; + ((uint8_t*)avctx->extradata)[2]= s->interlaced ? 0x10 : 0x20; + if(s->context) + ((uint8_t*)avctx->extradata)[2]|= 0x40; + ((uint8_t*)avctx->extradata)[3]= 0; + s->avctx->extradata_size= 4; + + if(avctx->stats_in){ + char *p= avctx->stats_in; + + for(i=0; i<3; i++) + for(j=0; j<256; j++) + s->stats[i][j]= 1; + + for(;;){ + for(i=0; i<3; i++){ + char *next; + + for(j=0; j<256; j++){ + s->stats[i][j]+= strtol(p, &next, 0); + if(next==p) return -1; + p=next; + } + } + if(p[0]==0 || p[1]==0 || p[2]==0) break; + } + }else{ + for(i=0; i<3; i++) + for(j=0; j<256; j++){ + int d= FFMIN(j, 256-j); + + s->stats[i][j]= 100000000/(d+1); + } + } + + for(i=0; i<3; i++){ + generate_len_table(s->len[i], s->stats[i], 256); + + if(generate_bits_table(s->bits[i], s->len[i])<0){ + return -1; + } + + s->avctx->extradata_size+= + store_table(s, s->len[i], &((uint8_t*)s->avctx->extradata)[s->avctx->extradata_size]); + } + + if(s->context){ + for(i=0; i<3; i++){ + int pels = s->width*s->height / (i?40:10); + for(j=0; j<256; j++){ + int d= FFMIN(j, 256-j); + s->stats[i][j]= pels/(d+1); + } + } + }else{ + for(i=0; i<3; i++) + for(j=0; j<256; j++) + s->stats[i][j]= 0; + } + +// printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced); + + alloc_temp(s); + + s->picture_number=0; + + return 0; +} + +static void decode_422_bitstream(HYuvContext *s, int count){ + int i; + + count/=2; + + for(i=0; itemp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); + s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); + } +} + +static void decode_gray_bitstream(HYuvContext *s, int count){ + int i; + + count/=2; + + for(i=0; itemp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + } +} + +static int encode_422_bitstream(HYuvContext *s, int count){ + int i; + + if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 2*4*count){ + av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + + count/=2; + if(s->flags&CODEC_FLAG_PASS1){ + for(i=0; istats[0][ s->temp[0][2*i ] ]++; + s->stats[1][ s->temp[1][ i ] ]++; + s->stats[0][ s->temp[0][2*i+1] ]++; + s->stats[2][ s->temp[2][ i ] ]++; + } + } + if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) + return 0; + if(s->context){ + for(i=0; istats[0][ s->temp[0][2*i ] ]++; + put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); + s->stats[1][ s->temp[1][ i ] ]++; + put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]); + s->stats[0][ s->temp[0][2*i+1] ]++; + put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]); + s->stats[2][ s->temp[2][ i ] ]++; + put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]); + } + }else{ + for(i=0; ipb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); + put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]); + put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]); + put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]); + } + } + return 0; +} + +static int encode_gray_bitstream(HYuvContext *s, int count){ + int i; + + if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*count){ + av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); + return -1; + } + + count/=2; + if(s->flags&CODEC_FLAG_PASS1){ + for(i=0; istats[0][ s->temp[0][2*i ] ]++; + s->stats[0][ s->temp[0][2*i+1] ]++; + } + } + if(s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT) + return 0; + + if(s->context){ + for(i=0; istats[0][ s->temp[0][2*i ] ]++; + put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); + s->stats[0][ s->temp[0][2*i+1] ]++; + put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]); + } + }else{ + for(i=0; ipb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]); + put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]); + } + } + return 0; +} + +static void decode_bgr_bitstream(HYuvContext *s, int count){ + int i; + + if(s->decorrelate){ + if(s->bitstream_bpp==24){ + for(i=0; itemp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); + s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G]; + s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+G]; + } + }else{ + for(i=0; itemp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); + s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G]; + s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+G]; + get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?! + } + } + }else{ + if(s->bitstream_bpp==24){ + for(i=0; itemp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); + s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); + } + }else{ + for(i=0; itemp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); + s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); + get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?! + } + } + } +} + +static void draw_slice(HYuvContext *s, int y){ + int h, cy; + int offset[4]; + + if(s->avctx->draw_horiz_band==NULL) + return; + + h= y - s->last_slice_end; + y -= h; + + if(s->bitstream_bpp==12){ + cy= y>>1; + }else{ + cy= y; + } + + offset[0] = s->picture.linesize[0]*y; + offset[1] = s->picture.linesize[1]*cy; + offset[2] = s->picture.linesize[2]*cy; + offset[3] = 0; + emms_c(); + + s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h); + + s->last_slice_end= y + h; +} + +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){ + HYuvContext *s = avctx->priv_data; + const int width= s->width; + const int width2= s->width>>1; + const int height= s->height; + int fake_ystride, fake_ustride, fake_vstride; + AVFrame * const p= &s->picture; + int table_size= 0; + + AVFrame *picture = data; + + s->bitstream_buffer= av_fast_realloc(s->bitstream_buffer, &s->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + + s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4); + + if(p->data[0]) + avctx->release_buffer(avctx, p); + + p->reference= 0; + if(avctx->get_buffer(avctx, p) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + if(s->context){ + table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size); + if(table_size < 0) + return -1; + } + + if((unsigned)(buf_size-table_size) >= INT_MAX/8) + return -1; + + init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size)*8); + + fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0]; + fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1]; + fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2]; + + s->last_slice_end= 0; + + if(s->bitstream_bpp<24){ + int y, cy; + int lefty, leftu, leftv; + int lefttopy, lefttopu, lefttopv; + + if(s->yuy2){ + p->data[0][3]= get_bits(&s->gb, 8); + p->data[0][2]= get_bits(&s->gb, 8); + p->data[0][1]= get_bits(&s->gb, 8); + p->data[0][0]= get_bits(&s->gb, 8); + + av_log(avctx, AV_LOG_ERROR, "YUY2 output is not implemented yet\n"); + return -1; + }else{ + + leftv= p->data[2][0]= get_bits(&s->gb, 8); + lefty= p->data[0][1]= get_bits(&s->gb, 8); + leftu= p->data[1][0]= get_bits(&s->gb, 8); + p->data[0][0]= get_bits(&s->gb, 8); + + switch(s->predictor){ + case LEFT: + case PLANE: + decode_422_bitstream(s, width-2); + lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); + if(!(s->flags&CODEC_FLAG_GRAY)){ + leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); + leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); + } + + for(cy=y=1; yheight; y++,cy++){ + uint8_t *ydst, *udst, *vdst; + + if(s->bitstream_bpp==12){ + decode_gray_bitstream(s, width); + + ydst= p->data[0] + p->linesize[0]*y; + + lefty= add_left_prediction(ydst, s->temp[0], width, lefty); + if(s->predictor == PLANE){ + if(y>s->interlaced) + s->dsp.add_bytes(ydst, ydst - fake_ystride, width); + } + y++; + if(y>=s->height) break; + } + + draw_slice(s, y); + + ydst= p->data[0] + p->linesize[0]*y; + udst= p->data[1] + p->linesize[1]*cy; + vdst= p->data[2] + p->linesize[2]*cy; + + decode_422_bitstream(s, width); + lefty= add_left_prediction(ydst, s->temp[0], width, lefty); + if(!(s->flags&CODEC_FLAG_GRAY)){ + leftu= add_left_prediction(udst, s->temp[1], width2, leftu); + leftv= add_left_prediction(vdst, s->temp[2], width2, leftv); + } + if(s->predictor == PLANE){ + if(cy>s->interlaced){ + s->dsp.add_bytes(ydst, ydst - fake_ystride, width); + if(!(s->flags&CODEC_FLAG_GRAY)){ + s->dsp.add_bytes(udst, udst - fake_ustride, width2); + s->dsp.add_bytes(vdst, vdst - fake_vstride, width2); + } + } + } + } + draw_slice(s, height); + + break; + case MEDIAN: + /* first line except first 2 pixels is left predicted */ + decode_422_bitstream(s, width-2); + lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); + if(!(s->flags&CODEC_FLAG_GRAY)){ + leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); + leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); + } + + cy=y=1; + + /* second line is left predicted for interlaced case */ + if(s->interlaced){ + decode_422_bitstream(s, width); + lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty); + if(!(s->flags&CODEC_FLAG_GRAY)){ + leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); + leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); + } + y++; cy++; + } + + /* next 4 pixels are left predicted too */ + decode_422_bitstream(s, 4); + lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty); + if(!(s->flags&CODEC_FLAG_GRAY)){ + leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu); + leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv); + } + + /* next line except the first 4 pixels is median predicted */ + lefttopy= p->data[0][3]; + decode_422_bitstream(s, width-4); + add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy); + if(!(s->flags&CODEC_FLAG_GRAY)){ + lefttopu= p->data[1][1]; + lefttopv= p->data[2][1]; + add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); + add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); + } + y++; cy++; + + for(; ybitstream_bpp==12){ + while(2*cy > y){ + decode_gray_bitstream(s, width); + ydst= p->data[0] + p->linesize[0]*y; + add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); + y++; + } + if(y>=height) break; + } + draw_slice(s, y); + + decode_422_bitstream(s, width); + + ydst= p->data[0] + p->linesize[0]*y; + udst= p->data[1] + p->linesize[1]*cy; + vdst= p->data[2] + p->linesize[2]*cy; + + add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); + if(!(s->flags&CODEC_FLAG_GRAY)){ + add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu); + add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv); + } + } + + draw_slice(s, height); + break; + } + } + }else{ + int y; + int leftr, leftg, leftb; + const int last_line= (height-1)*p->linesize[0]; + + if(s->bitstream_bpp==32){ + skip_bits(&s->gb, 8); + leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8); + leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8); + leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8); + }else{ + leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8); + leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8); + leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8); + skip_bits(&s->gb, 8); + } + + if(s->bgr32){ + switch(s->predictor){ + case LEFT: + case PLANE: + decode_bgr_bitstream(s, width-1); + add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb); + + for(y=s->height-2; y>=0; y--){ //yes its stored upside down + decode_bgr_bitstream(s, width); + + add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb); + if(s->predictor == PLANE){ + if((y&s->interlaced)==0 && yheight-1-s->interlaced){ + s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, + p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride); + } + } + } + draw_slice(s, height); // just 1 large slice as this is not possible in reverse order + break; + default: + av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n"); + } + }else{ + + av_log(avctx, AV_LOG_ERROR, "BGR24 output is not implemented yet\n"); + return -1; + } + } + emms_c(); + + *picture= *p; + *data_size = sizeof(AVFrame); + + return (get_bits_count(&s->gb)+31)/32*4 + table_size; +} + +static int common_end(HYuvContext *s){ + int i; + + for(i=0; i<3; i++){ + av_freep(&s->temp[i]); + } + return 0; +} + +static int decode_end(AVCodecContext *avctx) +{ + HYuvContext *s = avctx->priv_data; + int i; + + common_end(s); + av_freep(&s->bitstream_buffer); + + for(i=0; i<3; i++){ + free_vlc(&s->vlc[i]); + } + + return 0; +} + +static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + HYuvContext *s = avctx->priv_data; + AVFrame *pict = data; + const int width= s->width; + const int width2= s->width>>1; + const int height= s->height; + const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0]; + const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1]; + const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2]; + AVFrame * const p= &s->picture; + int i, j, size=0; + + *p = *pict; + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + + if(s->context){ + for(i=0; i<3; i++){ + generate_len_table(s->len[i], s->stats[i], 256); + if(generate_bits_table(s->bits[i], s->len[i])<0) + return -1; + size+= store_table(s, s->len[i], &buf[size]); + } + + for(i=0; i<3; i++) + for(j=0; j<256; j++) + s->stats[i][j] >>= 1; + } + + init_put_bits(&s->pb, buf+size, buf_size-size); + + if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){ + int lefty, leftu, leftv, y, cy; + + put_bits(&s->pb, 8, leftv= p->data[2][0]); + put_bits(&s->pb, 8, lefty= p->data[0][1]); + put_bits(&s->pb, 8, leftu= p->data[1][0]); + put_bits(&s->pb, 8, p->data[0][0]); + + lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty); + leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu); + leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv); + + encode_422_bitstream(s, width-2); + + if(s->predictor==MEDIAN){ + int lefttopy, lefttopu, lefttopv; + cy=y=1; + if(s->interlaced){ + lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty); + leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu); + leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv); + + encode_422_bitstream(s, width); + y++; cy++; + } + + lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty); + leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ustride, 2, leftu); + leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_vstride, 2, leftv); + + encode_422_bitstream(s, 4); + + lefttopy= p->data[0][3]; + lefttopu= p->data[1][1]; + lefttopv= p->data[2][1]; + s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy); + s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu); + s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv); + encode_422_bitstream(s, width-4); + y++; cy++; + + for(; ybitstream_bpp==12){ + while(2*cy > y){ + ydst= p->data[0] + p->linesize[0]*y; + s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); + encode_gray_bitstream(s, width); + y++; + } + if(y>=height) break; + } + ydst= p->data[0] + p->linesize[0]*y; + udst= p->data[1] + p->linesize[1]*cy; + vdst= p->data[2] + p->linesize[2]*cy; + + s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); + s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu); + s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv); + + encode_422_bitstream(s, width); + } + }else{ + for(cy=y=1; ybitstream_bpp==12){ + ydst= p->data[0] + p->linesize[0]*y; + + if(s->predictor == PLANE && s->interlaced < y){ + s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); + + lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty); + }else{ + lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty); + } + encode_gray_bitstream(s, width); + y++; + if(y>=height) break; + } + + ydst= p->data[0] + p->linesize[0]*y; + udst= p->data[1] + p->linesize[1]*cy; + vdst= p->data[2] + p->linesize[2]*cy; + + if(s->predictor == PLANE && s->interlaced < cy){ + s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); + s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2); + s->dsp.diff_bytes(s->temp[2] + width2, vdst, vdst - fake_vstride, width2); + + lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty); + leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu); + leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + width2, width2, leftv); + }else{ + lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty); + leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu); + leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv); + } + + encode_422_bitstream(s, width); + } + } + }else{ + av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); + } + emms_c(); + + size+= (put_bits_count(&s->pb)+31)/8; + size/= 4; + + if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){ + int j; + char *p= avctx->stats_out; + char *end= p + 1024*30; + for(i=0; i<3; i++){ + for(j=0; j<256; j++){ + snprintf(p, end-p, "%"PRIu64" ", s->stats[i][j]); + p+= strlen(p); + s->stats[i][j]= 0; + } + snprintf(p, end-p, "\n"); + p++; + } + } + if(!(s->avctx->flags2 & CODEC_FLAG2_NO_OUTPUT)){ + flush_put_bits(&s->pb); + s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); + avctx->stats_out[0] = '\0'; + } + + s->picture_number++; + + return size*4; +} + +static int encode_end(AVCodecContext *avctx) +{ + HYuvContext *s = avctx->priv_data; + + common_end(s); + + av_freep(&avctx->extradata); + av_freep(&avctx->stats_out); + + return 0; +} + +AVCodec huffyuv_decoder = { + "huffyuv", + CODEC_TYPE_VIDEO, + CODEC_ID_HUFFYUV, + sizeof(HYuvContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, + NULL +}; + +AVCodec ffvhuff_decoder = { + "ffvhuff", + CODEC_TYPE_VIDEO, + CODEC_ID_FFVHUFF, + sizeof(HYuvContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, + NULL +}; + +#ifdef CONFIG_ENCODERS + +AVCodec huffyuv_encoder = { + "huffyuv", + CODEC_TYPE_VIDEO, + CODEC_ID_HUFFYUV, + sizeof(HYuvContext), + encode_init, + encode_frame, + encode_end, +}; + +AVCodec ffvhuff_encoder = { + "ffvhuff", + CODEC_TYPE_VIDEO, + CODEC_ID_FFVHUFF, + sizeof(HYuvContext), + encode_init, + encode_frame, + encode_end, +}; + +#endif //CONFIG_ENCODERS diff --git a/mpeg4/src/libavcodec/i386/cputest.c b/mpeg4/src/libavcodec/i386/cputest.c new file mode 100644 index 00000000..64656c65 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/cputest.c @@ -0,0 +1,131 @@ +/* Cpu detection code, extracted from mmx.h ((c)1997-99 by H. Dietz + and R. Fisher). Converted to C and improved by Fabrice Bellard */ + +#include +#include "../dsputil.h" + +#ifdef ARCH_X86_64 +# define REG_b "rbx" +# define REG_S "rsi" +#else +# define REG_b "ebx" +# define REG_S "esi" +#endif + +/* ebx saving is necessary for PIC. gcc seems unable to see it alone */ +#define cpuid(index,eax,ebx,ecx,edx)\ + __asm __volatile\ + ("mov %%"REG_b", %%"REG_S"\n\t"\ + "cpuid\n\t"\ + "xchg %%"REG_b", %%"REG_S\ + : "=a" (eax), "=S" (ebx),\ + "=c" (ecx), "=d" (edx)\ + : "0" (index)); + +/* Function to test if multimedia instructions are supported... */ +int mm_support(void) +{ + int rval = 0; + int eax, ebx, ecx, edx; + int max_std_level, max_ext_level, std_caps=0, ext_caps=0; + long a, c; + + __asm__ __volatile__ ( + /* See if CPUID instruction is supported ... */ + /* ... Get copies of EFLAGS into eax and ecx */ + "pushf\n\t" + "pop %0\n\t" + "mov %0, %1\n\t" + + /* ... Toggle the ID bit in one copy and store */ + /* to the EFLAGS reg */ + "xor $0x200000, %0\n\t" + "push %0\n\t" + "popf\n\t" + + /* ... Get the (hopefully modified) EFLAGS */ + "pushf\n\t" + "pop %0\n\t" + : "=a" (a), "=c" (c) + : + : "cc" + ); + + if (a == c) + return 0; /* CPUID not supported */ + + cpuid(0, max_std_level, ebx, ecx, edx); + + if(max_std_level >= 1){ + cpuid(1, eax, ebx, ecx, std_caps); + if (std_caps & (1<<23)) + rval |= MM_MMX; + if (std_caps & (1<<25)) + rval |= MM_MMXEXT | MM_SSE; + if (std_caps & (1<<26)) + rval |= MM_SSE2; + } + + cpuid(0x80000000, max_ext_level, ebx, ecx, edx); + + if(max_ext_level >= 0x80000001){ + cpuid(0x80000001, eax, ebx, ecx, ext_caps); + if (ext_caps & (1<<31)) + rval |= MM_3DNOW; + if (ext_caps & (1<<30)) + rval |= MM_3DNOWEXT; + if (ext_caps & (1<<23)) + rval |= MM_MMX; + } + + cpuid(0, eax, ebx, ecx, edx); + if ( ebx == 0x68747541 && + edx == 0x69746e65 && + ecx == 0x444d4163) { + /* AMD */ + if(ext_caps & (1<<22)) + rval |= MM_MMXEXT; + } else if (ebx == 0x746e6543 && + edx == 0x48727561 && + ecx == 0x736c7561) { /* "CentaurHauls" */ + /* VIA C3 */ + if(ext_caps & (1<<24)) + rval |= MM_MMXEXT; + } else if (ebx == 0x69727943 && + edx == 0x736e4978 && + ecx == 0x64616574) { + /* Cyrix Section */ + /* See if extended CPUID level 80000001 is supported */ + /* The value of CPUID/80000001 for the 6x86MX is undefined + according to the Cyrix CPU Detection Guide (Preliminary + Rev. 1.01 table 1), so we'll check the value of eax for + CPUID/0 to see if standard CPUID level 2 is supported. + According to the table, the only CPU which supports level + 2 is also the only one which supports extended CPUID levels. + */ + if (eax < 2) + return rval; + if (ext_caps & (1<<24)) + rval |= MM_MMXEXT; + } +#if 0 + av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s\n", + (rval&MM_MMX) ? "MMX ":"", + (rval&MM_MMXEXT) ? "MMX2 ":"", + (rval&MM_SSE) ? "SSE ":"", + (rval&MM_SSE2) ? "SSE2 ":"", + (rval&MM_3DNOW) ? "3DNow ":"", + (rval&MM_3DNOWEXT) ? "3DNowExt ":""); +#endif + return rval; +} + +#ifdef __TEST__ +int main ( void ) +{ + int mm_flags; + mm_flags = mm_support(); + printf("mm_support = 0x%08X\n",mm_flags); + return 0; +} +#endif diff --git a/mpeg4/src/libavcodec/i386/dsputil_h264_template_mmx.c b/mpeg4/src/libavcodec/i386/dsputil_h264_template_mmx.c new file mode 100644 index 00000000..b49c880a --- /dev/null +++ b/mpeg4/src/libavcodec/i386/dsputil_h264_template_mmx.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2005 Zoltan Hidvegi , + * Loren Merritt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * MMX optimized version of (put|avg)_h264_chroma_mc8. + * H264_CHROMA_MC8_TMPL must be defined to the desired function name + * H264_CHROMA_OP must be defined to empty for put and pavgb/pavgusb for avg + * H264_CHROMA_MC8_MV0 must be defined to a (put|avg)_pixels8 function + */ +static void H264_CHROMA_MC8_TMPL(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) +{ + DECLARE_ALIGNED_8(uint64_t, AA); + DECLARE_ALIGNED_8(uint64_t, DD); + int i; + + if(y==0 && x==0) { + /* no filter needed */ + H264_CHROMA_MC8_MV0(dst, src, stride, h); + return; + } + + assert(x<8 && y<8 && x>=0 && y>=0); + + if(y==0 || x==0) + { + /* 1 dimensional filter only */ + const int dxy = x ? 1 : stride; + + asm volatile( + "movd %0, %%mm5\n\t" + "movq %1, %%mm4\n\t" + "punpcklwd %%mm5, %%mm5\n\t" + "punpckldq %%mm5, %%mm5\n\t" /* mm5 = B = x */ + "movq %%mm4, %%mm6\n\t" + "pxor %%mm7, %%mm7\n\t" + "psubw %%mm5, %%mm4\n\t" /* mm4 = A = 8-x */ + "psrlw $1, %%mm6\n\t" /* mm6 = 4 */ + :: "rm"(x+y), "m"(ff_pw_8)); + + for(i=0; i> 3 */ + "paddw %%mm6, %%mm0\n\t" + "paddw %%mm6, %%mm1\n\t" + "paddw %%mm2, %%mm0\n\t" + "paddw %%mm3, %%mm1\n\t" + "psrlw $3, %%mm0\n\t" + "psrlw $3, %%mm1\n\t" + "packuswb %%mm1, %%mm0\n\t" + H264_CHROMA_OP(%0, %%mm0) + "movq %%mm0, %0\n\t" + : "=m" (dst[0])); + + src += stride; + dst += stride; + } + return; + } + + /* general case, bilinear */ + asm volatile("movd %2, %%mm4\n\t" + "movd %3, %%mm6\n\t" + "punpcklwd %%mm4, %%mm4\n\t" + "punpcklwd %%mm6, %%mm6\n\t" + "punpckldq %%mm4, %%mm4\n\t" /* mm4 = x words */ + "punpckldq %%mm6, %%mm6\n\t" /* mm6 = y words */ + "movq %%mm4, %%mm5\n\t" + "pmullw %%mm6, %%mm4\n\t" /* mm4 = x * y */ + "psllw $3, %%mm5\n\t" + "psllw $3, %%mm6\n\t" + "movq %%mm5, %%mm7\n\t" + "paddw %%mm6, %%mm7\n\t" + "movq %%mm4, %1\n\t" /* DD = x * y */ + "psubw %%mm4, %%mm5\n\t" /* mm5 = B = 8x - xy */ + "psubw %%mm4, %%mm6\n\t" /* mm6 = C = 8y - xy */ + "paddw %4, %%mm4\n\t" + "psubw %%mm7, %%mm4\n\t" /* mm4 = A = xy - (8x+8y) + 64 */ + "pxor %%mm7, %%mm7\n\t" + "movq %%mm4, %0\n\t" + : "=m" (AA), "=m" (DD) : "rm" (x), "rm" (y), "m" (ff_pw_64)); + + asm volatile( + /* mm0 = src[0..7], mm1 = src[1..8] */ + "movq %0, %%mm0\n\t" + "movq %1, %%mm1\n\t" + : : "m" (src[0]), "m" (src[1])); + + for(i=0; i> 6 */ + "paddw %1, %%mm2\n\t" + "paddw %1, %%mm3\n\t" + "psrlw $6, %%mm2\n\t" + "psrlw $6, %%mm3\n\t" + "packuswb %%mm3, %%mm2\n\t" + H264_CHROMA_OP(%0, %%mm2) + "movq %%mm2, %0\n\t" + : "=m" (dst[0]) : "m" (ff_pw_32)); + dst+= stride; + } +} + +static void H264_CHROMA_MC4_TMPL(uint8_t *dst/*align 4*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) +{ + DECLARE_ALIGNED_8(uint64_t, AA); + DECLARE_ALIGNED_8(uint64_t, DD); + int i; + + /* no special case for mv=(0,0) in 4x*, since it's much less common than in 8x*. + * could still save a few cycles, but maybe not worth the complexity. */ + + assert(x<8 && y<8 && x>=0 && y>=0); + + asm volatile("movd %2, %%mm4\n\t" + "movd %3, %%mm6\n\t" + "punpcklwd %%mm4, %%mm4\n\t" + "punpcklwd %%mm6, %%mm6\n\t" + "punpckldq %%mm4, %%mm4\n\t" /* mm4 = x words */ + "punpckldq %%mm6, %%mm6\n\t" /* mm6 = y words */ + "movq %%mm4, %%mm5\n\t" + "pmullw %%mm6, %%mm4\n\t" /* mm4 = x * y */ + "psllw $3, %%mm5\n\t" + "psllw $3, %%mm6\n\t" + "movq %%mm5, %%mm7\n\t" + "paddw %%mm6, %%mm7\n\t" + "movq %%mm4, %1\n\t" /* DD = x * y */ + "psubw %%mm4, %%mm5\n\t" /* mm5 = B = 8x - xy */ + "psubw %%mm4, %%mm6\n\t" /* mm6 = C = 8y - xy */ + "paddw %4, %%mm4\n\t" + "psubw %%mm7, %%mm4\n\t" /* mm4 = A = xy - (8x+8y) + 64 */ + "pxor %%mm7, %%mm7\n\t" + "movq %%mm4, %0\n\t" + : "=m" (AA), "=m" (DD) : "rm" (x), "rm" (y), "m" (ff_pw_64)); + + asm volatile( + /* mm0 = src[0..3], mm1 = src[1..4] */ + "movd %0, %%mm0\n\t" + "movd %1, %%mm1\n\t" + "punpcklbw %%mm7, %%mm0\n\t" + "punpcklbw %%mm7, %%mm1\n\t" + : : "m" (src[0]), "m" (src[1])); + + for(i=0; i> 6) */ + "paddw %1, %%mm2\n\t" + "psrlw $6, %%mm2\n\t" + "packuswb %%mm7, %%mm2\n\t" + H264_CHROMA_OP4(%0, %%mm2, %%mm3) + "movd %%mm2, %0\n\t" + : "=m" (dst[0]) : "m" (ff_pw_32)); + dst += stride; + } +} + +#ifdef H264_CHROMA_MC2_TMPL +static void H264_CHROMA_MC2_TMPL(uint8_t *dst/*align 2*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y) +{ + int CD=((1<<16)-1)*x*y + 8*y; + int AB=((8<<16)-8)*x + 64 - CD; + int i; + + asm volatile( + /* mm5 = {A,B,A,B} */ + /* mm6 = {C,D,C,D} */ + "movd %0, %%mm5\n\t" + "movd %1, %%mm6\n\t" + "punpckldq %%mm5, %%mm5\n\t" + "punpckldq %%mm6, %%mm6\n\t" + "pxor %%mm7, %%mm7\n\t" + :: "r"(AB), "r"(CD)); + + asm volatile( + /* mm0 = src[0,1,1,2] */ + "movd %0, %%mm0\n\t" + "punpcklbw %%mm7, %%mm0\n\t" + "pshufw $0x94, %%mm0, %%mm0\n\t" + :: "m"(src[0])); + + for(i=0; i> 6) */ + "paddw %1, %%mm1\n\t" + "psrlw $6, %%mm1\n\t" + "packssdw %%mm7, %%mm1\n\t" + "packuswb %%mm7, %%mm1\n\t" + /* writes garbage to the right of dst. + * ok because partitions are processed from left to right. */ + H264_CHROMA_OP4(%0, %%mm1, %%mm3) + "movd %%mm1, %0\n\t" + : "=m" (dst[0]) : "m" (ff_pw_32)); + dst += stride; + } +} +#endif + diff --git a/mpeg4/src/libavcodec/i386/dsputil_mmx.c b/mpeg4/src/libavcodec/i386/dsputil_mmx.c new file mode 100644 index 00000000..2bef197c --- /dev/null +++ b/mpeg4/src/libavcodec/i386/dsputil_mmx.c @@ -0,0 +1,3154 @@ +/* + * MMX optimized DSP utils + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * MMX optimization by Nick Kurshev + */ + +#include "../dsputil.h" +#include "../simple_idct.h" +#include "../mpegvideo.h" +#include "mmx.h" + +//#undef NDEBUG +//#include + +extern const uint8_t ff_h263_loop_filter_strength[32]; +extern void ff_idct_xvid_mmx(short *block); +extern void ff_idct_xvid_mmx2(short *block); + +int mm_flags; /* multimedia extension flags */ + +/* pixel operations */ +static const uint64_t mm_bone attribute_used __attribute__ ((aligned(8))) = 0x0101010101010101ULL; +static const uint64_t mm_wone attribute_used __attribute__ ((aligned(8))) = 0x0001000100010001ULL; +static const uint64_t mm_wtwo attribute_used __attribute__ ((aligned(8))) = 0x0002000200020002ULL; + +static const uint64_t ff_pw_20 attribute_used __attribute__ ((aligned(8))) = 0x0014001400140014ULL; +static const uint64_t ff_pw_3 attribute_used __attribute__ ((aligned(8))) = 0x0003000300030003ULL; +static const uint64_t ff_pw_4 attribute_used __attribute__ ((aligned(8))) = 0x0004000400040004ULL; +static const uint64_t ff_pw_5 attribute_used __attribute__ ((aligned(8))) = 0x0005000500050005ULL; +static const uint64_t ff_pw_8 attribute_used __attribute__ ((aligned(8))) = 0x0008000800080008ULL; +static const uint64_t ff_pw_16 attribute_used __attribute__ ((aligned(8))) = 0x0010001000100010ULL; +static const uint64_t ff_pw_32 attribute_used __attribute__ ((aligned(8))) = 0x0020002000200020ULL; +static const uint64_t ff_pw_64 attribute_used __attribute__ ((aligned(8))) = 0x0040004000400040ULL; +static const uint64_t ff_pw_15 attribute_used __attribute__ ((aligned(8))) = 0x000F000F000F000FULL; + +static const uint64_t ff_pb_3F attribute_used __attribute__ ((aligned(8))) = 0x3F3F3F3F3F3F3F3FULL; +static const uint64_t ff_pb_FC attribute_used __attribute__ ((aligned(8))) = 0xFCFCFCFCFCFCFCFCULL; + +#define JUMPALIGN() __asm __volatile (".balign 8"::) +#define MOVQ_ZERO(regd) __asm __volatile ("pxor %%" #regd ", %%" #regd ::) + +#define MOVQ_WONE(regd) \ + __asm __volatile ( \ + "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ + "psrlw $15, %%" #regd ::) + +#define MOVQ_BFE(regd) \ + __asm __volatile ( \ + "pcmpeqd %%" #regd ", %%" #regd " \n\t"\ + "paddb %%" #regd ", %%" #regd " \n\t" ::) + +#ifndef PIC +#define MOVQ_BONE(regd) __asm __volatile ("movq %0, %%" #regd " \n\t" ::"m"(mm_bone)) +#define MOVQ_WTWO(regd) __asm __volatile ("movq %0, %%" #regd " \n\t" ::"m"(mm_wtwo)) +#else +// for shared library it's better to use this way for accessing constants +// pcmpeqd -> -1 +#define MOVQ_BONE(regd) \ + __asm __volatile ( \ + "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ + "psrlw $15, %%" #regd " \n\t" \ + "packuswb %%" #regd ", %%" #regd " \n\t" ::) + +#define MOVQ_WTWO(regd) \ + __asm __volatile ( \ + "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ + "psrlw $15, %%" #regd " \n\t" \ + "psllw $1, %%" #regd " \n\t"::) + +#endif + +// using regr as temporary and for the output result +// first argument is unmodifed and second is trashed +// regfe is supposed to contain 0xfefefefefefefefe +#define PAVGB_MMX_NO_RND(rega, regb, regr, regfe) \ + "movq " #rega ", " #regr " \n\t"\ + "pand " #regb ", " #regr " \n\t"\ + "pxor " #rega ", " #regb " \n\t"\ + "pand " #regfe "," #regb " \n\t"\ + "psrlq $1, " #regb " \n\t"\ + "paddb " #regb ", " #regr " \n\t" + +#define PAVGB_MMX(rega, regb, regr, regfe) \ + "movq " #rega ", " #regr " \n\t"\ + "por " #regb ", " #regr " \n\t"\ + "pxor " #rega ", " #regb " \n\t"\ + "pand " #regfe "," #regb " \n\t"\ + "psrlq $1, " #regb " \n\t"\ + "psubb " #regb ", " #regr " \n\t" + +// mm6 is supposed to contain 0xfefefefefefefefe +#define PAVGBP_MMX_NO_RND(rega, regb, regr, regc, regd, regp) \ + "movq " #rega ", " #regr " \n\t"\ + "movq " #regc ", " #regp " \n\t"\ + "pand " #regb ", " #regr " \n\t"\ + "pand " #regd ", " #regp " \n\t"\ + "pxor " #rega ", " #regb " \n\t"\ + "pxor " #regc ", " #regd " \n\t"\ + "pand %%mm6, " #regb " \n\t"\ + "pand %%mm6, " #regd " \n\t"\ + "psrlq $1, " #regb " \n\t"\ + "psrlq $1, " #regd " \n\t"\ + "paddb " #regb ", " #regr " \n\t"\ + "paddb " #regd ", " #regp " \n\t" + +#define PAVGBP_MMX(rega, regb, regr, regc, regd, regp) \ + "movq " #rega ", " #regr " \n\t"\ + "movq " #regc ", " #regp " \n\t"\ + "por " #regb ", " #regr " \n\t"\ + "por " #regd ", " #regp " \n\t"\ + "pxor " #rega ", " #regb " \n\t"\ + "pxor " #regc ", " #regd " \n\t"\ + "pand %%mm6, " #regb " \n\t"\ + "pand %%mm6, " #regd " \n\t"\ + "psrlq $1, " #regd " \n\t"\ + "psrlq $1, " #regb " \n\t"\ + "psubb " #regb ", " #regr " \n\t"\ + "psubb " #regd ", " #regp " \n\t" + +/***********************************/ +/* MMX no rounding */ +#define DEF(x, y) x ## _no_rnd_ ## y ##_mmx +#define SET_RND MOVQ_WONE +#define PAVGBP(a, b, c, d, e, f) PAVGBP_MMX_NO_RND(a, b, c, d, e, f) +#define PAVGB(a, b, c, e) PAVGB_MMX_NO_RND(a, b, c, e) + +#include "dsputil_mmx_rnd.h" + +#undef DEF +#undef SET_RND +#undef PAVGBP +#undef PAVGB +/***********************************/ +/* MMX rounding */ + +#define DEF(x, y) x ## _ ## y ##_mmx +#define SET_RND MOVQ_WTWO +#define PAVGBP(a, b, c, d, e, f) PAVGBP_MMX(a, b, c, d, e, f) +#define PAVGB(a, b, c, e) PAVGB_MMX(a, b, c, e) + +#include "dsputil_mmx_rnd.h" + +#undef DEF +#undef SET_RND +#undef PAVGBP +#undef PAVGB + +/***********************************/ +/* 3Dnow specific */ + +#define DEF(x) x ## _3dnow +/* for Athlons PAVGUSB is prefered */ +#define PAVGB "pavgusb" + +#include "dsputil_mmx_avg.h" + +#undef DEF +#undef PAVGB + +/***********************************/ +/* MMX2 specific */ + +#define DEF(x) x ## _mmx2 + +/* Introduced only in MMX2 set */ +#define PAVGB "pavgb" + +#include "dsputil_mmx_avg.h" + +#undef DEF +#undef PAVGB + +/***********************************/ +/* standard MMX */ + +#ifdef CONFIG_ENCODERS +static void get_pixels_mmx(DCTELEM *block, const uint8_t *pixels, int line_size) +{ + asm volatile( + "mov $-128, %%"REG_a" \n\t" + "pxor %%mm7, %%mm7 \n\t" + ".balign 16 \n\t" + "1: \n\t" + "movq (%0), %%mm0 \n\t" + "movq (%0, %2), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "movq %%mm0, (%1, %%"REG_a") \n\t" + "movq %%mm1, 8(%1, %%"REG_a") \n\t" + "movq %%mm2, 16(%1, %%"REG_a") \n\t" + "movq %%mm3, 24(%1, %%"REG_a") \n\t" + "add %3, %0 \n\t" + "add $32, %%"REG_a" \n\t" + "js 1b \n\t" + : "+r" (pixels) + : "r" (block+64), "r" ((long)line_size), "r" ((long)line_size*2) + : "%"REG_a + ); +} + +static inline void diff_pixels_mmx(DCTELEM *block, const uint8_t *s1, const uint8_t *s2, int stride) +{ + asm volatile( + "pxor %%mm7, %%mm7 \n\t" + "mov $-128, %%"REG_a" \n\t" + ".balign 16 \n\t" + "1: \n\t" + "movq (%0), %%mm0 \n\t" + "movq (%1), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "movq %%mm0, (%2, %%"REG_a") \n\t" + "movq %%mm1, 8(%2, %%"REG_a") \n\t" + "add %3, %0 \n\t" + "add %3, %1 \n\t" + "add $16, %%"REG_a" \n\t" + "jnz 1b \n\t" + : "+r" (s1), "+r" (s2) + : "r" (block+64), "r" ((long)stride) + : "%"REG_a + ); +} +#endif //CONFIG_ENCODERS + +void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size) +{ + const DCTELEM *p; + uint8_t *pix; + + /* read the pixels */ + p = block; + pix = pixels; + /* unrolled loop */ + __asm __volatile( + "movq %3, %%mm0 \n\t" + "movq 8%3, %%mm1 \n\t" + "movq 16%3, %%mm2 \n\t" + "movq 24%3, %%mm3 \n\t" + "movq 32%3, %%mm4 \n\t" + "movq 40%3, %%mm5 \n\t" + "movq 48%3, %%mm6 \n\t" + "movq 56%3, %%mm7 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "packuswb %%mm3, %%mm2 \n\t" + "packuswb %%mm5, %%mm4 \n\t" + "packuswb %%mm7, %%mm6 \n\t" + "movq %%mm0, (%0) \n\t" + "movq %%mm2, (%0, %1) \n\t" + "movq %%mm4, (%0, %1, 2) \n\t" + "movq %%mm6, (%0, %2) \n\t" + ::"r" (pix), "r" ((long)line_size), "r" ((long)line_size*3), "m"(*p) + :"memory"); + pix += line_size*4; + p += 32; + + // if here would be an exact copy of the code above + // compiler would generate some very strange code + // thus using "r" + __asm __volatile( + "movq (%3), %%mm0 \n\t" + "movq 8(%3), %%mm1 \n\t" + "movq 16(%3), %%mm2 \n\t" + "movq 24(%3), %%mm3 \n\t" + "movq 32(%3), %%mm4 \n\t" + "movq 40(%3), %%mm5 \n\t" + "movq 48(%3), %%mm6 \n\t" + "movq 56(%3), %%mm7 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "packuswb %%mm3, %%mm2 \n\t" + "packuswb %%mm5, %%mm4 \n\t" + "packuswb %%mm7, %%mm6 \n\t" + "movq %%mm0, (%0) \n\t" + "movq %%mm2, (%0, %1) \n\t" + "movq %%mm4, (%0, %1, 2) \n\t" + "movq %%mm6, (%0, %2) \n\t" + ::"r" (pix), "r" ((long)line_size), "r" ((long)line_size*3), "r"(p) + :"memory"); +} + +static DECLARE_ALIGNED_8(const unsigned char, vector128[8]) = + { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; + +void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size) +{ + int i; + + movq_m2r(*vector128, mm1); + for (i = 0; i < 8; i++) { + movq_m2r(*(block), mm0); + packsswb_m2r(*(block + 4), mm0); + block += 8; + paddb_r2r(mm1, mm0); + movq_r2m(mm0, *pixels); + pixels += line_size; + } +} + +void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size) +{ + const DCTELEM *p; + uint8_t *pix; + int i; + + /* read the pixels */ + p = block; + pix = pixels; + MOVQ_ZERO(mm7); + i = 4; + do { + __asm __volatile( + "movq (%2), %%mm0 \n\t" + "movq 8(%2), %%mm1 \n\t" + "movq 16(%2), %%mm2 \n\t" + "movq 24(%2), %%mm3 \n\t" + "movq %0, %%mm4 \n\t" + "movq %1, %%mm6 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddsw %%mm4, %%mm0 \n\t" + "paddsw %%mm5, %%mm1 \n\t" + "movq %%mm6, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm6 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddsw %%mm6, %%mm2 \n\t" + "paddsw %%mm5, %%mm3 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "packuswb %%mm3, %%mm2 \n\t" + "movq %%mm0, %0 \n\t" + "movq %%mm2, %1 \n\t" + :"+m"(*pix), "+m"(*(pix+line_size)) + :"r"(p) + :"memory"); + pix += line_size*2; + p += 16; + } while (--i); +} + +static void put_pixels4_mmx(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movd (%1), %%mm0 \n\t" + "movd (%1, %3), %%mm1 \n\t" + "movd %%mm0, (%2) \n\t" + "movd %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "movd (%1), %%mm0 \n\t" + "movd (%1, %3), %%mm1 \n\t" + "movd %%mm0, (%2) \n\t" + "movd %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + : "+g"(h), "+r" (pixels), "+r" (block) + : "r"((long)line_size) + : "%"REG_a, "memory" + ); +} + +static void put_pixels8_mmx(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + : "+g"(h), "+r" (pixels), "+r" (block) + : "r"((long)line_size) + : "%"REG_a, "memory" + ); +} + +static void put_pixels16_mmx(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm4 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq 8(%1, %3), %%mm5 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm4, 8(%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm4 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq 8(%1, %3), %%mm5 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm4, 8(%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + : "+g"(h), "+r" (pixels), "+r" (block) + : "r"((long)line_size) + : "%"REG_a, "memory" + ); +} + +static void clear_blocks_mmx(DCTELEM *blocks) +{ + __asm __volatile( + "pxor %%mm7, %%mm7 \n\t" + "mov $-128*6, %%"REG_a" \n\t" + "1: \n\t" + "movq %%mm7, (%0, %%"REG_a") \n\t" + "movq %%mm7, 8(%0, %%"REG_a") \n\t" + "movq %%mm7, 16(%0, %%"REG_a") \n\t" + "movq %%mm7, 24(%0, %%"REG_a") \n\t" + "add $32, %%"REG_a" \n\t" + " js 1b \n\t" + : : "r" (((uint8_t *)blocks)+128*6) + : "%"REG_a + ); +} + +#ifdef CONFIG_ENCODERS +static int pix_sum16_mmx(uint8_t * pix, int line_size){ + const int h=16; + int sum; + long index= -line_size*h; + + __asm __volatile( + "pxor %%mm7, %%mm7 \n\t" + "pxor %%mm6, %%mm6 \n\t" + "1: \n\t" + "movq (%2, %1), %%mm0 \n\t" + "movq (%2, %1), %%mm1 \n\t" + "movq 8(%2, %1), %%mm2 \n\t" + "movq 8(%2, %1), %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddw %%mm0, %%mm1 \n\t" + "paddw %%mm2, %%mm3 \n\t" + "paddw %%mm1, %%mm3 \n\t" + "paddw %%mm3, %%mm6 \n\t" + "add %3, %1 \n\t" + " js 1b \n\t" + "movq %%mm6, %%mm5 \n\t" + "psrlq $32, %%mm6 \n\t" + "paddw %%mm5, %%mm6 \n\t" + "movq %%mm6, %%mm5 \n\t" + "psrlq $16, %%mm6 \n\t" + "paddw %%mm5, %%mm6 \n\t" + "movd %%mm6, %0 \n\t" + "andl $0xFFFF, %0 \n\t" + : "=&r" (sum), "+r" (index) + : "r" (pix - index), "r" ((long)line_size) + ); + + return sum; +} +#endif //CONFIG_ENCODERS + +static void add_bytes_mmx(uint8_t *dst, uint8_t *src, int w){ + long i=0; + asm volatile( + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq (%2, %0), %%mm1 \n\t" + "paddb %%mm0, %%mm1 \n\t" + "movq %%mm1, (%2, %0) \n\t" + "movq 8(%1, %0), %%mm0 \n\t" + "movq 8(%2, %0), %%mm1 \n\t" + "paddb %%mm0, %%mm1 \n\t" + "movq %%mm1, 8(%2, %0) \n\t" + "add $16, %0 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (i) + : "r"(src), "r"(dst), "r"((long)w-15) + ); + for(; idsp.sse[0](c, pix1, pix2, line_size, h); + else score1 = sse16_mmx(c, pix1, pix2, line_size, h); + score2= hf_noise16_mmx(pix1, line_size, h) - hf_noise16_mmx(pix2, line_size, h); + + if(c) return score1 + ABS(score2)*c->avctx->nsse_weight; + else return score1 + ABS(score2)*8; +} + +static int nsse8_mmx(void *p, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + MpegEncContext *c = p; + int score1= sse8_mmx(c, pix1, pix2, line_size, h); + int score2= hf_noise8_mmx(pix1, line_size, h) - hf_noise8_mmx(pix2, line_size, h); + + if(c) return score1 + ABS(score2)*c->avctx->nsse_weight; + else return score1 + ABS(score2)*8; +} + +static int vsad_intra16_mmx(void *v, uint8_t * pix, uint8_t * dummy, int line_size, int h) { + int tmp; + + assert( (((int)pix) & 7) == 0); + assert((line_size &7) ==0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0), %%mm2\n"\ + "movq 8(%0), %%mm3\n"\ + "add %2,%0\n"\ + "movq %%mm2, " #out0 "\n"\ + "movq %%mm3, " #out1 "\n"\ + "psubusb " #in0 ", %%mm2\n"\ + "psubusb " #in1 ", %%mm3\n"\ + "psubusb " #out0 ", " #in0 "\n"\ + "psubusb " #out1 ", " #in1 "\n"\ + "por %%mm2, " #in0 "\n"\ + "por %%mm3, " #in1 "\n"\ + "movq " #in0 ", %%mm2\n"\ + "movq " #in1 ", %%mm3\n"\ + "punpcklbw %%mm7, " #in0 "\n"\ + "punpcklbw %%mm7, " #in1 "\n"\ + "punpckhbw %%mm7, %%mm2\n"\ + "punpckhbw %%mm7, %%mm3\n"\ + "paddw " #in1 ", " #in0 "\n"\ + "paddw %%mm3, %%mm2\n"\ + "paddw %%mm2, " #in0 "\n"\ + "paddw " #in0 ", %%mm6\n" + + + asm volatile ( + "movl %3,%%ecx\n" + "pxor %%mm6,%%mm6\n" + "pxor %%mm7,%%mm7\n" + "movq (%0),%%mm0\n" + "movq 8(%0),%%mm1\n" + "add %2,%0\n" + "subl $2, %%ecx\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movq %%mm6,%%mm0\n" + "psrlq $32, %%mm6\n" + "paddw %%mm6,%%mm0\n" + "movq %%mm0,%%mm6\n" + "psrlq $16, %%mm0\n" + "paddw %%mm6,%%mm0\n" + "movd %%mm0,%1\n" + : "+r" (pix), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp & 0xFFFF; +} +#undef SUM + +static int vsad_intra16_mmx2(void *v, uint8_t * pix, uint8_t * dummy, int line_size, int h) { + int tmp; + + assert( (((int)pix) & 7) == 0); + assert((line_size &7) ==0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0), " #out0 "\n"\ + "movq 8(%0), " #out1 "\n"\ + "add %2,%0\n"\ + "psadbw " #out0 ", " #in0 "\n"\ + "psadbw " #out1 ", " #in1 "\n"\ + "paddw " #in1 ", " #in0 "\n"\ + "paddw " #in0 ", %%mm6\n" + + asm volatile ( + "movl %3,%%ecx\n" + "pxor %%mm6,%%mm6\n" + "pxor %%mm7,%%mm7\n" + "movq (%0),%%mm0\n" + "movq 8(%0),%%mm1\n" + "add %2,%0\n" + "subl $2, %%ecx\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movd %%mm6,%1\n" + : "+r" (pix), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp; +} +#undef SUM + +static int vsad16_mmx(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + int tmp; + + assert( (((int)pix1) & 7) == 0); + assert( (((int)pix2) & 7) == 0); + assert((line_size &7) ==0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0),%%mm2\n"\ + "movq (%1)," #out0 "\n"\ + "movq 8(%0),%%mm3\n"\ + "movq 8(%1)," #out1 "\n"\ + "add %3,%0\n"\ + "add %3,%1\n"\ + "psubb " #out0 ", %%mm2\n"\ + "psubb " #out1 ", %%mm3\n"\ + "pxor %%mm7, %%mm2\n"\ + "pxor %%mm7, %%mm3\n"\ + "movq %%mm2, " #out0 "\n"\ + "movq %%mm3, " #out1 "\n"\ + "psubusb " #in0 ", %%mm2\n"\ + "psubusb " #in1 ", %%mm3\n"\ + "psubusb " #out0 ", " #in0 "\n"\ + "psubusb " #out1 ", " #in1 "\n"\ + "por %%mm2, " #in0 "\n"\ + "por %%mm3, " #in1 "\n"\ + "movq " #in0 ", %%mm2\n"\ + "movq " #in1 ", %%mm3\n"\ + "punpcklbw %%mm7, " #in0 "\n"\ + "punpcklbw %%mm7, " #in1 "\n"\ + "punpckhbw %%mm7, %%mm2\n"\ + "punpckhbw %%mm7, %%mm3\n"\ + "paddw " #in1 ", " #in0 "\n"\ + "paddw %%mm3, %%mm2\n"\ + "paddw %%mm2, " #in0 "\n"\ + "paddw " #in0 ", %%mm6\n" + + + asm volatile ( + "movl %4,%%ecx\n" + "pxor %%mm6,%%mm6\n" + "pcmpeqw %%mm7,%%mm7\n" + "psllw $15, %%mm7\n" + "packsswb %%mm7, %%mm7\n" + "movq (%0),%%mm0\n" + "movq (%1),%%mm2\n" + "movq 8(%0),%%mm1\n" + "movq 8(%1),%%mm3\n" + "add %3,%0\n" + "add %3,%1\n" + "subl $2, %%ecx\n" + "psubb %%mm2, %%mm0\n" + "psubb %%mm3, %%mm1\n" + "pxor %%mm7, %%mm0\n" + "pxor %%mm7, %%mm1\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movq %%mm6,%%mm0\n" + "psrlq $32, %%mm6\n" + "paddw %%mm6,%%mm0\n" + "movq %%mm0,%%mm6\n" + "psrlq $16, %%mm0\n" + "paddw %%mm6,%%mm0\n" + "movd %%mm0,%2\n" + : "+r" (pix1), "+r" (pix2), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp & 0x7FFF; +} +#undef SUM + +static int vsad16_mmx2(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, int h) { + int tmp; + + assert( (((int)pix1) & 7) == 0); + assert( (((int)pix2) & 7) == 0); + assert((line_size &7) ==0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0)," #out0 "\n"\ + "movq (%1),%%mm2\n"\ + "movq 8(%0)," #out1 "\n"\ + "movq 8(%1),%%mm3\n"\ + "add %3,%0\n"\ + "add %3,%1\n"\ + "psubb %%mm2, " #out0 "\n"\ + "psubb %%mm3, " #out1 "\n"\ + "pxor %%mm7, " #out0 "\n"\ + "pxor %%mm7, " #out1 "\n"\ + "psadbw " #out0 ", " #in0 "\n"\ + "psadbw " #out1 ", " #in1 "\n"\ + "paddw " #in1 ", " #in0 "\n"\ + "paddw " #in0 ", %%mm6\n" + + asm volatile ( + "movl %4,%%ecx\n" + "pxor %%mm6,%%mm6\n" + "pcmpeqw %%mm7,%%mm7\n" + "psllw $15, %%mm7\n" + "packsswb %%mm7, %%mm7\n" + "movq (%0),%%mm0\n" + "movq (%1),%%mm2\n" + "movq 8(%0),%%mm1\n" + "movq 8(%1),%%mm3\n" + "add %3,%0\n" + "add %3,%1\n" + "subl $2, %%ecx\n" + "psubb %%mm2, %%mm0\n" + "psubb %%mm3, %%mm1\n" + "pxor %%mm7, %%mm0\n" + "pxor %%mm7, %%mm1\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movd %%mm6,%2\n" + : "+r" (pix1), "+r" (pix2), "=r"(tmp) + : "r" ((long)line_size) , "m" (h) + : "%ecx"); + return tmp; +} +#undef SUM + +static void diff_bytes_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ + long i=0; + asm volatile( + "1: \n\t" + "movq (%2, %0), %%mm0 \n\t" + "movq (%1, %0), %%mm1 \n\t" + "psubb %%mm0, %%mm1 \n\t" + "movq %%mm1, (%3, %0) \n\t" + "movq 8(%2, %0), %%mm0 \n\t" + "movq 8(%1, %0), %%mm1 \n\t" + "psubb %%mm0, %%mm1 \n\t" + "movq %%mm1, 8(%3, %0) \n\t" + "add $16, %0 \n\t" + "cmp %4, %0 \n\t" + " jb 1b \n\t" + : "+r" (i) + : "r"(src1), "r"(src2), "r"(dst), "r"((long)w-15) + ); + for(; iput_ ## postfix1 = put_ ## postfix2;\ + c->put_no_rnd_ ## postfix1 = put_no_rnd_ ## postfix2;\ + c->avg_ ## postfix1 = avg_ ## postfix2; + +static void gmc_mmx(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height){ + const int w = 8; + const int ix = ox>>(16+shift); + const int iy = oy>>(16+shift); + const int oxs = ox>>4; + const int oys = oy>>4; + const int dxxs = dxx>>4; + const int dxys = dxy>>4; + const int dyxs = dyx>>4; + const int dyys = dyy>>4; + const uint16_t r4[4] = {r,r,r,r}; + const uint16_t dxy4[4] = {dxys,dxys,dxys,dxys}; + const uint16_t dyy4[4] = {dyys,dyys,dyys,dyys}; + const uint64_t shift2 = 2*shift; + uint8_t edge_buf[(h+1)*stride]; + int x, y; + + const int dxw = (dxx-(1<<(16+shift)))*(w-1); + const int dyh = (dyy-(1<<(16+shift)))*(h-1); + const int dxh = dxy*(h-1); + const int dyw = dyx*(w-1); + if( // non-constant fullpel offset (3% of blocks) + (ox^(ox+dxw) | ox^(ox+dxh) | ox^(ox+dxw+dxh) | + oy^(oy+dyw) | oy^(oy+dyh) | oy^(oy+dyw+dyh)) >> (16+shift) + // uses more than 16 bits of subpel mv (only at huge resolution) + || (dxx|dxy|dyx|dyy)&15 ) + { + //FIXME could still use mmx for some of the rows + ff_gmc_c(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r, width, height); + return; + } + + src += ix + iy*stride; + if( (unsigned)ix >= width-w || + (unsigned)iy >= height-h ) + { + ff_emulated_edge_mc(edge_buf, src, stride, w+1, h+1, ix, iy, width, height); + src = edge_buf; + } + + asm volatile( + "movd %0, %%mm6 \n\t" + "pxor %%mm7, %%mm7 \n\t" + "punpcklwd %%mm6, %%mm6 \n\t" + "punpcklwd %%mm6, %%mm6 \n\t" + :: "r"(1<>(BASIS_SHIFT - RECON_SHIFT); + } + } +} + +#define PREFETCH(name, op) \ +void name(void *mem, int stride, int h){\ + const uint8_t *p= mem;\ + do{\ + asm volatile(#op" %0" :: "m"(*p));\ + p+= stride;\ + }while(--h);\ +} +PREFETCH(prefetch_mmx2, prefetcht0) +PREFETCH(prefetch_3dnow, prefetch) +#undef PREFETCH + +#include "h264dsp_mmx.c" + +/* external functions, from idct_mmx.c */ +void ff_mmx_idct(DCTELEM *block); +void ff_mmxext_idct(DCTELEM *block); + +void ff_vp3_idct_sse2(int16_t *input_data); +void ff_vp3_idct_mmx(int16_t *data); +void ff_vp3_dsp_init_mmx(void); + +/* XXX: those functions should be suppressed ASAP when all IDCTs are + converted */ +static void ff_libmpeg2mmx_idct_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_mmx_idct (block); + put_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_libmpeg2mmx_idct_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_mmx_idct (block); + add_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_libmpeg2mmx2_idct_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_mmxext_idct (block); + put_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_libmpeg2mmx2_idct_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_mmxext_idct (block); + add_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_vp3_idct_sse2(block); + put_signed_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_vp3_idct_sse2(block); + add_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_vp3_idct_mmx(block); + put_signed_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_vp3_idct_mmx(block); + add_pixels_clamped_mmx(block, dest, line_size); +} +#ifdef CONFIG_GPL +static void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_idct_xvid_mmx (block); + put_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_idct_xvid_mmx (block); + add_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_idct_xvid_mmx2_put(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_idct_xvid_mmx2 (block); + put_pixels_clamped_mmx(block, dest, line_size); +} +static void ff_idct_xvid_mmx2_add(uint8_t *dest, int line_size, DCTELEM *block) +{ + ff_idct_xvid_mmx2 (block); + add_pixels_clamped_mmx(block, dest, line_size); +} +#endif + +#ifdef CONFIG_SNOW_ENCODER +extern void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width); +extern void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width); +extern void ff_snow_vertical_compose97i_sse2(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width); +extern void ff_snow_vertical_compose97i_mmx(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width); +extern void ff_snow_inner_add_yblock_sse2(uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, + int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8); +extern void ff_snow_inner_add_yblock_mmx(uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, + int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8); +#endif + +void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) +{ + mm_flags = mm_support(); + + if (avctx->dsp_mask) { + if (avctx->dsp_mask & FF_MM_FORCE) + mm_flags |= (avctx->dsp_mask & 0xffff); + else + mm_flags &= ~(avctx->dsp_mask & 0xffff); + } + +#if 0 + av_log(avctx, AV_LOG_INFO, "libavcodec: CPU flags:"); + if (mm_flags & MM_MMX) + av_log(avctx, AV_LOG_INFO, " mmx"); + if (mm_flags & MM_MMXEXT) + av_log(avctx, AV_LOG_INFO, " mmxext"); + if (mm_flags & MM_3DNOW) + av_log(avctx, AV_LOG_INFO, " 3dnow"); + if (mm_flags & MM_SSE) + av_log(avctx, AV_LOG_INFO, " sse"); + if (mm_flags & MM_SSE2) + av_log(avctx, AV_LOG_INFO, " sse2"); + av_log(avctx, AV_LOG_INFO, "\n"); +#endif + + if (mm_flags & MM_MMX) { + const int idct_algo= avctx->idct_algo; + +#ifdef CONFIG_ENCODERS + const int dct_algo = avctx->dct_algo; + if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){ + if(mm_flags & MM_SSE2){ + c->fdct = ff_fdct_sse2; + }else if(mm_flags & MM_MMXEXT){ + c->fdct = ff_fdct_mmx2; + }else{ + c->fdct = ff_fdct_mmx; + } + } +#endif //CONFIG_ENCODERS + if(avctx->lowres==0){ + if(idct_algo==FF_IDCT_AUTO || idct_algo==FF_IDCT_SIMPLEMMX){ + c->idct_put= ff_simple_idct_put_mmx; + c->idct_add= ff_simple_idct_add_mmx; + c->idct = ff_simple_idct_mmx; + c->idct_permutation_type= FF_SIMPLE_IDCT_PERM; + }else if(idct_algo==FF_IDCT_LIBMPEG2MMX){ + if(mm_flags & MM_MMXEXT){ + c->idct_put= ff_libmpeg2mmx2_idct_put; + c->idct_add= ff_libmpeg2mmx2_idct_add; + c->idct = ff_mmxext_idct; + }else{ + c->idct_put= ff_libmpeg2mmx_idct_put; + c->idct_add= ff_libmpeg2mmx_idct_add; + c->idct = ff_mmx_idct; + } + c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; + }else if(idct_algo==FF_IDCT_VP3){ + if(mm_flags & MM_SSE2){ + c->idct_put= ff_vp3_idct_put_sse2; + c->idct_add= ff_vp3_idct_add_sse2; + c->idct = ff_vp3_idct_sse2; + c->idct_permutation_type= FF_TRANSPOSE_IDCT_PERM; + }else{ + ff_vp3_dsp_init_mmx(); + c->idct_put= ff_vp3_idct_put_mmx; + c->idct_add= ff_vp3_idct_add_mmx; + c->idct = ff_vp3_idct_mmx; + c->idct_permutation_type= FF_PARTTRANS_IDCT_PERM; + } +#ifdef CONFIG_GPL + }else if(idct_algo==FF_IDCT_XVIDMMX){ + if(mm_flags & MM_MMXEXT){ + c->idct_put= ff_idct_xvid_mmx2_put; + c->idct_add= ff_idct_xvid_mmx2_add; + c->idct = ff_idct_xvid_mmx2; + }else{ + c->idct_put= ff_idct_xvid_mmx_put; + c->idct_add= ff_idct_xvid_mmx_add; + c->idct = ff_idct_xvid_mmx; + } +#endif + } + } + +#ifdef CONFIG_ENCODERS + c->get_pixels = get_pixels_mmx; + c->diff_pixels = diff_pixels_mmx; +#endif //CONFIG_ENCODERS + c->put_pixels_clamped = put_pixels_clamped_mmx; + c->put_signed_pixels_clamped = put_signed_pixels_clamped_mmx; + c->add_pixels_clamped = add_pixels_clamped_mmx; + c->clear_blocks = clear_blocks_mmx; +#ifdef CONFIG_ENCODERS + c->pix_sum = pix_sum16_mmx; +#endif //CONFIG_ENCODERS + + c->put_pixels_tab[0][0] = put_pixels16_mmx; + c->put_pixels_tab[0][1] = put_pixels16_x2_mmx; + c->put_pixels_tab[0][2] = put_pixels16_y2_mmx; + c->put_pixels_tab[0][3] = put_pixels16_xy2_mmx; + + c->put_no_rnd_pixels_tab[0][0] = put_pixels16_mmx; + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmx; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmx; + c->put_no_rnd_pixels_tab[0][3] = put_no_rnd_pixels16_xy2_mmx; + + c->avg_pixels_tab[0][0] = avg_pixels16_mmx; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmx; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmx; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmx; + + c->avg_no_rnd_pixels_tab[0][0] = avg_no_rnd_pixels16_mmx; + c->avg_no_rnd_pixels_tab[0][1] = avg_no_rnd_pixels16_x2_mmx; + c->avg_no_rnd_pixels_tab[0][2] = avg_no_rnd_pixels16_y2_mmx; + c->avg_no_rnd_pixels_tab[0][3] = avg_no_rnd_pixels16_xy2_mmx; + + c->put_pixels_tab[1][0] = put_pixels8_mmx; + c->put_pixels_tab[1][1] = put_pixels8_x2_mmx; + c->put_pixels_tab[1][2] = put_pixels8_y2_mmx; + c->put_pixels_tab[1][3] = put_pixels8_xy2_mmx; + + c->put_no_rnd_pixels_tab[1][0] = put_pixels8_mmx; + c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_mmx; + c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_mmx; + c->put_no_rnd_pixels_tab[1][3] = put_no_rnd_pixels8_xy2_mmx; + + c->avg_pixels_tab[1][0] = avg_pixels8_mmx; + c->avg_pixels_tab[1][1] = avg_pixels8_x2_mmx; + c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmx; + c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mmx; + + c->avg_no_rnd_pixels_tab[1][0] = avg_no_rnd_pixels8_mmx; + c->avg_no_rnd_pixels_tab[1][1] = avg_no_rnd_pixels8_x2_mmx; + c->avg_no_rnd_pixels_tab[1][2] = avg_no_rnd_pixels8_y2_mmx; + c->avg_no_rnd_pixels_tab[1][3] = avg_no_rnd_pixels8_xy2_mmx; + + c->gmc= gmc_mmx; + + c->add_bytes= add_bytes_mmx; +#ifdef CONFIG_ENCODERS + c->diff_bytes= diff_bytes_mmx; + + c->hadamard8_diff[0]= hadamard8_diff16_mmx; + c->hadamard8_diff[1]= hadamard8_diff_mmx; + + c->pix_norm1 = pix_norm1_mmx; + c->sse[0] = (mm_flags & MM_SSE2) ? sse16_sse2 : sse16_mmx; + c->sse[1] = sse8_mmx; + c->vsad[4]= vsad_intra16_mmx; + + c->nsse[0] = nsse16_mmx; + c->nsse[1] = nsse8_mmx; + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->vsad[0] = vsad16_mmx; + } + + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->try_8x8basis= try_8x8basis_mmx; + } + c->add_8x8basis= add_8x8basis_mmx; + +#endif //CONFIG_ENCODERS + + c->h263_v_loop_filter= h263_v_loop_filter_mmx; + c->h263_h_loop_filter= h263_h_loop_filter_mmx; + c->put_h264_chroma_pixels_tab[0]= put_h264_chroma_mc8_mmx; + c->put_h264_chroma_pixels_tab[1]= put_h264_chroma_mc4_mmx; + + c->h264_idct_dc_add= + c->h264_idct_add= ff_h264_idct_add_mmx; + c->h264_idct8_dc_add= + c->h264_idct8_add= ff_h264_idct8_add_mmx; + + if (mm_flags & MM_MMXEXT) { + c->prefetch = prefetch_mmx2; + + c->put_pixels_tab[0][1] = put_pixels16_x2_mmx2; + c->put_pixels_tab[0][2] = put_pixels16_y2_mmx2; + + c->avg_pixels_tab[0][0] = avg_pixels16_mmx2; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmx2; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmx2; + + c->put_pixels_tab[1][1] = put_pixels8_x2_mmx2; + c->put_pixels_tab[1][2] = put_pixels8_y2_mmx2; + + c->avg_pixels_tab[1][0] = avg_pixels8_mmx2; + c->avg_pixels_tab[1][1] = avg_pixels8_x2_mmx2; + c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmx2; + +#ifdef CONFIG_ENCODERS + c->hadamard8_diff[0]= hadamard8_diff16_mmx2; + c->hadamard8_diff[1]= hadamard8_diff_mmx2; + c->vsad[4]= vsad_intra16_mmx2; +#endif //CONFIG_ENCODERS + + c->h264_idct_dc_add= ff_h264_idct_dc_add_mmx2; + c->h264_idct8_dc_add= ff_h264_idct8_dc_add_mmx2; + + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmx2; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmx2; + c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_mmx2; + c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_mmx2; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmx2; + c->avg_pixels_tab[1][3] = avg_pixels8_xy2_mmx2; +#ifdef CONFIG_ENCODERS + c->vsad[0] = vsad16_mmx2; +#endif //CONFIG_ENCODERS + } + +#if 1 + SET_QPEL_FUNC(qpel_pixels_tab[0][ 0], qpel16_mc00_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 1], qpel16_mc10_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 2], qpel16_mc20_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 3], qpel16_mc30_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 4], qpel16_mc01_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 6], qpel16_mc21_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 8], qpel16_mc02_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][10], qpel16_mc22_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][12], qpel16_mc03_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][14], qpel16_mc23_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 0], qpel8_mc00_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 1], qpel8_mc10_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 2], qpel8_mc20_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 3], qpel8_mc30_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 4], qpel8_mc01_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 6], qpel8_mc21_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 8], qpel8_mc02_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][10], qpel8_mc22_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][12], qpel8_mc03_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][14], qpel8_mc23_mmx2) + SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_mmx2) +#endif + +//FIXME 3dnow too +#define dspfunc(PFX, IDX, NUM) \ + c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_mmx2; \ + c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_mmx2; \ + c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_mmx2; \ + c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_mmx2; \ + c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_mmx2; \ + c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_mmx2; \ + c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_mmx2; \ + c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_mmx2; \ + c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_mmx2; \ + c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_mmx2; \ + c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_mmx2; \ + c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_mmx2; \ + c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_mmx2; \ + c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_mmx2; \ + c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_mmx2; \ + c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_mmx2 + + dspfunc(put_h264_qpel, 0, 16); + dspfunc(put_h264_qpel, 1, 8); + dspfunc(put_h264_qpel, 2, 4); + dspfunc(avg_h264_qpel, 0, 16); + dspfunc(avg_h264_qpel, 1, 8); + dspfunc(avg_h264_qpel, 2, 4); +#undef dspfunc + + c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_mmx2; + c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_mmx2; + c->avg_h264_chroma_pixels_tab[2]= avg_h264_chroma_mc2_mmx2; + c->put_h264_chroma_pixels_tab[2]= put_h264_chroma_mc2_mmx2; + c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_mmx2; + c->h264_h_loop_filter_luma= h264_h_loop_filter_luma_mmx2; + c->h264_v_loop_filter_chroma= h264_v_loop_filter_chroma_mmx2; + c->h264_h_loop_filter_chroma= h264_h_loop_filter_chroma_mmx2; + c->h264_v_loop_filter_chroma_intra= h264_v_loop_filter_chroma_intra_mmx2; + c->h264_h_loop_filter_chroma_intra= h264_h_loop_filter_chroma_intra_mmx2; + + c->weight_h264_pixels_tab[0]= ff_h264_weight_16x16_mmx2; + c->weight_h264_pixels_tab[1]= ff_h264_weight_16x8_mmx2; + c->weight_h264_pixels_tab[2]= ff_h264_weight_8x16_mmx2; + c->weight_h264_pixels_tab[3]= ff_h264_weight_8x8_mmx2; + c->weight_h264_pixels_tab[4]= ff_h264_weight_8x4_mmx2; + c->weight_h264_pixels_tab[5]= ff_h264_weight_4x8_mmx2; + c->weight_h264_pixels_tab[6]= ff_h264_weight_4x4_mmx2; + c->weight_h264_pixels_tab[7]= ff_h264_weight_4x2_mmx2; + + c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16x16_mmx2; + c->biweight_h264_pixels_tab[1]= ff_h264_biweight_16x8_mmx2; + c->biweight_h264_pixels_tab[2]= ff_h264_biweight_8x16_mmx2; + c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_mmx2; + c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_mmx2; + c->biweight_h264_pixels_tab[5]= ff_h264_biweight_4x8_mmx2; + c->biweight_h264_pixels_tab[6]= ff_h264_biweight_4x4_mmx2; + c->biweight_h264_pixels_tab[7]= ff_h264_biweight_4x2_mmx2; + +#ifdef CONFIG_ENCODERS + c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_mmx2; +#endif //CONFIG_ENCODERS + } else if (mm_flags & MM_3DNOW) { + c->prefetch = prefetch_3dnow; + + c->put_pixels_tab[0][1] = put_pixels16_x2_3dnow; + c->put_pixels_tab[0][2] = put_pixels16_y2_3dnow; + + c->avg_pixels_tab[0][0] = avg_pixels16_3dnow; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_3dnow; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_3dnow; + + c->put_pixels_tab[1][1] = put_pixels8_x2_3dnow; + c->put_pixels_tab[1][2] = put_pixels8_y2_3dnow; + + c->avg_pixels_tab[1][0] = avg_pixels8_3dnow; + c->avg_pixels_tab[1][1] = avg_pixels8_x2_3dnow; + c->avg_pixels_tab[1][2] = avg_pixels8_y2_3dnow; + + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_3dnow; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_3dnow; + c->put_no_rnd_pixels_tab[1][1] = put_no_rnd_pixels8_x2_3dnow; + c->put_no_rnd_pixels_tab[1][2] = put_no_rnd_pixels8_y2_3dnow; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_3dnow; + c->avg_pixels_tab[1][3] = avg_pixels8_xy2_3dnow; + } + + SET_QPEL_FUNC(qpel_pixels_tab[0][ 0], qpel16_mc00_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 1], qpel16_mc10_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 2], qpel16_mc20_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 3], qpel16_mc30_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 4], qpel16_mc01_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 6], qpel16_mc21_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 8], qpel16_mc02_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][10], qpel16_mc22_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][12], qpel16_mc03_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][14], qpel16_mc23_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 0], qpel8_mc00_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 1], qpel8_mc10_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 2], qpel8_mc20_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 3], qpel8_mc30_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 4], qpel8_mc01_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 6], qpel8_mc21_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 8], qpel8_mc02_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][10], qpel8_mc22_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][12], qpel8_mc03_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][14], qpel8_mc23_3dnow) + SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_3dnow) + +#define dspfunc(PFX, IDX, NUM) \ + c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_3dnow; \ + c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_3dnow; \ + c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_3dnow; \ + c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_3dnow; \ + c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_3dnow; \ + c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_3dnow; \ + c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_3dnow; \ + c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_3dnow; \ + c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_3dnow; \ + c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_3dnow; \ + c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_3dnow; \ + c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_3dnow; \ + c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_3dnow; \ + c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_3dnow; \ + c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_3dnow; \ + c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_3dnow + + dspfunc(put_h264_qpel, 0, 16); + dspfunc(put_h264_qpel, 1, 8); + dspfunc(put_h264_qpel, 2, 4); + dspfunc(avg_h264_qpel, 0, 16); + dspfunc(avg_h264_qpel, 1, 8); + dspfunc(avg_h264_qpel, 2, 4); + + c->avg_h264_chroma_pixels_tab[0]= avg_h264_chroma_mc8_3dnow; + c->avg_h264_chroma_pixels_tab[1]= avg_h264_chroma_mc4_3dnow; + } + +#ifdef CONFIG_SNOW_ENCODER + if(mm_flags & MM_SSE2){ + c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2; + c->vertical_compose97i = ff_snow_vertical_compose97i_sse2; + c->inner_add_yblock = ff_snow_inner_add_yblock_sse2; + } + else{ + c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx; + c->vertical_compose97i = ff_snow_vertical_compose97i_mmx; + c->inner_add_yblock = ff_snow_inner_add_yblock_mmx; + } +#endif + } + +#ifdef CONFIG_ENCODERS + dsputil_init_pix_mmx(c, avctx); +#endif //CONFIG_ENCODERS +#if 0 + // for speed testing + get_pixels = just_return; + put_pixels_clamped = just_return; + add_pixels_clamped = just_return; + + pix_abs16x16 = just_return; + pix_abs16x16_x2 = just_return; + pix_abs16x16_y2 = just_return; + pix_abs16x16_xy2 = just_return; + + put_pixels_tab[0] = just_return; + put_pixels_tab[1] = just_return; + put_pixels_tab[2] = just_return; + put_pixels_tab[3] = just_return; + + put_no_rnd_pixels_tab[0] = just_return; + put_no_rnd_pixels_tab[1] = just_return; + put_no_rnd_pixels_tab[2] = just_return; + put_no_rnd_pixels_tab[3] = just_return; + + avg_pixels_tab[0] = just_return; + avg_pixels_tab[1] = just_return; + avg_pixels_tab[2] = just_return; + avg_pixels_tab[3] = just_return; + + avg_no_rnd_pixels_tab[0] = just_return; + avg_no_rnd_pixels_tab[1] = just_return; + avg_no_rnd_pixels_tab[2] = just_return; + avg_no_rnd_pixels_tab[3] = just_return; + + //av_fdct = just_return; + //ff_idct = just_return; +#endif +} diff --git a/mpeg4/src/libavcodec/i386/dsputil_mmx_avg.h b/mpeg4/src/libavcodec/i386/dsputil_mmx_avg.h new file mode 100644 index 00000000..440c5bb9 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/dsputil_mmx_avg.h @@ -0,0 +1,820 @@ +/* + * DSP utils : average functions are compiled twice for 3dnow/mmx2 + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * MMX optimization by Nick Kurshev + * mostly rewritten by Michael Niedermayer + * and improved by Zdenek Kabelac + */ + +/* XXX: we use explicit registers to avoid a gcc 2.95.2 register asm + clobber bug - now it will work with 2.95.2 and also with -fPIC + */ +static void DEF(put_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm1 \n\t" + PAVGB" 1(%1), %%mm0 \n\t" + PAVGB" 1(%1, %3), %%mm1 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm1 \n\t" + PAVGB" 1(%1), %%mm0 \n\t" + PAVGB" 1(%1, %3), %%mm1 \n\t" + "add %%"REG_a", %1 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r" ((long)line_size) + :"%"REG_a, "memory"); +} + +static void DEF(put_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + __asm __volatile( + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movd (%1), %%mm0 \n\t" + "movd (%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "add $4, %2 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + "movd %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + "1: \n\t" + "movd (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movd (%1), %%mm1 \n\t" + "movd (%2), %%mm2 \n\t" + "movd 4(%2), %%mm3 \n\t" + "add %4, %1 \n\t" + PAVGB" %%mm2, %%mm0 \n\t" + PAVGB" %%mm3, %%mm1 \n\t" + "movd %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "movd %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "movd (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movd (%1), %%mm1 \n\t" + "movd 8(%2), %%mm2 \n\t" + "movd 12(%2), %%mm3 \n\t" + "add %4, %1 \n\t" + PAVGB" %%mm2, %%mm0 \n\t" + PAVGB" %%mm3, %%mm1 \n\t" + "movd %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "movd %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "add $16, %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +} + + +static void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + __asm __volatile( + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "add $8, %2 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + "movq %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movq (%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" 8(%2), %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "movq %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "movq (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movq (%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" 16(%2), %%mm0 \n\t" + PAVGB" 24(%2), %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "movq %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "add $32, %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +//the following should be used, though better not with gcc ... +/* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) + :"r"(src1Stride), "r"(dstStride) + :"memory");*/ +} + +static void DEF(put_no_rnd_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + __asm __volatile( + "pcmpeqb %%mm6, %%mm6 \n\t" + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "add $8, %2 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "movq %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movq (%1), %%mm1 \n\t" + "add %4, %1 \n\t" + "movq (%2), %%mm2 \n\t" + "movq 8(%2), %%mm3 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "pxor %%mm6, %%mm2 \n\t" + "pxor %%mm6, %%mm3 \n\t" + PAVGB" %%mm2, %%mm0 \n\t" + PAVGB" %%mm3, %%mm1 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "movq %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "movq (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movq (%1), %%mm1 \n\t" + "add %4, %1 \n\t" + "movq 16(%2), %%mm2 \n\t" + "movq 24(%2), %%mm3 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "pxor %%mm6, %%mm2 \n\t" + "pxor %%mm6, %%mm3 \n\t" + PAVGB" %%mm2, %%mm0 \n\t" + PAVGB" %%mm3, %%mm1 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "movq %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "add $32, %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +//the following should be used, though better not with gcc ... +/* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) + :"r"(src1Stride), "r"(dstStride) + :"memory");*/ +} + +static void DEF(avg_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + __asm __volatile( + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movd (%1), %%mm0 \n\t" + "movd (%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "add $4, %2 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + PAVGB" (%3), %%mm0 \n\t" + "movd %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + "1: \n\t" + "movd (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movd (%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" 4(%2), %%mm1 \n\t" + PAVGB" (%3), %%mm0 \n\t" + "movd %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + PAVGB" (%3), %%mm1 \n\t" + "movd %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "movd (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movd (%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" 8(%2), %%mm0 \n\t" + PAVGB" 12(%2), %%mm1 \n\t" + PAVGB" (%3), %%mm0 \n\t" + "movd %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + PAVGB" (%3), %%mm1 \n\t" + "movd %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "add $16, %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +} + + +static void DEF(avg_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + __asm __volatile( + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "add $8, %2 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + PAVGB" (%3), %%mm0 \n\t" + "movq %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movq (%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" 8(%2), %%mm1 \n\t" + PAVGB" (%3), %%mm0 \n\t" + "movq %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + PAVGB" (%3), %%mm1 \n\t" + "movq %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "movq (%1), %%mm0 \n\t" + "add %4, %1 \n\t" + "movq (%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" 16(%2), %%mm0 \n\t" + PAVGB" 24(%2), %%mm1 \n\t" + PAVGB" (%3), %%mm0 \n\t" + "movq %%mm0, (%3) \n\t" + "add %5, %3 \n\t" + PAVGB" (%3), %%mm1 \n\t" + "movq %%mm1, (%3) \n\t" + "add %5, %3 \n\t" + "add $32, %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +//the following should be used, though better not with gcc ... +/* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) + :"r"(src1Stride), "r"(dstStride) + :"memory");*/ +} + +static void DEF(put_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq 8(%1), %%mm2 \n\t" + "movq 8(%1, %3), %%mm3 \n\t" + PAVGB" 1(%1), %%mm0 \n\t" + PAVGB" 1(%1, %3), %%mm1 \n\t" + PAVGB" 9(%1), %%mm2 \n\t" + PAVGB" 9(%1, %3), %%mm3 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "movq %%mm2, 8(%2) \n\t" + "movq %%mm3, 8(%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq 8(%1), %%mm2 \n\t" + "movq 8(%1, %3), %%mm3 \n\t" + PAVGB" 1(%1), %%mm0 \n\t" + PAVGB" 1(%1, %3), %%mm1 \n\t" + PAVGB" 9(%1), %%mm2 \n\t" + PAVGB" 9(%1, %3), %%mm3 \n\t" + "add %%"REG_a", %1 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "movq %%mm2, 8(%2) \n\t" + "movq %%mm3, 8(%2, %3) \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r" ((long)line_size) + :"%"REG_a, "memory"); +} + +static void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + __asm __volatile( + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm1 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" 8(%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "add $16, %2 \n\t" + "movq %%mm0, (%3) \n\t" + "movq %%mm1, 8(%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" 8(%2), %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "movq %%mm1, 8(%3) \n\t" + "add %5, %3 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" 16(%2), %%mm0 \n\t" + PAVGB" 24(%2), %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "movq %%mm1, 8(%3) \n\t" + "add %5, %3 \n\t" + "add $32, %2 \n\t" + "subl $2, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +//the following should be used, though better not with gcc ... +/* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) + :"r"(src1Stride), "r"(dstStride) + :"memory");*/ +} + +static void DEF(avg_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + __asm __volatile( + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm1 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" 8(%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "add $16, %2 \n\t" + PAVGB" (%3), %%mm0 \n\t" + PAVGB" 8(%3), %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "movq %%mm1, 8(%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" 8(%2), %%mm1 \n\t" + PAVGB" (%3), %%mm0 \n\t" + PAVGB" 8(%3), %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "movq %%mm1, 8(%3) \n\t" + "add %5, %3 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm1 \n\t" + "add %4, %1 \n\t" + PAVGB" 16(%2), %%mm0 \n\t" + PAVGB" 24(%2), %%mm1 \n\t" + PAVGB" (%3), %%mm0 \n\t" + PAVGB" 8(%3), %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "movq %%mm1, 8(%3) \n\t" + "add %5, %3 \n\t" + "add $32, %2 \n\t" + "subl $2, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +//the following should be used, though better not with gcc ... +/* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) + :"r"(src1Stride), "r"(dstStride) + :"memory");*/ +} + +static void DEF(put_no_rnd_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + __asm __volatile( + "pcmpeqb %%mm6, %%mm6 \n\t" + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm1 \n\t" + "movq (%2), %%mm2 \n\t" + "movq 8(%2), %%mm3 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "pxor %%mm6, %%mm2 \n\t" + "pxor %%mm6, %%mm3 \n\t" + PAVGB" %%mm2, %%mm0 \n\t" + PAVGB" %%mm3, %%mm1 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "add %4, %1 \n\t" + "add $16, %2 \n\t" + "movq %%mm0, (%3) \n\t" + "movq %%mm1, 8(%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm1 \n\t" + "add %4, %1 \n\t" + "movq (%2), %%mm2 \n\t" + "movq 8(%2), %%mm3 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "pxor %%mm6, %%mm2 \n\t" + "pxor %%mm6, %%mm3 \n\t" + PAVGB" %%mm2, %%mm0 \n\t" + PAVGB" %%mm3, %%mm1 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "movq %%mm1, 8(%3) \n\t" + "add %5, %3 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm1 \n\t" + "add %4, %1 \n\t" + "movq 16(%2), %%mm2 \n\t" + "movq 24(%2), %%mm3 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "pxor %%mm6, %%mm2 \n\t" + "pxor %%mm6, %%mm3 \n\t" + PAVGB" %%mm2, %%mm0 \n\t" + PAVGB" %%mm3, %%mm1 \n\t" + "pxor %%mm6, %%mm0 \n\t" + "pxor %%mm6, %%mm1 \n\t" + "movq %%mm0, (%3) \n\t" + "movq %%mm1, 8(%3) \n\t" + "add %5, %3 \n\t" + "add $32, %2 \n\t" + "subl $2, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +//the following should be used, though better not with gcc ... +/* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst) + :"r"(src1Stride), "r"(dstStride) + :"memory");*/ +} + +/* GL: this function does incorrect rounding if overflow */ +static void DEF(put_no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BONE(mm6); + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + "add %%"REG_a", %1 \n\t" + "psubusb %%mm6, %%mm0 \n\t" + "psubusb %%mm6, %%mm2 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + PAVGB" %%mm3, %%mm2 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm2, (%2, %3) \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + "add %%"REG_a", %2 \n\t" + "add %%"REG_a", %1 \n\t" + "psubusb %%mm6, %%mm0 \n\t" + "psubusb %%mm6, %%mm2 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + PAVGB" %%mm3, %%mm2 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm2, (%2, %3) \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r" ((long)line_size) + :"%"REG_a, "memory"); +} + +static void DEF(put_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + "sub %3, %2 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm2 \n\t" + "add %%"REG_a", %1 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + PAVGB" %%mm2, %%mm1 \n\t" + "movq %%mm0, (%2, %3) \n\t" + "movq %%mm1, (%2, %%"REG_a") \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "add %%"REG_a", %2 \n\t" + "add %%"REG_a", %1 \n\t" + PAVGB" %%mm1, %%mm2 \n\t" + PAVGB" %%mm0, %%mm1 \n\t" + "movq %%mm2, (%2, %3) \n\t" + "movq %%mm1, (%2, %%"REG_a") \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D" (block) + :"r" ((long)line_size) + :"%"REG_a, "memory"); +} + +/* GL: this function does incorrect rounding if overflow */ +static void DEF(put_no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BONE(mm6); + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + "sub %3, %2 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm2 \n\t" + "add %%"REG_a", %1 \n\t" + "psubusb %%mm6, %%mm1 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + PAVGB" %%mm2, %%mm1 \n\t" + "movq %%mm0, (%2, %3) \n\t" + "movq %%mm1, (%2, %%"REG_a") \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "add %%"REG_a", %2 \n\t" + "add %%"REG_a", %1 \n\t" + "psubusb %%mm6, %%mm1 \n\t" + PAVGB" %%mm1, %%mm2 \n\t" + PAVGB" %%mm0, %%mm1 \n\t" + "movq %%mm2, (%2, %3) \n\t" + "movq %%mm1, (%2, %%"REG_a") \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D" (block) + :"r" ((long)line_size) + :"%"REG_a, "memory"); +} + +static void DEF(avg_pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "1: \n\t" + "movq (%2), %%mm0 \n\t" + "movq (%2, %3), %%mm1 \n\t" + PAVGB" (%1), %%mm0 \n\t" + PAVGB" (%1, %3), %%mm1 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "movq (%2), %%mm0 \n\t" + "movq (%2, %3), %%mm1 \n\t" + PAVGB" (%1), %%mm0 \n\t" + PAVGB" (%1, %3), %%mm1 \n\t" + "add %%"REG_a", %1 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r" ((long)line_size) + :"%"REG_a, "memory"); +} + +static void DEF(avg_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm2 \n\t" + PAVGB" 1(%1), %%mm0 \n\t" + PAVGB" 1(%1, %3), %%mm2 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" (%2, %3), %%mm2 \n\t" + "add %%"REG_a", %1 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm2, (%2, %3) \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%1, %3), %%mm2 \n\t" + PAVGB" 1(%1), %%mm0 \n\t" + PAVGB" 1(%1, %3), %%mm2 \n\t" + "add %%"REG_a", %2 \n\t" + "add %%"REG_a", %1 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" (%2, %3), %%mm2 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm2, (%2, %3) \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r" ((long)line_size) + :"%"REG_a, "memory"); +} + +static void DEF(avg_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + "sub %3, %2 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm2 \n\t" + "add %%"REG_a", %1 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + PAVGB" %%mm2, %%mm1 \n\t" + "movq (%2, %3), %%mm3 \n\t" + "movq (%2, %%"REG_a"), %%mm4 \n\t" + PAVGB" %%mm3, %%mm0 \n\t" + PAVGB" %%mm4, %%mm1 \n\t" + "movq %%mm0, (%2, %3) \n\t" + "movq %%mm1, (%2, %%"REG_a") \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + PAVGB" %%mm1, %%mm2 \n\t" + PAVGB" %%mm0, %%mm1 \n\t" + "add %%"REG_a", %2 \n\t" + "add %%"REG_a", %1 \n\t" + "movq (%2, %3), %%mm3 \n\t" + "movq (%2, %%"REG_a"), %%mm4 \n\t" + PAVGB" %%mm3, %%mm2 \n\t" + PAVGB" %%mm4, %%mm1 \n\t" + "movq %%mm2, (%2, %3) \n\t" + "movq %%mm1, (%2, %%"REG_a") \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r" ((long)line_size) + :"%"REG_a, "memory"); +} + +// Note this is not correctly rounded, but this function is only used for b frames so it doesnt matter +static void DEF(avg_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BONE(mm6); + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + PAVGB" 1(%1), %%mm0 \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1, %%"REG_a"), %%mm2 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "psubusb %%mm6, %%mm2 \n\t" + PAVGB" 1(%1, %3), %%mm1 \n\t" + PAVGB" 1(%1, %%"REG_a"), %%mm2 \n\t" + "add %%"REG_a", %1 \n\t" + PAVGB" %%mm1, %%mm0 \n\t" + PAVGB" %%mm2, %%mm1 \n\t" + PAVGB" (%2), %%mm0 \n\t" + PAVGB" (%2, %3), %%mm1 \n\t" + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + PAVGB" 1(%1, %3), %%mm1 \n\t" + PAVGB" 1(%1, %%"REG_a"), %%mm0 \n\t" + "add %%"REG_a", %2 \n\t" + "add %%"REG_a", %1 \n\t" + PAVGB" %%mm1, %%mm2 \n\t" + PAVGB" %%mm0, %%mm1 \n\t" + PAVGB" (%2), %%mm2 \n\t" + PAVGB" (%2, %3), %%mm1 \n\t" + "movq %%mm2, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r" ((long)line_size) + :"%"REG_a, "memory"); +} + +//FIXME the following could be optimized too ... +static void DEF(put_no_rnd_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(put_no_rnd_pixels8_x2)(block , pixels , line_size, h); + DEF(put_no_rnd_pixels8_x2)(block+8, pixels+8, line_size, h); +} +static void DEF(put_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(put_pixels8_y2)(block , pixels , line_size, h); + DEF(put_pixels8_y2)(block+8, pixels+8, line_size, h); +} +static void DEF(put_no_rnd_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(put_no_rnd_pixels8_y2)(block , pixels , line_size, h); + DEF(put_no_rnd_pixels8_y2)(block+8, pixels+8, line_size, h); +} +static void DEF(avg_pixels16)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(avg_pixels8)(block , pixels , line_size, h); + DEF(avg_pixels8)(block+8, pixels+8, line_size, h); +} +static void DEF(avg_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(avg_pixels8_x2)(block , pixels , line_size, h); + DEF(avg_pixels8_x2)(block+8, pixels+8, line_size, h); +} +static void DEF(avg_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(avg_pixels8_y2)(block , pixels , line_size, h); + DEF(avg_pixels8_y2)(block+8, pixels+8, line_size, h); +} +static void DEF(avg_pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(avg_pixels8_xy2)(block , pixels , line_size, h); + DEF(avg_pixels8_xy2)(block+8, pixels+8, line_size, h); +} + diff --git a/mpeg4/src/libavcodec/i386/dsputil_mmx_rnd.h b/mpeg4/src/libavcodec/i386/dsputil_mmx_rnd.h new file mode 100644 index 00000000..3ecd776b --- /dev/null +++ b/mpeg4/src/libavcodec/i386/dsputil_mmx_rnd.h @@ -0,0 +1,590 @@ +/* + * DSP utils mmx functions are compiled twice for rnd/no_rnd + * Copyright (c) 2000, 2001 Fabrice Bellard. + * Copyright (c) 2003-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * MMX optimization by Nick Kurshev + * mostly rewritten by Michael Niedermayer + * and improved by Zdenek Kabelac + */ + +// put_pixels +static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BFE(mm6); + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((long)line_size) + :REG_a, "memory"); +} + +static void attribute_unused DEF(put, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + MOVQ_BFE(mm6); + __asm __volatile( + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "add $8, %2 \n\t" + PAVGB(%%mm0, %%mm1, %%mm4, %%mm6) + "movq %%mm4, (%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "movq (%1), %%mm2 \n\t" + "movq 8(%2), %%mm3 \n\t" + "add %4, %1 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%3) \n\t" + "add %5, %3 \n\t" + "movq %%mm5, (%3) \n\t" + "add %5, %3 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 16(%2), %%mm1 \n\t" + "add %4, %1 \n\t" + "movq (%1), %%mm2 \n\t" + "movq 24(%2), %%mm3 \n\t" + "add %4, %1 \n\t" + "add $32, %2 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%3) \n\t" + "add %5, %3 \n\t" + "movq %%mm5, (%3) \n\t" + "add %5, %3 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +} + +static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BFE(mm6); + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%1, %3), %%mm2 \n\t" + "movq 9(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, 8(%2) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%1, %3), %%mm2 \n\t" + "movq 9(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, 8(%2) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((long)line_size) + :REG_a, "memory"); +} + +static void attribute_unused DEF(put, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + MOVQ_BFE(mm6); + __asm __volatile( + "testl $1, %0 \n\t" + " jz 1f \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%2), %%mm1 \n\t" + "movq 8(%1), %%mm2 \n\t" + "movq 8(%2), %%mm3 \n\t" + "add %4, %1 \n\t" + "add $16, %2 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%3) \n\t" + "movq %%mm5, 8(%3) \n\t" + "add %5, %3 \n\t" + "decl %0 \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq (%2), %%mm1 \n\t" + "movq 8(%1), %%mm2 \n\t" + "movq 8(%2), %%mm3 \n\t" + "add %4, %1 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%3) \n\t" + "movq %%mm5, 8(%3) \n\t" + "add %5, %3 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 16(%2), %%mm1 \n\t" + "movq 8(%1), %%mm2 \n\t" + "movq 24(%2), %%mm3 \n\t" + "add %4, %1 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%3) \n\t" + "movq %%mm5, 8(%3) \n\t" + "add %5, %3 \n\t" + "add $32, %2 \n\t" + "subl $2, %0 \n\t" + "jnz 1b \n\t" +#ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used + :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#else + :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst) +#endif + :"S"((long)src1Stride), "D"((long)dstStride) + :"memory"); +} + +static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BFE(mm6); + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"),%%mm2 \n\t" + PAVGBP(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"),%%mm0 \n\t" + PAVGBP(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((long)line_size) + :REG_a, "memory"); +} + +static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_ZERO(mm7); + SET_RND(mm6); // =2 for rnd and =1 for no_rnd version + __asm __volatile( + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm4 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "xor %%"REG_a", %%"REG_a" \n\t" + "add %3, %1 \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "movq 1(%1, %%"REG_a"), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddusw %%mm2, %%mm0 \n\t" + "paddusw %%mm3, %%mm1 \n\t" + "paddusw %%mm6, %%mm4 \n\t" + "paddusw %%mm6, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "psrlw $2, %%mm4 \n\t" + "psrlw $2, %%mm5 \n\t" + "packuswb %%mm5, %%mm4 \n\t" + "movq %%mm4, (%2, %%"REG_a") \n\t" + "add %3, %%"REG_a" \n\t" + + "movq (%1, %%"REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 + "movq 1(%1, %%"REG_a"), %%mm4 \n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm2, %%mm4 \n\t" + "paddusw %%mm3, %%mm5 \n\t" + "paddusw %%mm6, %%mm0 \n\t" + "paddusw %%mm6, %%mm1 \n\t" + "paddusw %%mm4, %%mm0 \n\t" + "paddusw %%mm5, %%mm1 \n\t" + "psrlw $2, %%mm0 \n\t" + "psrlw $2, %%mm1 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "movq %%mm0, (%2, %%"REG_a") \n\t" + "add %3, %%"REG_a" \n\t" + + "subl $2, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels) + :"D"(block), "r"((long)line_size) + :REG_a, "memory"); +} + +// avg_pixels +static void attribute_unused DEF(avg, pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BFE(mm6); + JUMPALIGN(); + do { + __asm __volatile( + "movd %0, %%mm0 \n\t" + "movd %1, %%mm1 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + "movd %%mm2, %0 \n\t" + :"+m"(*block) + :"m"(*pixels) + :"memory"); + pixels += line_size; + block += line_size; + } + while (--h); +} + +// in case more speed is needed - unroling would certainly help +static void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BFE(mm6); + JUMPALIGN(); + do { + __asm __volatile( + "movq %0, %%mm0 \n\t" + "movq %1, %%mm1 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + "movq %%mm2, %0 \n\t" + :"+m"(*block) + :"m"(*pixels) + :"memory"); + pixels += line_size; + block += line_size; + } + while (--h); +} + +static void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BFE(mm6); + JUMPALIGN(); + do { + __asm __volatile( + "movq %0, %%mm0 \n\t" + "movq %1, %%mm1 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + "movq %%mm2, %0 \n\t" + "movq 8%0, %%mm0 \n\t" + "movq 8%1, %%mm1 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + "movq %%mm2, 8%0 \n\t" + :"+m"(*block) + :"m"(*pixels) + :"memory"); + pixels += line_size; + block += line_size; + } + while (--h); +} + +static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BFE(mm6); + JUMPALIGN(); + do { + __asm __volatile( + "movq %1, %%mm0 \n\t" + "movq 1%1, %%mm1 \n\t" + "movq %0, %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, %0 \n\t" + :"+m"(*block) + :"m"(*pixels) + :"memory"); + pixels += line_size; + block += line_size; + } while (--h); +} + +static __attribute__((unused)) void DEF(avg, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + MOVQ_BFE(mm6); + JUMPALIGN(); + do { + __asm __volatile( + "movq %1, %%mm0 \n\t" + "movq %2, %%mm1 \n\t" + "movq %0, %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, %0 \n\t" + :"+m"(*dst) + :"m"(*src1), "m"(*src2) + :"memory"); + dst += dstStride; + src1 += src1Stride; + src2 += 8; + } while (--h); +} + +static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BFE(mm6); + JUMPALIGN(); + do { + __asm __volatile( + "movq %1, %%mm0 \n\t" + "movq 1%1, %%mm1 \n\t" + "movq %0, %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, %0 \n\t" + "movq 8%1, %%mm0 \n\t" + "movq 9%1, %%mm1 \n\t" + "movq 8%0, %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, 8%0 \n\t" + :"+m"(*block) + :"m"(*pixels) + :"memory"); + pixels += line_size; + block += line_size; + } while (--h); +} + +static __attribute__((unused)) void DEF(avg, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +{ + MOVQ_BFE(mm6); + JUMPALIGN(); + do { + __asm __volatile( + "movq %1, %%mm0 \n\t" + "movq %2, %%mm1 \n\t" + "movq %0, %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, %0 \n\t" + "movq 8%1, %%mm0 \n\t" + "movq 8%2, %%mm1 \n\t" + "movq 8%0, %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, 8%0 \n\t" + :"+m"(*dst) + :"m"(*src1), "m"(*src2) + :"memory"); + dst += dstStride; + src1 += src1Stride; + src2 += 16; + } while (--h); +} + +static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_BFE(mm6); + __asm __volatile( + "lea (%3, %3), %%"REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm2 \n\t" + PAVGBP(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) + "movq (%2), %%mm3 \n\t" + PAVGB(%%mm3, %%mm4, %%mm0, %%mm6) + "movq (%2, %3), %%mm3 \n\t" + PAVGB(%%mm3, %%mm5, %%mm1, %%mm6) + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + PAVGBP(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) + "movq (%2), %%mm3 \n\t" + PAVGB(%%mm3, %%mm4, %%mm2, %%mm6) + "movq (%2, %3), %%mm3 \n\t" + PAVGB(%%mm3, %%mm5, %%mm1, %%mm6) + "movq %%mm2, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"REG_a", %1 \n\t" + "add %%"REG_a", %2 \n\t" + + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((long)line_size) + :REG_a, "memory"); +} + +// this routine is 'slightly' suboptimal but mostly unused +static void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h) +{ + MOVQ_ZERO(mm7); + SET_RND(mm6); // =2 for rnd and =1 for no_rnd version + __asm __volatile( + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm4 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "xor %%"REG_a", %%"REG_a" \n\t" + "add %3, %1 \n\t" + ".balign 8 \n\t" + "1: \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "movq 1(%1, %%"REG_a"), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddusw %%mm2, %%mm0 \n\t" + "paddusw %%mm3, %%mm1 \n\t" + "paddusw %%mm6, %%mm4 \n\t" + "paddusw %%mm6, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "psrlw $2, %%mm4 \n\t" + "psrlw $2, %%mm5 \n\t" + "movq (%2, %%"REG_a"), %%mm3 \n\t" + "packuswb %%mm5, %%mm4 \n\t" + "pcmpeqd %%mm2, %%mm2 \n\t" + "paddb %%mm2, %%mm2 \n\t" + PAVGB(%%mm3, %%mm4, %%mm5, %%mm2) + "movq %%mm5, (%2, %%"REG_a") \n\t" + "add %3, %%"REG_a" \n\t" + + "movq (%1, %%"REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 + "movq 1(%1, %%"REG_a"), %%mm4 \n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm2, %%mm4 \n\t" + "paddusw %%mm3, %%mm5 \n\t" + "paddusw %%mm6, %%mm0 \n\t" + "paddusw %%mm6, %%mm1 \n\t" + "paddusw %%mm4, %%mm0 \n\t" + "paddusw %%mm5, %%mm1 \n\t" + "psrlw $2, %%mm0 \n\t" + "psrlw $2, %%mm1 \n\t" + "movq (%2, %%"REG_a"), %%mm3 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "pcmpeqd %%mm2, %%mm2 \n\t" + "paddb %%mm2, %%mm2 \n\t" + PAVGB(%%mm3, %%mm0, %%mm1, %%mm2) + "movq %%mm1, (%2, %%"REG_a") \n\t" + "add %3, %%"REG_a" \n\t" + + "subl $2, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels) + :"D"(block), "r"((long)line_size) + :REG_a, "memory"); +} + +//FIXME optimize +static void DEF(put, pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(put, pixels8_y2)(block , pixels , line_size, h); + DEF(put, pixels8_y2)(block+8, pixels+8, line_size, h); +} + +static void DEF(put, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(put, pixels8_xy2)(block , pixels , line_size, h); + DEF(put, pixels8_xy2)(block+8, pixels+8, line_size, h); +} + +static void DEF(avg, pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(avg, pixels8_y2)(block , pixels , line_size, h); + DEF(avg, pixels8_y2)(block+8, pixels+8, line_size, h); +} + +static void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){ + DEF(avg, pixels8_xy2)(block , pixels , line_size, h); + DEF(avg, pixels8_xy2)(block+8, pixels+8, line_size, h); +} + + diff --git a/mpeg4/src/libavcodec/i386/fdct_mmx.c b/mpeg4/src/libavcodec/i386/fdct_mmx.c new file mode 100644 index 00000000..f6150c83 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/fdct_mmx.c @@ -0,0 +1,562 @@ +/* + * MMX optimized forward DCT + * The gcc porting is Copyright (c) 2001 Fabrice Bellard. + * cleanup/optimizations are Copyright (c) 2002-2004 Michael Niedermayer + * SSE2 optimization is Copyright (c) 2004 Denes Balatoni. + * + * from fdctam32.c - AP922 MMX(3D-Now) forward-DCT + * + * Intel Application Note AP-922 - fast, precise implementation of DCT + * http://developer.intel.com/vtune/cbts/appnotes.htm + * + * Also of inspiration: + * a page about fdct at http://www.geocities.com/ssavekar/dct.htm + * Skal's fdct at http://skal.planet-d.net/coding/dct.html + */ +#include "common.h" +#include "../dsputil.h" +#include "mmx.h" + +#define ATTR_ALIGN(align) __attribute__ ((__aligned__ (align))) + +////////////////////////////////////////////////////////////////////// +// +// constants for the forward DCT +// ----------------------------- +// +// Be sure to check that your compiler is aligning all constants to QWORD +// (8-byte) memory boundaries! Otherwise the unaligned memory access will +// severely stall MMX execution. +// +////////////////////////////////////////////////////////////////////// + +#define BITS_FRW_ACC 3 //; 2 or 3 for accuracy +#define SHIFT_FRW_COL BITS_FRW_ACC +#define SHIFT_FRW_ROW (BITS_FRW_ACC + 17 - 3) +#define RND_FRW_ROW (1 << (SHIFT_FRW_ROW-1)) +//#define RND_FRW_COL (1 << (SHIFT_FRW_COL-1)) + +//concatenated table, for forward DCT transformation +static const int16_t fdct_tg_all_16[] ATTR_ALIGN(8) = { + 13036, 13036, 13036, 13036, // tg * (2<<16) + 0.5 + 27146, 27146, 27146, 27146, // tg * (2<<16) + 0.5 + -21746, -21746, -21746, -21746, // tg * (2<<16) + 0.5 +}; + +static const int16_t ocos_4_16[4] ATTR_ALIGN(8) = { + 23170, 23170, 23170, 23170, //cos * (2<<15) + 0.5 +}; + +static const int64_t fdct_one_corr ATTR_ALIGN(8) = 0x0001000100010001LL; + +static const int32_t fdct_r_row[2] ATTR_ALIGN(8) = {RND_FRW_ROW, RND_FRW_ROW }; + +struct +{ + const int32_t fdct_r_row_sse2[4] ATTR_ALIGN(16); +} fdct_r_row_sse2 ATTR_ALIGN(16)= +{{ + RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW +}}; +//static const long fdct_r_row_sse2[4] ATTR_ALIGN(16) = {RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW}; + +static const int16_t tab_frw_01234567[] ATTR_ALIGN(8) = { // forward_dct coeff table + 16384, 16384, 22725, 19266, + 16384, 16384, 12873, 4520, + 21407, 8867, 19266, -4520, + -8867, -21407, -22725, -12873, + 16384, -16384, 12873, -22725, + -16384, 16384, 4520, 19266, + 8867, -21407, 4520, -12873, + 21407, -8867, 19266, -22725, + + 22725, 22725, 31521, 26722, + 22725, 22725, 17855, 6270, + 29692, 12299, 26722, -6270, + -12299, -29692, -31521, -17855, + 22725, -22725, 17855, -31521, + -22725, 22725, 6270, 26722, + 12299, -29692, 6270, -17855, + 29692, -12299, 26722, -31521, + + 21407, 21407, 29692, 25172, + 21407, 21407, 16819, 5906, + 27969, 11585, 25172, -5906, + -11585, -27969, -29692, -16819, + 21407, -21407, 16819, -29692, + -21407, 21407, 5906, 25172, + 11585, -27969, 5906, -16819, + 27969, -11585, 25172, -29692, + + 19266, 19266, 26722, 22654, + 19266, 19266, 15137, 5315, + 25172, 10426, 22654, -5315, + -10426, -25172, -26722, -15137, + 19266, -19266, 15137, -26722, + -19266, 19266, 5315, 22654, + 10426, -25172, 5315, -15137, + 25172, -10426, 22654, -26722, + + 16384, 16384, 22725, 19266, + 16384, 16384, 12873, 4520, + 21407, 8867, 19266, -4520, + -8867, -21407, -22725, -12873, + 16384, -16384, 12873, -22725, + -16384, 16384, 4520, 19266, + 8867, -21407, 4520, -12873, + 21407, -8867, 19266, -22725, + + 19266, 19266, 26722, 22654, + 19266, 19266, 15137, 5315, + 25172, 10426, 22654, -5315, + -10426, -25172, -26722, -15137, + 19266, -19266, 15137, -26722, + -19266, 19266, 5315, 22654, + 10426, -25172, 5315, -15137, + 25172, -10426, 22654, -26722, + + 21407, 21407, 29692, 25172, + 21407, 21407, 16819, 5906, + 27969, 11585, 25172, -5906, + -11585, -27969, -29692, -16819, + 21407, -21407, 16819, -29692, + -21407, 21407, 5906, 25172, + 11585, -27969, 5906, -16819, + 27969, -11585, 25172, -29692, + + 22725, 22725, 31521, 26722, + 22725, 22725, 17855, 6270, + 29692, 12299, 26722, -6270, + -12299, -29692, -31521, -17855, + 22725, -22725, 17855, -31521, + -22725, 22725, 6270, 26722, + 12299, -29692, 6270, -17855, + 29692, -12299, 26722, -31521, +}; + +struct +{ + const int16_t tab_frw_01234567_sse2[256] ATTR_ALIGN(16); +} tab_frw_01234567_sse2 ATTR_ALIGN(16) = +{{ +//static const int16_t tab_frw_01234567_sse2[] ATTR_ALIGN(16) = { // forward_dct coeff table +#define TABLE_SSE2 C4, C4, C1, C3, -C6, -C2, -C1, -C5, \ + C4, C4, C5, C7, C2, C6, C3, -C7, \ + -C4, C4, C7, C3, C6, -C2, C7, -C5, \ + C4, -C4, C5, -C1, C2, -C6, C3, -C1, +// c1..c7 * cos(pi/4) * 2^15 +#define C1 22725 +#define C2 21407 +#define C3 19266 +#define C4 16384 +#define C5 12873 +#define C6 8867 +#define C7 4520 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 31521 +#define C2 29692 +#define C3 26722 +#define C4 22725 +#define C5 17855 +#define C6 12299 +#define C7 6270 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 29692 +#define C2 27969 +#define C3 25172 +#define C4 21407 +#define C5 16819 +#define C6 11585 +#define C7 5906 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 26722 +#define C2 25172 +#define C3 22654 +#define C4 19266 +#define C5 15137 +#define C6 10426 +#define C7 5315 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 22725 +#define C2 21407 +#define C3 19266 +#define C4 16384 +#define C5 12873 +#define C6 8867 +#define C7 4520 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 26722 +#define C2 25172 +#define C3 22654 +#define C4 19266 +#define C5 15137 +#define C6 10426 +#define C7 5315 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 29692 +#define C2 27969 +#define C3 25172 +#define C4 21407 +#define C5 16819 +#define C6 11585 +#define C7 5906 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 31521 +#define C2 29692 +#define C3 26722 +#define C4 22725 +#define C5 17855 +#define C6 12299 +#define C7 6270 +TABLE_SSE2 +}}; + + +static always_inline void fdct_col(const int16_t *in, int16_t *out, int offset) +{ + movq_m2r(*(in + offset + 1 * 8), mm0); + movq_m2r(*(in + offset + 6 * 8), mm1); + movq_r2r(mm0, mm2); + movq_m2r(*(in + offset + 2 * 8), mm3); + paddsw_r2r(mm1, mm0); + movq_m2r(*(in + offset + 5 * 8), mm4); + psllw_i2r(SHIFT_FRW_COL, mm0); + movq_m2r(*(in + offset + 0 * 8), mm5); + paddsw_r2r(mm3, mm4); + paddsw_m2r(*(in + offset + 7 * 8), mm5); + psllw_i2r(SHIFT_FRW_COL, mm4); + movq_r2r(mm0, mm6); + psubsw_r2r(mm1, mm2); + movq_m2r(*(fdct_tg_all_16 + 4), mm1); + psubsw_r2r(mm4, mm0); + movq_m2r(*(in + offset + 3 * 8), mm7); + pmulhw_r2r(mm0, mm1); + paddsw_m2r(*(in + offset + 4 * 8), mm7); + psllw_i2r(SHIFT_FRW_COL, mm5); + paddsw_r2r(mm4, mm6); + psllw_i2r(SHIFT_FRW_COL, mm7); + movq_r2r(mm5, mm4); + psubsw_r2r(mm7, mm5); + paddsw_r2r(mm5, mm1); + paddsw_r2r(mm7, mm4); + por_m2r(fdct_one_corr, mm1); + psllw_i2r(SHIFT_FRW_COL + 1, mm2); + pmulhw_m2r(*(fdct_tg_all_16 + 4), mm5); + movq_r2r(mm4, mm7); + psubsw_m2r(*(in + offset + 5 * 8), mm3); + psubsw_r2r(mm6, mm4); + movq_r2m(mm1, *(out + offset + 2 * 8)); + paddsw_r2r(mm6, mm7); + movq_m2r(*(in + offset + 3 * 8), mm1); + psllw_i2r(SHIFT_FRW_COL + 1, mm3); + psubsw_m2r(*(in + offset + 4 * 8), mm1); + movq_r2r(mm2, mm6); + movq_r2m(mm4, *(out + offset + 4 * 8)); + paddsw_r2r(mm3, mm2); + pmulhw_m2r(*ocos_4_16, mm2); + psubsw_r2r(mm3, mm6); + pmulhw_m2r(*ocos_4_16, mm6); + psubsw_r2r(mm0, mm5); + por_m2r(fdct_one_corr, mm5); + psllw_i2r(SHIFT_FRW_COL, mm1); + por_m2r(fdct_one_corr, mm2); + movq_r2r(mm1, mm4); + movq_m2r(*(in + offset + 0 * 8), mm3); + paddsw_r2r(mm6, mm1); + psubsw_m2r(*(in + offset + 7 * 8), mm3); + psubsw_r2r(mm6, mm4); + movq_m2r(*(fdct_tg_all_16 + 0), mm0); + psllw_i2r(SHIFT_FRW_COL, mm3); + movq_m2r(*(fdct_tg_all_16 + 8), mm6); + pmulhw_r2r(mm1, mm0); + movq_r2m(mm7, *(out + offset + 0 * 8)); + pmulhw_r2r(mm4, mm6); + movq_r2m(mm5, *(out + offset + 6 * 8)); + movq_r2r(mm3, mm7); + movq_m2r(*(fdct_tg_all_16 + 8), mm5); + psubsw_r2r(mm2, mm7); + paddsw_r2r(mm2, mm3); + pmulhw_r2r(mm7, mm5); + paddsw_r2r(mm3, mm0); + paddsw_r2r(mm4, mm6); + pmulhw_m2r(*(fdct_tg_all_16 + 0), mm3); + por_m2r(fdct_one_corr, mm0); + paddsw_r2r(mm7, mm5); + psubsw_r2r(mm6, mm7); + movq_r2m(mm0, *(out + offset + 1 * 8)); + paddsw_r2r(mm4, mm5); + movq_r2m(mm7, *(out + offset + 3 * 8)); + psubsw_r2r(mm1, mm3); + movq_r2m(mm5, *(out + offset + 5 * 8)); + movq_r2m(mm3, *(out + offset + 7 * 8)); +} + + +static always_inline void fdct_row_sse2(const int16_t *in, int16_t *out) +{ + asm volatile( + ".macro FDCT_ROW_SSE2_H1 i t \n\t" + "movq \\i(%0), %%xmm2 \n\t" + "movq \\i+8(%0), %%xmm0 \n\t" + "movdqa \\t+32(%1), %%xmm3 \n\t" + "movdqa \\t+48(%1), %%xmm7 \n\t" + "movdqa \\t(%1), %%xmm4 \n\t" + "movdqa \\t+16(%1), %%xmm5 \n\t" + ".endm \n\t" + ".macro FDCT_ROW_SSE2_H2 i t \n\t" + "movq \\i(%0), %%xmm2 \n\t" + "movq \\i+8(%0), %%xmm0 \n\t" + "movdqa \\t+32(%1), %%xmm3 \n\t" + "movdqa \\t+48(%1), %%xmm7 \n\t" + ".endm \n\t" + ".macro FDCT_ROW_SSE2 i \n\t" + "movq %%xmm2, %%xmm1 \n\t" + "pshuflw $27, %%xmm0, %%xmm0 \n\t" + "paddsw %%xmm0, %%xmm1 \n\t" + "psubsw %%xmm0, %%xmm2 \n\t" + "punpckldq %%xmm2, %%xmm1 \n\t" + "pshufd $78, %%xmm1, %%xmm2 \n\t" + "pmaddwd %%xmm2, %%xmm3 \n\t" + "pmaddwd %%xmm1, %%xmm7 \n\t" + "pmaddwd %%xmm5, %%xmm2 \n\t" + "pmaddwd %%xmm4, %%xmm1 \n\t" + "paddd %%xmm7, %%xmm3 \n\t" + "paddd %%xmm2, %%xmm1 \n\t" + "paddd %%xmm6, %%xmm3 \n\t" + "paddd %%xmm6, %%xmm1 \n\t" + "psrad %3, %%xmm3 \n\t" + "psrad %3, %%xmm1 \n\t" + "packssdw %%xmm3, %%xmm1 \n\t" + "movdqa %%xmm1, \\i(%4) \n\t" + ".endm \n\t" + "movdqa (%2), %%xmm6 \n\t" + "FDCT_ROW_SSE2_H1 0 0 \n\t" + "FDCT_ROW_SSE2 0 \n\t" + "FDCT_ROW_SSE2_H2 64 0 \n\t" + "FDCT_ROW_SSE2 64 \n\t" + + "FDCT_ROW_SSE2_H1 16 64 \n\t" + "FDCT_ROW_SSE2 16 \n\t" + "FDCT_ROW_SSE2_H2 112 64 \n\t" + "FDCT_ROW_SSE2 112 \n\t" + + "FDCT_ROW_SSE2_H1 32 128 \n\t" + "FDCT_ROW_SSE2 32 \n\t" + "FDCT_ROW_SSE2_H2 96 128 \n\t" + "FDCT_ROW_SSE2 96 \n\t" + + "FDCT_ROW_SSE2_H1 48 192 \n\t" + "FDCT_ROW_SSE2 48 \n\t" + "FDCT_ROW_SSE2_H2 80 192 \n\t" + "FDCT_ROW_SSE2 80 \n\t" + : + : "r" (in), "r" (tab_frw_01234567_sse2.tab_frw_01234567_sse2), "r" (fdct_r_row_sse2.fdct_r_row_sse2), "i" (SHIFT_FRW_ROW), "r" (out) + ); +} + +static always_inline void fdct_row_mmx2(const int16_t *in, int16_t *out, const int16_t *table) +{ + pshufw_m2r(*(in + 4), mm5, 0x1B); + movq_m2r(*(in + 0), mm0); + movq_r2r(mm0, mm1); + paddsw_r2r(mm5, mm0); + psubsw_r2r(mm5, mm1); + movq_r2r(mm0, mm2); + punpckldq_r2r(mm1, mm0); + punpckhdq_r2r(mm1, mm2); + movq_m2r(*(table + 0), mm1); + movq_m2r(*(table + 4), mm3); + movq_m2r(*(table + 8), mm4); + movq_m2r(*(table + 12), mm5); + movq_m2r(*(table + 16), mm6); + movq_m2r(*(table + 20), mm7); + pmaddwd_r2r(mm0, mm1); + pmaddwd_r2r(mm2, mm3); + pmaddwd_r2r(mm0, mm4); + pmaddwd_r2r(mm2, mm5); + pmaddwd_r2r(mm0, mm6); + pmaddwd_r2r(mm2, mm7); + pmaddwd_m2r(*(table + 24), mm0); + pmaddwd_m2r(*(table + 28), mm2); + paddd_r2r(mm1, mm3); + paddd_r2r(mm4, mm5); + paddd_r2r(mm6, mm7); + paddd_r2r(mm0, mm2); + movq_m2r(*fdct_r_row, mm0); + paddd_r2r(mm0, mm3); + paddd_r2r(mm0, mm5); + paddd_r2r(mm0, mm7); + paddd_r2r(mm0, mm2); + psrad_i2r(SHIFT_FRW_ROW, mm3); + psrad_i2r(SHIFT_FRW_ROW, mm5); + psrad_i2r(SHIFT_FRW_ROW, mm7); + psrad_i2r(SHIFT_FRW_ROW, mm2); + packssdw_r2r(mm5, mm3); + packssdw_r2r(mm2, mm7); + movq_r2m(mm3, *(out + 0)); + movq_r2m(mm7, *(out + 4)); +} + +static always_inline void fdct_row_mmx(const int16_t *in, int16_t *out, const int16_t *table) +{ +//FIXME reorder (i dont have a old mmx only cpu here to benchmark ...) + movd_m2r(*(in + 6), mm1); + punpcklwd_m2r(*(in + 4), mm1); + movq_r2r(mm1, mm2); + psrlq_i2r(0x20, mm1); + movq_m2r(*(in + 0), mm0); + punpcklwd_r2r(mm2, mm1); + movq_r2r(mm0, mm5); + paddsw_r2r(mm1, mm0); + psubsw_r2r(mm1, mm5); + movq_r2r(mm0, mm2); + punpckldq_r2r(mm5, mm0); + punpckhdq_r2r(mm5, mm2); + movq_m2r(*(table + 0), mm1); + movq_m2r(*(table + 4), mm3); + movq_m2r(*(table + 8), mm4); + movq_m2r(*(table + 12), mm5); + movq_m2r(*(table + 16), mm6); + movq_m2r(*(table + 20), mm7); + pmaddwd_r2r(mm0, mm1); + pmaddwd_r2r(mm2, mm3); + pmaddwd_r2r(mm0, mm4); + pmaddwd_r2r(mm2, mm5); + pmaddwd_r2r(mm0, mm6); + pmaddwd_r2r(mm2, mm7); + pmaddwd_m2r(*(table + 24), mm0); + pmaddwd_m2r(*(table + 28), mm2); + paddd_r2r(mm1, mm3); + paddd_r2r(mm4, mm5); + paddd_r2r(mm6, mm7); + paddd_r2r(mm0, mm2); + movq_m2r(*fdct_r_row, mm0); + paddd_r2r(mm0, mm3); + paddd_r2r(mm0, mm5); + paddd_r2r(mm0, mm7); + paddd_r2r(mm0, mm2); + psrad_i2r(SHIFT_FRW_ROW, mm3); + psrad_i2r(SHIFT_FRW_ROW, mm5); + psrad_i2r(SHIFT_FRW_ROW, mm7); + psrad_i2r(SHIFT_FRW_ROW, mm2); + packssdw_r2r(mm5, mm3); + packssdw_r2r(mm2, mm7); + movq_r2m(mm3, *(out + 0)); + movq_r2m(mm7, *(out + 4)); +} + +void ff_fdct_mmx(int16_t *block) +{ + int64_t align_tmp[16] ATTR_ALIGN(8); + int16_t * const block_tmp= (int16_t*)align_tmp; + int16_t *block1, *out; + const int16_t *table; + int i; + + block1 = block_tmp; + fdct_col(block, block1, 0); + fdct_col(block, block1, 4); + + block1 = block_tmp; + table = tab_frw_01234567; + out = block; + for(i=8;i>0;i--) { + fdct_row_mmx(block1, out, table); + block1 += 8; + table += 32; + out += 8; + } +} + +void ff_fdct_mmx2(int16_t *block) +{ + int64_t align_tmp[16] ATTR_ALIGN(8); + int16_t * const block_tmp= (int16_t*)align_tmp; + int16_t *block1, *out; + const int16_t *table; + int i; + + block1 = block_tmp; + fdct_col(block, block1, 0); + fdct_col(block, block1, 4); + + block1 = block_tmp; + table = tab_frw_01234567; + out = block; + for(i=8;i>0;i--) { + fdct_row_mmx2(block1, out, table); + block1 += 8; + table += 32; + out += 8; + } +} + +void ff_fdct_sse2(int16_t *block) +{ + int64_t align_tmp[16] ATTR_ALIGN(8); + int16_t * const block_tmp= (int16_t*)align_tmp; + int16_t *block1; + + block1 = block_tmp; + fdct_col(block, block1, 0); + fdct_col(block, block1, 4); + + fdct_row_sse2(block1, block); +} + diff --git a/mpeg4/src/libavcodec/i386/fft_3dn.c b/mpeg4/src/libavcodec/i386/fft_3dn.c new file mode 100644 index 00000000..16595bdd --- /dev/null +++ b/mpeg4/src/libavcodec/i386/fft_3dn.c @@ -0,0 +1,136 @@ +/* + * FFT/MDCT transform with 3DNow! optimizations + * Copyright (c) 2006 Zuxy MENG Jie. + * Based on fft_sse.c copyright (c) 2002 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "../dsputil.h" +#include + +#ifdef HAVE_MM3DNOW + +#include + +static const int p1m1[2] __attribute__((aligned(8))) = + { 0, 1 << 31 }; + +static const int m1p1[2] __attribute__((aligned(8))) = + { 1 << 31, 0 }; + +void ff_fft_calc_3dn(FFTContext *s, FFTComplex *z) +{ + int ln = s->nbits; + int j, np, np2; + int nblocks, nloops; + register FFTComplex *p, *q; + FFTComplex *cptr, *cptr1; + int k; + + np = 1 << ln; + /* FEMMS not a must here but recommended by AMD */ + _m_femms(); + + { + __m64 *r, a0, a1, b0, b1, tmp, c; + + r = (__m64 *)&z[0]; + if (s->inverse) + c = *(__m64 *)m1p1; + else + c = *(__m64 *)p1m1; + + j = (np >> 2); + do { + /* do the pass 0 butterfly */ + a0 = _m_pfadd(r[0], r[1]); + a1 = _m_pfsub(r[0], r[1]); + + /* do the pass 0 butterfly */ + b0 = _m_pfadd(r[2], r[3]); + b1 = _m_pfsub(r[2], r[3]); + + /* multiply third by -i */ + tmp = _m_punpckhdq(b1, b1); + b1 = _m_punpckldq(b1, b1); + b1 = _m_punpckldq(tmp, b1); + b1 = _m_pxor(b1, c); + + /* do the pass 1 butterfly */ + r[0] = _m_pfadd(a0, b0); + r[1] = _m_pfadd(a1, b1); + r[2] = _m_pfsub(a0, b0); + r[3] = _m_pfsub(a1, b1); + r += 4; + } while (--j != 0); + } + /* pass 2 .. ln-1 */ + + nblocks = np >> 3; + nloops = 1 << 2; + np2 = np >> 1; + + cptr1 = s->exptab1; + do { + p = z; + q = z + nloops; + j = nblocks; + do { + cptr = cptr1; + k = nloops >> 1; + do { + __m64 a0, a1, b0, b1, c0, c1, t10, t11, t20, t21; + + a0 = *(__m64 *)&p[0]; + a1 = *(__m64 *)&p[1]; + b0 = *(__m64 *)&q[0]; + b1 = *(__m64 *)&q[1]; + + /* complex mul */ + c0 = *(__m64 *)&cptr[0]; + c1 = *(__m64 *)&cptr[1]; + /* cre*re cim*re */ + t10 = _m_pfmul(c0, _m_punpckldq(b0, b0)); + t11 = _m_pfmul(c1, _m_punpckldq(b1, b1)); + c0 = *(__m64 *)&cptr[2]; + c1 = *(__m64 *)&cptr[3]; + /* -cim*im cre*im */ + t20 = _m_pfmul(c0, _m_punpckhdq(b0, b0)); + t21 = _m_pfmul(c1, _m_punpckhdq(b1, b1)); + b0 = _m_pfadd(t10, t20); + b1 = _m_pfadd(t11, t21); + + /* butterfly */ + *(__m64 *)&p[0] = _m_pfadd(a0, b0); + *(__m64 *)&p[1] = _m_pfadd(a1, b1); + *(__m64 *)&q[0] = _m_pfsub(a0, b0); + *(__m64 *)&q[1] = _m_pfsub(a1, b1); + + p += 2; + q += 2; + cptr += 4; + } while (--k); + + p += nloops; + q += nloops; + } while (--j); + cptr1 += nloops * 2; + nblocks = nblocks >> 1; + nloops = nloops << 1; + } while (nblocks != 0); + _m_femms(); +} + +#endif diff --git a/mpeg4/src/libavcodec/i386/fft_3dn2.c b/mpeg4/src/libavcodec/i386/fft_3dn2.c new file mode 100644 index 00000000..aa8f0aee --- /dev/null +++ b/mpeg4/src/libavcodec/i386/fft_3dn2.c @@ -0,0 +1,136 @@ +/* + * FFT/MDCT transform with Extended 3DNow! optimizations + * Copyright (c) 2006 Zuxy MENG Jie. + * Based on fft_sse.c copyright (c) 2002 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "../dsputil.h" +#include + +#ifdef HAVE_MM3DNOW + +#include + +static const int p1m1[2] __attribute__((aligned(8))) = + { 0, 1 << 31 }; + +static const int m1p1[2] __attribute__((aligned(8))) = + { 1 << 31, 0 }; + +void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z) +{ + int ln = s->nbits; + int j, np, np2; + int nblocks, nloops; + register FFTComplex *p, *q; + FFTComplex *cptr, *cptr1; + int k; + + np = 1 << ln; + /* FEMMS is not a must here but recommended by AMD */ + _m_femms(); + + { + __m64 *r, a0, a1, b0, b1, c; + + r = (__m64 *)&z[0]; + if (s->inverse) + c = *(__m64 *)m1p1; + else + c = *(__m64 *)p1m1; + + j = (np >> 2); + do { + /* do the pass 0 butterfly */ + a0 = _m_pfadd(r[0], r[1]); + a1 = _m_pfsub(r[0], r[1]); + + /* do the pass 0 butterfly */ + b0 = _m_pfadd(r[2], r[3]); + b1 = _m_pfsub(r[2], r[3]); + + /* multiply third by -i */ + b1 = _m_pswapd(b1); + b1 = _m_pxor(b1, c); + + r[0] = _m_pfadd(a0, b0); + r[1] = _m_pfadd(a1, b1); + r[2] = _m_pfsub(a0, b0); + r[3] = _m_pfsub(a1, b1); + r += 4; + } while (--j != 0); + } + /* pass 2 .. ln-1 */ + + nblocks = np >> 3; + nloops = 1 << 2; + np2 = np >> 1; + + cptr1 = s->exptab1; + do { + p = z; + q = z + nloops; + j = nblocks; + do { + cptr = cptr1; + k = nloops >> 1; + do { + __m64 a0, a1, b0, b1, c0, c1, t10, t11, t20, t21; + + a0 = *(__m64 *)&p[0]; + a1 = *(__m64 *)&p[1]; + b0 = *(__m64 *)&q[0]; + b1 = *(__m64 *)&q[1]; + + /* complex mul */ + c0 = *(__m64 *)&cptr[0]; + c1 = *(__m64 *)&cptr[1]; + /* cre*re cim*im */ + t10 = _m_pfmul(c0, b0); + t11 = _m_pfmul(c1, b1); + /* no need to access cptr[2] & cptr[3] */ + c0 = _m_pswapd(c0); + c1 = _m_pswapd(c1); + /* cim*re cre*im */ + t20 = _m_pfmul(c0, b0); + t21 = _m_pfmul(c1, b1); + + /* cre*re-cim*im cim*re+cre*im */ + b0 = _m_pfpnacc(t10, t20); + b1 = _m_pfpnacc(t11, t21); + + /* butterfly */ + *(__m64 *)&p[0] = _m_pfadd(a0, b0); + *(__m64 *)&p[1] = _m_pfadd(a1, b1); + *(__m64 *)&q[0] = _m_pfsub(a0, b0); + *(__m64 *)&q[1] = _m_pfsub(a1, b1); + + p += 2; + q += 2; + cptr += 4; + } while (--k); + + p += nloops; + q += nloops; + } while (--j); + cptr1 += nloops * 2; + nblocks = nblocks >> 1; + nloops = nloops << 1; + } while (nblocks != 0); + _m_femms(); +} + +#endif diff --git a/mpeg4/src/libavcodec/i386/fft_sse.c b/mpeg4/src/libavcodec/i386/fft_sse.c new file mode 100644 index 00000000..63184826 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/fft_sse.c @@ -0,0 +1,140 @@ +/* + * FFT/MDCT transform with SSE optimizations + * Copyright (c) 2002 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "../dsputil.h" +#include + +#ifdef HAVE_BUILTIN_VECTOR + +#include + +static const int p1p1p1m1[4] __attribute__((aligned(16))) = + { 0, 0, 0, 1 << 31 }; + +static const int p1p1m1p1[4] __attribute__((aligned(16))) = + { 0, 0, 1 << 31, 0 }; + +static const int p1p1m1m1[4] __attribute__((aligned(16))) = + { 0, 0, 1 << 31, 1 << 31 }; + +#if 0 +static void print_v4sf(const char *str, __m128 a) +{ + float *p = (float *)&a; + printf("%s: %f %f %f %f\n", + str, p[0], p[1], p[2], p[3]); +} +#endif + +/* XXX: handle reverse case */ +void ff_fft_calc_sse(FFTContext *s, FFTComplex *z) +{ + int ln = s->nbits; + int j, np, np2; + int nblocks, nloops; + register FFTComplex *p, *q; + FFTComplex *cptr, *cptr1; + int k; + + np = 1 << ln; + + { + __m128 *r, a, b, a1, c1, c2; + + r = (__m128 *)&z[0]; + c1 = *(__m128 *)p1p1m1m1; + if (s->inverse) + c2 = *(__m128 *)p1p1m1p1; + else + c2 = *(__m128 *)p1p1p1m1; + + j = (np >> 2); + do { + a = r[0]; + b = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + a = _mm_xor_ps(a, c1); + /* do the pass 0 butterfly */ + a = _mm_add_ps(a, b); + + a1 = r[1]; + b = _mm_shuffle_ps(a1, a1, _MM_SHUFFLE(1, 0, 3, 2)); + a1 = _mm_xor_ps(a1, c1); + /* do the pass 0 butterfly */ + b = _mm_add_ps(a1, b); + + /* multiply third by -i */ + /* by toggling the sign bit */ + b = _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 3, 1, 0)); + b = _mm_xor_ps(b, c2); + + /* do the pass 1 butterfly */ + r[0] = _mm_add_ps(a, b); + r[1] = _mm_sub_ps(a, b); + r += 2; + } while (--j != 0); + } + /* pass 2 .. ln-1 */ + + nblocks = np >> 3; + nloops = 1 << 2; + np2 = np >> 1; + + cptr1 = s->exptab1; + do { + p = z; + q = z + nloops; + j = nblocks; + do { + cptr = cptr1; + k = nloops >> 1; + do { + __m128 a, b, c, t1, t2; + + a = *(__m128 *)p; + b = *(__m128 *)q; + + /* complex mul */ + c = *(__m128 *)cptr; + /* cre*re cim*re */ + t1 = _mm_mul_ps(c, + _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 0, 0))); + c = *(__m128 *)(cptr + 2); + /* -cim*im cre*im */ + t2 = _mm_mul_ps(c, + _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 1, 1))); + b = _mm_add_ps(t1, t2); + + /* butterfly */ + *(__m128 *)p = _mm_add_ps(a, b); + *(__m128 *)q = _mm_sub_ps(a, b); + + p += 2; + q += 2; + cptr += 4; + } while (--k); + + p += nloops; + q += nloops; + } while (--j); + cptr1 += nloops * 2; + nblocks = nblocks >> 1; + nloops = nloops << 1; + } while (nblocks != 0); +} + +#endif diff --git a/mpeg4/src/libavcodec/i386/h264dsp_mmx.c b/mpeg4/src/libavcodec/i386/h264dsp_mmx.c new file mode 100644 index 00000000..aedde696 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/h264dsp_mmx.c @@ -0,0 +1,1433 @@ +/* + * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +/***********************************/ +/* IDCT */ + +/* in/out: mma=mma+mmb, mmb=mmb-mma */ +#define SUMSUB_BA( a, b ) \ + "paddw "#b", "#a" \n\t"\ + "paddw "#b", "#b" \n\t"\ + "psubw "#a", "#b" \n\t" + +#define SUMSUB_BADC( a, b, c, d ) \ + "paddw "#b", "#a" \n\t"\ + "paddw "#d", "#c" \n\t"\ + "paddw "#b", "#b" \n\t"\ + "paddw "#d", "#d" \n\t"\ + "psubw "#a", "#b" \n\t"\ + "psubw "#c", "#d" \n\t" + +#define SUMSUBD2_AB( a, b, t ) \ + "movq "#b", "#t" \n\t"\ + "psraw $1 , "#b" \n\t"\ + "paddw "#a", "#b" \n\t"\ + "psraw $1 , "#a" \n\t"\ + "psubw "#t", "#a" \n\t" + +#define IDCT4_1D( s02, s13, d02, d13, t ) \ + SUMSUB_BA ( s02, d02 )\ + SUMSUBD2_AB( s13, d13, t )\ + SUMSUB_BADC( d13, s02, s13, d02 ) + +#define SBUTTERFLY(a,b,t,n)\ + "movq " #a ", " #t " \n\t" /* abcd */\ + "punpckl" #n " " #b ", " #a " \n\t" /* aebf */\ + "punpckh" #n " " #b ", " #t " \n\t" /* cgdh */\ + +#define TRANSPOSE4(a,b,c,d,t)\ + SBUTTERFLY(a,b,t,wd) /* a=aebf t=cgdh */\ + SBUTTERFLY(c,d,b,wd) /* c=imjn b=kolp */\ + SBUTTERFLY(a,c,d,dq) /* a=aeim d=bfjn */\ + SBUTTERFLY(t,b,c,dq) /* t=cgko c=dhlp */ + +#define STORE_DIFF_4P( p, t, z ) \ + "psraw $6, "#p" \n\t"\ + "movd (%0), "#t" \n\t"\ + "punpcklbw "#z", "#t" \n\t"\ + "paddsw "#t", "#p" \n\t"\ + "packuswb "#z", "#p" \n\t"\ + "movd "#p", (%0) \n\t" + +static void ff_h264_idct_add_mmx(uint8_t *dst, int16_t *block, int stride) +{ + /* Load dct coeffs */ + asm volatile( + "movq (%0), %%mm0 \n\t" + "movq 8(%0), %%mm1 \n\t" + "movq 16(%0), %%mm2 \n\t" + "movq 24(%0), %%mm3 \n\t" + :: "r"(block) ); + + asm volatile( + /* mm1=s02+s13 mm2=s02-s13 mm4=d02+d13 mm0=d02-d13 */ + IDCT4_1D( %%mm2, %%mm1, %%mm0, %%mm3, %%mm4 ) + + "movq %0, %%mm6 \n\t" + /* in: 1,4,0,2 out: 1,2,3,0 */ + TRANSPOSE4( %%mm3, %%mm1, %%mm0, %%mm2, %%mm4 ) + + "paddw %%mm6, %%mm3 \n\t" + + /* mm2=s02+s13 mm3=s02-s13 mm4=d02+d13 mm1=d02-d13 */ + IDCT4_1D( %%mm4, %%mm2, %%mm3, %%mm0, %%mm1 ) + + "pxor %%mm7, %%mm7 \n\t" + :: "m"(ff_pw_32)); + + asm volatile( + STORE_DIFF_4P( %%mm0, %%mm1, %%mm7) + "add %1, %0 \n\t" + STORE_DIFF_4P( %%mm2, %%mm1, %%mm7) + "add %1, %0 \n\t" + STORE_DIFF_4P( %%mm3, %%mm1, %%mm7) + "add %1, %0 \n\t" + STORE_DIFF_4P( %%mm4, %%mm1, %%mm7) + : "+r"(dst) + : "r" ((long)stride) + ); +} + +static inline void h264_idct8_1d(int16_t *block) +{ + asm volatile( + "movq 112(%0), %%mm7 \n\t" + "movq 80(%0), %%mm5 \n\t" + "movq 48(%0), %%mm3 \n\t" + "movq 16(%0), %%mm1 \n\t" + + "movq %%mm7, %%mm4 \n\t" + "movq %%mm3, %%mm6 \n\t" + "movq %%mm5, %%mm0 \n\t" + "movq %%mm7, %%mm2 \n\t" + "psraw $1, %%mm4 \n\t" + "psraw $1, %%mm6 \n\t" + "psubw %%mm7, %%mm0 \n\t" + "psubw %%mm6, %%mm2 \n\t" + "psubw %%mm4, %%mm0 \n\t" + "psubw %%mm3, %%mm2 \n\t" + "psubw %%mm3, %%mm0 \n\t" + "paddw %%mm1, %%mm2 \n\t" + + "movq %%mm5, %%mm4 \n\t" + "movq %%mm1, %%mm6 \n\t" + "psraw $1, %%mm4 \n\t" + "psraw $1, %%mm6 \n\t" + "paddw %%mm5, %%mm4 \n\t" + "paddw %%mm1, %%mm6 \n\t" + "paddw %%mm7, %%mm4 \n\t" + "paddw %%mm5, %%mm6 \n\t" + "psubw %%mm1, %%mm4 \n\t" + "paddw %%mm3, %%mm6 \n\t" + + "movq %%mm0, %%mm1 \n\t" + "movq %%mm4, %%mm3 \n\t" + "movq %%mm2, %%mm5 \n\t" + "movq %%mm6, %%mm7 \n\t" + "psraw $2, %%mm6 \n\t" + "psraw $2, %%mm3 \n\t" + "psraw $2, %%mm5 \n\t" + "psraw $2, %%mm0 \n\t" + "paddw %%mm6, %%mm1 \n\t" + "paddw %%mm2, %%mm3 \n\t" + "psubw %%mm4, %%mm5 \n\t" + "psubw %%mm0, %%mm7 \n\t" + + "movq 32(%0), %%mm2 \n\t" + "movq 96(%0), %%mm6 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq %%mm6, %%mm0 \n\t" + "psraw $1, %%mm4 \n\t" + "psraw $1, %%mm6 \n\t" + "psubw %%mm0, %%mm4 \n\t" + "paddw %%mm2, %%mm6 \n\t" + + "movq (%0), %%mm2 \n\t" + "movq 64(%0), %%mm0 \n\t" + SUMSUB_BA( %%mm0, %%mm2 ) + SUMSUB_BA( %%mm6, %%mm0 ) + SUMSUB_BA( %%mm4, %%mm2 ) + SUMSUB_BA( %%mm7, %%mm6 ) + SUMSUB_BA( %%mm5, %%mm4 ) + SUMSUB_BA( %%mm3, %%mm2 ) + SUMSUB_BA( %%mm1, %%mm0 ) + :: "r"(block) + ); +} + +static void ff_h264_idct8_add_mmx(uint8_t *dst, int16_t *block, int stride) +{ + int i; + int16_t __attribute__ ((aligned(8))) b2[64]; + + block[0] += 32; + + for(i=0; i<2; i++){ + uint64_t tmp; + + h264_idct8_1d(block+4*i); + + asm volatile( + "movq %%mm7, %0 \n\t" + TRANSPOSE4( %%mm0, %%mm2, %%mm4, %%mm6, %%mm7 ) + "movq %%mm0, 8(%1) \n\t" + "movq %%mm6, 24(%1) \n\t" + "movq %%mm7, 40(%1) \n\t" + "movq %%mm4, 56(%1) \n\t" + "movq %0, %%mm7 \n\t" + TRANSPOSE4( %%mm7, %%mm5, %%mm3, %%mm1, %%mm0 ) + "movq %%mm7, (%1) \n\t" + "movq %%mm1, 16(%1) \n\t" + "movq %%mm0, 32(%1) \n\t" + "movq %%mm3, 48(%1) \n\t" + : "=m"(tmp) + : "r"(b2+32*i) + : "memory" + ); + } + + for(i=0; i<2; i++){ + h264_idct8_1d(b2+4*i); + + asm volatile( + "psraw $6, %%mm7 \n\t" + "psraw $6, %%mm6 \n\t" + "psraw $6, %%mm5 \n\t" + "psraw $6, %%mm4 \n\t" + "psraw $6, %%mm3 \n\t" + "psraw $6, %%mm2 \n\t" + "psraw $6, %%mm1 \n\t" + "psraw $6, %%mm0 \n\t" + + "movq %%mm7, (%0) \n\t" + "movq %%mm5, 16(%0) \n\t" + "movq %%mm3, 32(%0) \n\t" + "movq %%mm1, 48(%0) \n\t" + "movq %%mm0, 64(%0) \n\t" + "movq %%mm2, 80(%0) \n\t" + "movq %%mm4, 96(%0) \n\t" + "movq %%mm6, 112(%0) \n\t" + :: "r"(b2+4*i) + : "memory" + ); + } + + add_pixels_clamped_mmx(b2, dst, stride); +} + +static void ff_h264_idct_dc_add_mmx2(uint8_t *dst, int16_t *block, int stride) +{ + int dc = (block[0] + 32) >> 6; + asm volatile( + "movd %0, %%mm0 \n\t" + "pshufw $0, %%mm0, %%mm0 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "psubw %%mm0, %%mm1 \n\t" + "packuswb %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm1 \n\t" + ::"r"(dc) + ); + asm volatile( + "movd %0, %%mm2 \n\t" + "movd %1, %%mm3 \n\t" + "movd %2, %%mm4 \n\t" + "movd %3, %%mm5 \n\t" + "paddusb %%mm0, %%mm2 \n\t" + "paddusb %%mm0, %%mm3 \n\t" + "paddusb %%mm0, %%mm4 \n\t" + "paddusb %%mm0, %%mm5 \n\t" + "psubusb %%mm1, %%mm2 \n\t" + "psubusb %%mm1, %%mm3 \n\t" + "psubusb %%mm1, %%mm4 \n\t" + "psubusb %%mm1, %%mm5 \n\t" + "movd %%mm2, %0 \n\t" + "movd %%mm3, %1 \n\t" + "movd %%mm4, %2 \n\t" + "movd %%mm5, %3 \n\t" + :"+m"(*(uint32_t*)(dst+0*stride)), + "+m"(*(uint32_t*)(dst+1*stride)), + "+m"(*(uint32_t*)(dst+2*stride)), + "+m"(*(uint32_t*)(dst+3*stride)) + ); +} + +static void ff_h264_idct8_dc_add_mmx2(uint8_t *dst, int16_t *block, int stride) +{ + int dc = (block[0] + 32) >> 6; + int y; + asm volatile( + "movd %0, %%mm0 \n\t" + "pshufw $0, %%mm0, %%mm0 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "psubw %%mm0, %%mm1 \n\t" + "packuswb %%mm0, %%mm0 \n\t" + "packuswb %%mm1, %%mm1 \n\t" + ::"r"(dc) + ); + for(y=2; y--; dst += 4*stride){ + asm volatile( + "movq %0, %%mm2 \n\t" + "movq %1, %%mm3 \n\t" + "movq %2, %%mm4 \n\t" + "movq %3, %%mm5 \n\t" + "paddusb %%mm0, %%mm2 \n\t" + "paddusb %%mm0, %%mm3 \n\t" + "paddusb %%mm0, %%mm4 \n\t" + "paddusb %%mm0, %%mm5 \n\t" + "psubusb %%mm1, %%mm2 \n\t" + "psubusb %%mm1, %%mm3 \n\t" + "psubusb %%mm1, %%mm4 \n\t" + "psubusb %%mm1, %%mm5 \n\t" + "movq %%mm2, %0 \n\t" + "movq %%mm3, %1 \n\t" + "movq %%mm4, %2 \n\t" + "movq %%mm5, %3 \n\t" + :"+m"(*(uint64_t*)(dst+0*stride)), + "+m"(*(uint64_t*)(dst+1*stride)), + "+m"(*(uint64_t*)(dst+2*stride)), + "+m"(*(uint64_t*)(dst+3*stride)) + ); + } +} + + +/***********************************/ +/* deblocking */ + +// out: o = |x-y|>a +// clobbers: t +#define DIFF_GT_MMX(x,y,a,o,t)\ + "movq "#y", "#t" \n\t"\ + "movq "#x", "#o" \n\t"\ + "psubusb "#x", "#t" \n\t"\ + "psubusb "#y", "#o" \n\t"\ + "por "#t", "#o" \n\t"\ + "psubusb "#a", "#o" \n\t" + +// in: mm0=p1 mm1=p0 mm2=q0 mm3=q1 +// out: mm5=beta-1, mm7=mask +// clobbers: mm4,mm6 +#define H264_DEBLOCK_MASK(alpha1, beta1) \ + "pshufw $0, "#alpha1", %%mm4 \n\t"\ + "pshufw $0, "#beta1 ", %%mm5 \n\t"\ + "packuswb %%mm4, %%mm4 \n\t"\ + "packuswb %%mm5, %%mm5 \n\t"\ + DIFF_GT_MMX(%%mm1, %%mm2, %%mm4, %%mm7, %%mm6) /* |p0-q0| > alpha-1 */\ + DIFF_GT_MMX(%%mm0, %%mm1, %%mm5, %%mm4, %%mm6) /* |p1-p0| > beta-1 */\ + "por %%mm4, %%mm7 \n\t"\ + DIFF_GT_MMX(%%mm3, %%mm2, %%mm5, %%mm4, %%mm6) /* |q1-q0| > beta-1 */\ + "por %%mm4, %%mm7 \n\t"\ + "pxor %%mm6, %%mm6 \n\t"\ + "pcmpeqb %%mm6, %%mm7 \n\t" + +// in: mm0=p1 mm1=p0 mm2=q0 mm3=q1 mm7=(tc&mask) +// out: mm1=p0' mm2=q0' +// clobbers: mm0,3-6 +#define H264_DEBLOCK_P0_Q0(pb_01, pb_3f)\ + /* a = q0^p0^((p1-q1)>>2) */\ + "movq %%mm0, %%mm4 \n\t"\ + "psubb %%mm3, %%mm4 \n\t"\ + "psrlw $2, %%mm4 \n\t"\ + "pxor %%mm1, %%mm4 \n\t"\ + "pxor %%mm2, %%mm4 \n\t"\ + /* b = p0^(q1>>2) */\ + "psrlw $2, %%mm3 \n\t"\ + "pand "#pb_3f", %%mm3 \n\t"\ + "movq %%mm1, %%mm5 \n\t"\ + "pxor %%mm3, %%mm5 \n\t"\ + /* c = q0^(p1>>2) */\ + "psrlw $2, %%mm0 \n\t"\ + "pand "#pb_3f", %%mm0 \n\t"\ + "movq %%mm2, %%mm6 \n\t"\ + "pxor %%mm0, %%mm6 \n\t"\ + /* d = (c^b) & ~(b^a) & 1 */\ + "pxor %%mm5, %%mm6 \n\t"\ + "pxor %%mm4, %%mm5 \n\t"\ + "pandn %%mm6, %%mm5 \n\t"\ + "pand "#pb_01", %%mm5 \n\t"\ + /* delta = (avg(q0, p1>>2) + (d&a)) + * - (avg(p0, q1>>2) + (d&~a)) */\ + "pavgb %%mm2, %%mm0 \n\t"\ + "pand %%mm5, %%mm4 \n\t"\ + "paddusb %%mm4, %%mm0 \n\t"\ + "pavgb %%mm1, %%mm3 \n\t"\ + "pxor %%mm5, %%mm4 \n\t"\ + "paddusb %%mm4, %%mm3 \n\t"\ + /* p0 += clip(delta, -tc0, tc0) + * q0 -= clip(delta, -tc0, tc0) */\ + "movq %%mm0, %%mm4 \n\t"\ + "psubusb %%mm3, %%mm0 \n\t"\ + "psubusb %%mm4, %%mm3 \n\t"\ + "pminub %%mm7, %%mm0 \n\t"\ + "pminub %%mm7, %%mm3 \n\t"\ + "paddusb %%mm0, %%mm1 \n\t"\ + "paddusb %%mm3, %%mm2 \n\t"\ + "psubusb %%mm3, %%mm1 \n\t"\ + "psubusb %%mm0, %%mm2 \n\t" + +// in: mm0=p1 mm1=p0 mm2=q0 mm3=q1 mm7=(tc&mask) %8=mm_bone +// out: (q1addr) = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 ) +// clobbers: q2, tmp, tc0 +#define H264_DEBLOCK_Q1(p1, q2, q2addr, q1addr, tc0, tmp)\ + "movq %%mm1, "#tmp" \n\t"\ + "pavgb %%mm2, "#tmp" \n\t"\ + "pavgb "#tmp", "#q2" \n\t" /* avg(p2,avg(p0,q0)) */\ + "pxor "q2addr", "#tmp" \n\t"\ + "pand %8, "#tmp" \n\t" /* (p2^avg(p0,q0))&1 */\ + "psubusb "#tmp", "#q2" \n\t" /* (p2+((p0+q0+1)>>1))>>1 */\ + "movq "#p1", "#tmp" \n\t"\ + "psubusb "#tc0", "#tmp" \n\t"\ + "paddusb "#p1", "#tc0" \n\t"\ + "pmaxub "#tmp", "#q2" \n\t"\ + "pminub "#tc0", "#q2" \n\t"\ + "movq "#q2", "q1addr" \n\t" + +static inline void h264_loop_filter_luma_mmx2(uint8_t *pix, int stride, int alpha1, int beta1, int8_t *tc0) +{ + uint64_t tmp0; + uint64_t tc = (uint8_t)tc0[1]*0x01010000 | (uint8_t)tc0[0]*0x0101; + // with luma, tc0=0 doesn't mean no filtering, so we need a separate input mask + uint32_t mask[2] = { (tc0[0]>=0)*0xffffffff, (tc0[1]>=0)*0xffffffff }; + + asm volatile( + "movq (%1,%3), %%mm0 \n\t" //p1 + "movq (%1,%3,2), %%mm1 \n\t" //p0 + "movq (%2), %%mm2 \n\t" //q0 + "movq (%2,%3), %%mm3 \n\t" //q1 + H264_DEBLOCK_MASK(%6, %7) + "pand %5, %%mm7 \n\t" + "movq %%mm7, %0 \n\t" + + /* filter p1 */ + "movq (%1), %%mm3 \n\t" //p2 + DIFF_GT_MMX(%%mm1, %%mm3, %%mm5, %%mm6, %%mm4) // |p2-p0|>beta-1 + "pandn %%mm7, %%mm6 \n\t" + "pcmpeqb %%mm7, %%mm6 \n\t" + "pand %%mm7, %%mm6 \n\t" // mask & |p2-p0|beta-1 + "pandn %0, %%mm6 \n\t" + "pcmpeqb %0, %%mm6 \n\t" + "pand %0, %%mm6 \n\t" + "pshufw $80, %4, %%mm5 \n\t" + "pand %%mm6, %%mm5 \n\t" + "pand %8, %%mm6 \n\t" + "paddb %%mm6, %%mm7 \n\t" + "movq (%2,%3), %%mm3 \n\t" + H264_DEBLOCK_Q1(%%mm3, %%mm4, "(%2,%3,2)", "(%2,%3)", %%mm5, %%mm6) + + /* filter p0, q0 */ + H264_DEBLOCK_P0_Q0(%8, %9) + "movq %%mm1, (%1,%3,2) \n\t" + "movq %%mm2, (%2) \n\t" + + : "=m"(tmp0) + : "r"(pix-3*stride), "r"(pix), "r"((long)stride), + "m"(tc), "m"(*(uint64_t*)mask), "m"(alpha1), "m"(beta1), + "m"(mm_bone), "m"(ff_pb_3F) + ); +} + +static void h264_v_loop_filter_luma_mmx2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + if((tc0[0] & tc0[1]) >= 0) + h264_loop_filter_luma_mmx2(pix, stride, alpha-1, beta-1, tc0); + if((tc0[2] & tc0[3]) >= 0) + h264_loop_filter_luma_mmx2(pix+8, stride, alpha-1, beta-1, tc0+2); +} +static void h264_h_loop_filter_luma_mmx2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + //FIXME: could cut some load/stores by merging transpose with filter + // also, it only needs to transpose 6x8 + uint8_t trans[8*8]; + int i; + for(i=0; i<2; i++, pix+=8*stride, tc0+=2) { + if((tc0[0] & tc0[1]) < 0) + continue; + transpose4x4(trans, pix-4, 8, stride); + transpose4x4(trans +4*8, pix, 8, stride); + transpose4x4(trans+4, pix-4+4*stride, 8, stride); + transpose4x4(trans+4+4*8, pix +4*stride, 8, stride); + h264_loop_filter_luma_mmx2(trans+4*8, 8, alpha-1, beta-1, tc0); + transpose4x4(pix-2, trans +2*8, stride, 8); + transpose4x4(pix-2+4*stride, trans+4+2*8, stride, 8); + } +} + +static inline void h264_loop_filter_chroma_mmx2(uint8_t *pix, int stride, int alpha1, int beta1, int8_t *tc0) +{ + asm volatile( + "movq (%0), %%mm0 \n\t" //p1 + "movq (%0,%2), %%mm1 \n\t" //p0 + "movq (%1), %%mm2 \n\t" //q0 + "movq (%1,%2), %%mm3 \n\t" //q1 + H264_DEBLOCK_MASK(%4, %5) + "movd %3, %%mm6 \n\t" + "punpcklbw %%mm6, %%mm6 \n\t" + "pand %%mm6, %%mm7 \n\t" // mm7 = tc&mask + H264_DEBLOCK_P0_Q0(%6, %7) + "movq %%mm1, (%0,%2) \n\t" + "movq %%mm2, (%1) \n\t" + + :: "r"(pix-2*stride), "r"(pix), "r"((long)stride), + "r"(*(uint32_t*)tc0), + "m"(alpha1), "m"(beta1), "m"(mm_bone), "m"(ff_pb_3F) + ); +} + +static void h264_v_loop_filter_chroma_mmx2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + h264_loop_filter_chroma_mmx2(pix, stride, alpha-1, beta-1, tc0); +} + +static void h264_h_loop_filter_chroma_mmx2(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0) +{ + //FIXME: could cut some load/stores by merging transpose with filter + uint8_t trans[8*4]; + transpose4x4(trans, pix-2, 8, stride); + transpose4x4(trans+4, pix-2+4*stride, 8, stride); + h264_loop_filter_chroma_mmx2(trans+2*8, 8, alpha-1, beta-1, tc0); + transpose4x4(pix-2, trans, stride, 8); + transpose4x4(pix-2+4*stride, trans+4, stride, 8); +} + +// p0 = (p0 + q1 + 2*p1 + 2) >> 2 +#define H264_FILTER_CHROMA4(p0, p1, q1, one) \ + "movq "#p0", %%mm4 \n\t"\ + "pxor "#q1", %%mm4 \n\t"\ + "pand "#one", %%mm4 \n\t" /* mm4 = (p0^q1)&1 */\ + "pavgb "#q1", "#p0" \n\t"\ + "psubusb %%mm4, "#p0" \n\t"\ + "pavgb "#p1", "#p0" \n\t" /* dst = avg(p1, avg(p0,q1) - ((p0^q1)&1)) */\ + +static inline void h264_loop_filter_chroma_intra_mmx2(uint8_t *pix, int stride, int alpha1, int beta1) +{ + asm volatile( + "movq (%0), %%mm0 \n\t" + "movq (%0,%2), %%mm1 \n\t" + "movq (%1), %%mm2 \n\t" + "movq (%1,%2), %%mm3 \n\t" + H264_DEBLOCK_MASK(%3, %4) + "movq %%mm1, %%mm5 \n\t" + "movq %%mm2, %%mm6 \n\t" + H264_FILTER_CHROMA4(%%mm1, %%mm0, %%mm3, %5) //p0' + H264_FILTER_CHROMA4(%%mm2, %%mm3, %%mm0, %5) //q0' + "psubb %%mm5, %%mm1 \n\t" + "psubb %%mm6, %%mm2 \n\t" + "pand %%mm7, %%mm1 \n\t" + "pand %%mm7, %%mm2 \n\t" + "paddb %%mm5, %%mm1 \n\t" + "paddb %%mm6, %%mm2 \n\t" + "movq %%mm1, (%0,%2) \n\t" + "movq %%mm2, (%1) \n\t" + :: "r"(pix-2*stride), "r"(pix), "r"((long)stride), + "m"(alpha1), "m"(beta1), "m"(mm_bone) + ); +} + +static void h264_v_loop_filter_chroma_intra_mmx2(uint8_t *pix, int stride, int alpha, int beta) +{ + h264_loop_filter_chroma_intra_mmx2(pix, stride, alpha-1, beta-1); +} + +static void h264_h_loop_filter_chroma_intra_mmx2(uint8_t *pix, int stride, int alpha, int beta) +{ + //FIXME: could cut some load/stores by merging transpose with filter + uint8_t trans[8*4]; + transpose4x4(trans, pix-2, 8, stride); + transpose4x4(trans+4, pix-2+4*stride, 8, stride); + h264_loop_filter_chroma_intra_mmx2(trans+2*8, 8, alpha-1, beta-1); + transpose4x4(pix-2, trans, stride, 8); + transpose4x4(pix-2+4*stride, trans+4, stride, 8); +} + + +/***********************************/ +/* motion compensation */ + +#define QPEL_H264V(A,B,C,D,E,F,OP)\ + "movd (%0), "#F" \n\t"\ + "movq "#C", %%mm6 \n\t"\ + "paddw "#D", %%mm6 \n\t"\ + "psllw $2, %%mm6 \n\t"\ + "psubw "#B", %%mm6 \n\t"\ + "psubw "#E", %%mm6 \n\t"\ + "pmullw %4, %%mm6 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, "#F" \n\t"\ + "paddw %5, "#A" \n\t"\ + "paddw "#F", "#A" \n\t"\ + "paddw "#A", %%mm6 \n\t"\ + "psraw $5, %%mm6 \n\t"\ + "packuswb %%mm6, %%mm6 \n\t"\ + OP(%%mm6, (%1), A, d)\ + "add %3, %1 \n\t" + +#define QPEL_H264HV(A,B,C,D,E,F,OF)\ + "movd (%0), "#F" \n\t"\ + "movq "#C", %%mm6 \n\t"\ + "paddw "#D", %%mm6 \n\t"\ + "psllw $2, %%mm6 \n\t"\ + "psubw "#B", %%mm6 \n\t"\ + "psubw "#E", %%mm6 \n\t"\ + "pmullw %3, %%mm6 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, "#F" \n\t"\ + "paddw "#F", "#A" \n\t"\ + "paddw "#A", %%mm6 \n\t"\ + "movq %%mm6, "#OF"(%1) \n\t" + +#define QPEL_H264(OPNAME, OP, MMX)\ +static void OPNAME ## h264_qpel4_h_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + int h=4;\ +\ + asm volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movq %5, %%mm4 \n\t"\ + "movq %6, %%mm5 \n\t"\ + "1: \n\t"\ + "movd -1(%0), %%mm1 \n\t"\ + "movd (%0), %%mm2 \n\t"\ + "movd 1(%0), %%mm3 \n\t"\ + "movd 2(%0), %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "paddw %%mm0, %%mm1 \n\t"\ + "paddw %%mm3, %%mm2 \n\t"\ + "movd -2(%0), %%mm0 \n\t"\ + "movd 3(%0), %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "paddw %%mm3, %%mm0 \n\t"\ + "psllw $2, %%mm2 \n\t"\ + "psubw %%mm1, %%mm2 \n\t"\ + "pmullw %%mm4, %%mm2 \n\t"\ + "paddw %%mm5, %%mm0 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"\ + "psraw $5, %%mm0 \n\t"\ + "packuswb %%mm0, %%mm0 \n\t"\ + OP(%%mm0, (%1),%%mm6, d)\ + "add %3, %0 \n\t"\ + "add %4, %1 \n\t"\ + "decl %2 \n\t"\ + " jnz 1b \n\t"\ + : "+a"(src), "+c"(dst), "+m"(h)\ + : "d"((long)srcStride), "S"((long)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ + : "memory"\ + );\ +}\ +static void OPNAME ## h264_qpel4_h_lowpass_l2_ ## MMX(uint8_t *dst, uint8_t *src, uint8_t *src2, int dstStride, int src2Stride){\ + int h=4;\ + asm volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movq %0, %%mm4 \n\t"\ + "movq %1, %%mm5 \n\t"\ + :: "m"(ff_pw_5), "m"(ff_pw_16)\ + );\ + do{\ + asm volatile(\ + "movd -1(%0), %%mm1 \n\t"\ + "movd (%0), %%mm2 \n\t"\ + "movd 1(%0), %%mm3 \n\t"\ + "movd 2(%0), %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "paddw %%mm0, %%mm1 \n\t"\ + "paddw %%mm3, %%mm2 \n\t"\ + "movd -2(%0), %%mm0 \n\t"\ + "movd 3(%0), %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "paddw %%mm3, %%mm0 \n\t"\ + "psllw $2, %%mm2 \n\t"\ + "psubw %%mm1, %%mm2 \n\t"\ + "pmullw %%mm4, %%mm2 \n\t"\ + "paddw %%mm5, %%mm0 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"\ + "movd (%2), %%mm3 \n\t"\ + "psraw $5, %%mm0 \n\t"\ + "packuswb %%mm0, %%mm0 \n\t"\ + PAVGB" %%mm3, %%mm0 \n\t"\ + OP(%%mm0, (%1),%%mm6, d)\ + "add %4, %0 \n\t"\ + "add %4, %1 \n\t"\ + "add %3, %2 \n\t"\ + : "+a"(src), "+c"(dst), "+d"(src2)\ + : "D"((long)src2Stride), "S"((long)dstStride)\ + : "memory"\ + );\ + }while(--h);\ +}\ +static void OPNAME ## h264_qpel4_v_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + src -= 2*srcStride;\ + asm volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movd (%0), %%mm0 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm1 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm2 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm3 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm4 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + QPEL_H264V(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP)\ + QPEL_H264V(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP)\ + QPEL_H264V(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP)\ + QPEL_H264V(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP)\ + \ + : "+a"(src), "+c"(dst)\ + : "S"((long)srcStride), "D"((long)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ + : "memory"\ + );\ +}\ +static void OPNAME ## h264_qpel4_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + int h=4;\ + int w=3;\ + src -= 2*srcStride+2;\ + while(w--){\ + asm volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movd (%0), %%mm0 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm1 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm2 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm3 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm4 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + QPEL_H264HV(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, 0*8*3)\ + QPEL_H264HV(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, 1*8*3)\ + QPEL_H264HV(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, 2*8*3)\ + QPEL_H264HV(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, 3*8*3)\ + \ + : "+a"(src)\ + : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5)\ + : "memory"\ + );\ + tmp += 4;\ + src += 4 - 9*srcStride;\ + }\ + tmp -= 3*4;\ + asm volatile(\ + "movq %4, %%mm6 \n\t"\ + "1: \n\t"\ + "movq (%0), %%mm0 \n\t"\ + "paddw 10(%0), %%mm0 \n\t"\ + "movq 2(%0), %%mm1 \n\t"\ + "paddw 8(%0), %%mm1 \n\t"\ + "movq 4(%0), %%mm2 \n\t"\ + "paddw 6(%0), %%mm2 \n\t"\ + "psubw %%mm1, %%mm0 \n\t"/*a-b (abccba)*/\ + "psraw $2, %%mm0 \n\t"/*(a-b)/4 */\ + "psubw %%mm1, %%mm0 \n\t"/*(a-b)/4-b */\ + "paddsw %%mm2, %%mm0 \n\t"\ + "psraw $2, %%mm0 \n\t"/*((a-b)/4-b+c)/4 */\ + "paddw %%mm6, %%mm2 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"/*(a-5*b+20*c)/16 +32 */\ + "psraw $6, %%mm0 \n\t"\ + "packuswb %%mm0, %%mm0 \n\t"\ + OP(%%mm0, (%1),%%mm7, d)\ + "add $24, %0 \n\t"\ + "add %3, %1 \n\t"\ + "decl %2 \n\t"\ + " jnz 1b \n\t"\ + : "+a"(tmp), "+c"(dst), "+m"(h)\ + : "S"((long)dstStride), "m"(ff_pw_32)\ + : "memory"\ + );\ +}\ +\ +static void OPNAME ## h264_qpel8_h_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + int h=8;\ + asm volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movq %5, %%mm6 \n\t"\ + "1: \n\t"\ + "movq (%0), %%mm0 \n\t"\ + "movq 1(%0), %%mm2 \n\t"\ + "movq %%mm0, %%mm1 \n\t"\ + "movq %%mm2, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpckhbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpckhbw %%mm7, %%mm3 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"\ + "paddw %%mm3, %%mm1 \n\t"\ + "psllw $2, %%mm0 \n\t"\ + "psllw $2, %%mm1 \n\t"\ + "movq -1(%0), %%mm2 \n\t"\ + "movq 2(%0), %%mm4 \n\t"\ + "movq %%mm2, %%mm3 \n\t"\ + "movq %%mm4, %%mm5 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpckhbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + "punpckhbw %%mm7, %%mm5 \n\t"\ + "paddw %%mm4, %%mm2 \n\t"\ + "paddw %%mm3, %%mm5 \n\t"\ + "psubw %%mm2, %%mm0 \n\t"\ + "psubw %%mm5, %%mm1 \n\t"\ + "pmullw %%mm6, %%mm0 \n\t"\ + "pmullw %%mm6, %%mm1 \n\t"\ + "movd -2(%0), %%mm2 \n\t"\ + "movd 7(%0), %%mm5 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm5 \n\t"\ + "paddw %%mm3, %%mm2 \n\t"\ + "paddw %%mm5, %%mm4 \n\t"\ + "movq %6, %%mm5 \n\t"\ + "paddw %%mm5, %%mm2 \n\t"\ + "paddw %%mm5, %%mm4 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"\ + "paddw %%mm4, %%mm1 \n\t"\ + "psraw $5, %%mm0 \n\t"\ + "psraw $5, %%mm1 \n\t"\ + "packuswb %%mm1, %%mm0 \n\t"\ + OP(%%mm0, (%1),%%mm5, q)\ + "add %3, %0 \n\t"\ + "add %4, %1 \n\t"\ + "decl %2 \n\t"\ + " jnz 1b \n\t"\ + : "+a"(src), "+c"(dst), "+m"(h)\ + : "d"((long)srcStride), "S"((long)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ + : "memory"\ + );\ +}\ +\ +static void OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(uint8_t *dst, uint8_t *src, uint8_t *src2, int dstStride, int src2Stride){\ + int h=8;\ + asm volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movq %0, %%mm6 \n\t"\ + :: "m"(ff_pw_5)\ + );\ + do{\ + asm volatile(\ + "movq (%0), %%mm0 \n\t"\ + "movq 1(%0), %%mm2 \n\t"\ + "movq %%mm0, %%mm1 \n\t"\ + "movq %%mm2, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpckhbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpckhbw %%mm7, %%mm3 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"\ + "paddw %%mm3, %%mm1 \n\t"\ + "psllw $2, %%mm0 \n\t"\ + "psllw $2, %%mm1 \n\t"\ + "movq -1(%0), %%mm2 \n\t"\ + "movq 2(%0), %%mm4 \n\t"\ + "movq %%mm2, %%mm3 \n\t"\ + "movq %%mm4, %%mm5 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpckhbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + "punpckhbw %%mm7, %%mm5 \n\t"\ + "paddw %%mm4, %%mm2 \n\t"\ + "paddw %%mm3, %%mm5 \n\t"\ + "psubw %%mm2, %%mm0 \n\t"\ + "psubw %%mm5, %%mm1 \n\t"\ + "pmullw %%mm6, %%mm0 \n\t"\ + "pmullw %%mm6, %%mm1 \n\t"\ + "movd -2(%0), %%mm2 \n\t"\ + "movd 7(%0), %%mm5 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm5 \n\t"\ + "paddw %%mm3, %%mm2 \n\t"\ + "paddw %%mm5, %%mm4 \n\t"\ + "movq %5, %%mm5 \n\t"\ + "paddw %%mm5, %%mm2 \n\t"\ + "paddw %%mm5, %%mm4 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"\ + "paddw %%mm4, %%mm1 \n\t"\ + "psraw $5, %%mm0 \n\t"\ + "psraw $5, %%mm1 \n\t"\ + "movq (%2), %%mm4 \n\t"\ + "packuswb %%mm1, %%mm0 \n\t"\ + PAVGB" %%mm4, %%mm0 \n\t"\ + OP(%%mm0, (%1),%%mm5, q)\ + "add %4, %0 \n\t"\ + "add %4, %1 \n\t"\ + "add %3, %2 \n\t"\ + : "+a"(src), "+c"(dst), "+d"(src2)\ + : "D"((long)src2Stride), "S"((long)dstStride),\ + "m"(ff_pw_16)\ + : "memory"\ + );\ + }while(--h);\ +}\ +\ +static inline void OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h){\ + int w= 2;\ + src -= 2*srcStride;\ + \ + while(w--){\ + asm volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movd (%0), %%mm0 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm1 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm2 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm3 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm4 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + QPEL_H264V(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP)\ + QPEL_H264V(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP)\ + QPEL_H264V(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP)\ + QPEL_H264V(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP)\ + QPEL_H264V(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, OP)\ + QPEL_H264V(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, OP)\ + QPEL_H264V(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP)\ + QPEL_H264V(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP)\ + \ + : "+a"(src), "+c"(dst)\ + : "S"((long)srcStride), "D"((long)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ + : "memory"\ + );\ + if(h==16){\ + asm volatile(\ + QPEL_H264V(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP)\ + QPEL_H264V(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP)\ + QPEL_H264V(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, OP)\ + QPEL_H264V(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, OP)\ + QPEL_H264V(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP)\ + QPEL_H264V(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP)\ + QPEL_H264V(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP)\ + QPEL_H264V(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP)\ + \ + : "+a"(src), "+c"(dst)\ + : "S"((long)srcStride), "D"((long)dstStride), "m"(ff_pw_5), "m"(ff_pw_16)\ + : "memory"\ + );\ + }\ + src += 4-(h+5)*srcStride;\ + dst += 4-h*dstStride;\ + }\ +}\ +static inline void OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ + int h = size;\ + int w = (size+8)>>2;\ + src -= 2*srcStride+2;\ + while(w--){\ + asm volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movd (%0), %%mm0 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm1 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm2 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm3 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm4 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + QPEL_H264HV(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, 0*48)\ + QPEL_H264HV(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, 1*48)\ + QPEL_H264HV(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, 2*48)\ + QPEL_H264HV(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, 3*48)\ + QPEL_H264HV(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, 4*48)\ + QPEL_H264HV(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, 5*48)\ + QPEL_H264HV(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, 6*48)\ + QPEL_H264HV(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, 7*48)\ + : "+a"(src)\ + : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5)\ + : "memory"\ + );\ + if(size==16){\ + asm volatile(\ + QPEL_H264HV(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, 8*48)\ + QPEL_H264HV(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, 9*48)\ + QPEL_H264HV(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, 10*48)\ + QPEL_H264HV(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, 11*48)\ + QPEL_H264HV(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, 12*48)\ + QPEL_H264HV(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, 13*48)\ + QPEL_H264HV(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, 14*48)\ + QPEL_H264HV(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, 15*48)\ + : "+a"(src)\ + : "c"(tmp), "S"((long)srcStride), "m"(ff_pw_5)\ + : "memory"\ + );\ + }\ + tmp += 4;\ + src += 4 - (size+5)*srcStride;\ + }\ + tmp -= size+8;\ + w = size>>4;\ + do{\ + h = size;\ + asm volatile(\ + "movq %4, %%mm6 \n\t"\ + "1: \n\t"\ + "movq (%0), %%mm0 \n\t"\ + "movq 8(%0), %%mm3 \n\t"\ + "movq 2(%0), %%mm1 \n\t"\ + "movq 10(%0), %%mm4 \n\t"\ + "paddw %%mm4, %%mm0 \n\t"\ + "paddw %%mm3, %%mm1 \n\t"\ + "paddw 18(%0), %%mm3 \n\t"\ + "paddw 16(%0), %%mm4 \n\t"\ + "movq 4(%0), %%mm2 \n\t"\ + "movq 12(%0), %%mm5 \n\t"\ + "paddw 6(%0), %%mm2 \n\t"\ + "paddw 14(%0), %%mm5 \n\t"\ + "psubw %%mm1, %%mm0 \n\t"\ + "psubw %%mm4, %%mm3 \n\t"\ + "psraw $2, %%mm0 \n\t"\ + "psraw $2, %%mm3 \n\t"\ + "psubw %%mm1, %%mm0 \n\t"\ + "psubw %%mm4, %%mm3 \n\t"\ + "paddsw %%mm2, %%mm0 \n\t"\ + "paddsw %%mm5, %%mm3 \n\t"\ + "psraw $2, %%mm0 \n\t"\ + "psraw $2, %%mm3 \n\t"\ + "paddw %%mm6, %%mm2 \n\t"\ + "paddw %%mm6, %%mm5 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"\ + "paddw %%mm5, %%mm3 \n\t"\ + "psraw $6, %%mm0 \n\t"\ + "psraw $6, %%mm3 \n\t"\ + "packuswb %%mm3, %%mm0 \n\t"\ + OP(%%mm0, (%1),%%mm7, q)\ + "add $48, %0 \n\t"\ + "add %3, %1 \n\t"\ + "decl %2 \n\t"\ + " jnz 1b \n\t"\ + : "+a"(tmp), "+c"(dst), "+m"(h)\ + : "S"((long)dstStride), "m"(ff_pw_32)\ + : "memory"\ + );\ + tmp += 8 - size*24;\ + dst += 8 - size*dstStride;\ + }while(w--);\ +}\ +\ +static void OPNAME ## h264_qpel8_v_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static void OPNAME ## h264_qpel16_v_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 16);\ + OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +}\ +\ +static void OPNAME ## h264_qpel16_h_lowpass_ ## MMX(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){\ + OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ +}\ +\ +static void OPNAME ## h264_qpel16_h_lowpass_l2_ ## MMX(uint8_t *dst, uint8_t *src, uint8_t *src2, int dstStride, int src2Stride){\ + OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ + src += 8*dstStride;\ + dst += 8*dstStride;\ + src2 += 8*src2Stride;\ + OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ +}\ +\ +static void OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst , tmp , src , dstStride, tmpStride, srcStride, 8);\ +}\ +\ +static void OPNAME ## h264_qpel16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst , tmp , src , dstStride, tmpStride, srcStride, 16);\ +}\ +\ +static void OPNAME ## pixels4_l2_shift5_ ## MMX(uint8_t *dst, int16_t *src16, uint8_t *src8, int dstStride, int src8Stride, int h)\ +{\ + asm volatile(\ + "movq %5, %%mm6 \n\t"\ + "movq (%1), %%mm0 \n\t"\ + "movq 24(%1), %%mm1 \n\t"\ + "paddw %%mm6, %%mm0 \n\t"\ + "paddw %%mm6, %%mm1 \n\t"\ + "psraw $5, %%mm0 \n\t"\ + "psraw $5, %%mm1 \n\t"\ + "packuswb %%mm0, %%mm0 \n\t"\ + "packuswb %%mm1, %%mm1 \n\t"\ + PAVGB" (%0), %%mm0 \n\t"\ + PAVGB" (%0,%3), %%mm1 \n\t"\ + OP(%%mm0, (%2), %%mm4, d)\ + OP(%%mm1, (%2,%4), %%mm5, d)\ + "lea (%0,%3,2), %0 \n\t"\ + "lea (%2,%4,2), %2 \n\t"\ + "movq 48(%1), %%mm0 \n\t"\ + "movq 72(%1), %%mm1 \n\t"\ + "paddw %%mm6, %%mm0 \n\t"\ + "paddw %%mm6, %%mm1 \n\t"\ + "psraw $5, %%mm0 \n\t"\ + "psraw $5, %%mm1 \n\t"\ + "packuswb %%mm0, %%mm0 \n\t"\ + "packuswb %%mm1, %%mm1 \n\t"\ + PAVGB" (%0), %%mm0 \n\t"\ + PAVGB" (%0,%3), %%mm1 \n\t"\ + OP(%%mm0, (%2), %%mm4, d)\ + OP(%%mm1, (%2,%4), %%mm5, d)\ + :"+a"(src8), "+c"(src16), "+d"(dst)\ + :"S"((long)src8Stride), "D"((long)dstStride), "m"(ff_pw_16)\ + :"memory");\ +}\ +static void OPNAME ## pixels8_l2_shift5_ ## MMX(uint8_t *dst, int16_t *src16, uint8_t *src8, int dstStride, int src8Stride, int h)\ +{\ + asm volatile(\ + "movq %0, %%mm6 \n\t"\ + ::"m"(ff_pw_16)\ + );\ + while(h--){\ + asm volatile(\ + "movq (%1), %%mm0 \n\t"\ + "movq 8(%1), %%mm1 \n\t"\ + "paddw %%mm6, %%mm0 \n\t"\ + "paddw %%mm6, %%mm1 \n\t"\ + "psraw $5, %%mm0 \n\t"\ + "psraw $5, %%mm1 \n\t"\ + "packuswb %%mm1, %%mm0 \n\t"\ + PAVGB" (%0), %%mm0 \n\t"\ + OP(%%mm0, (%2), %%mm5, q)\ + ::"a"(src8), "c"(src16), "d"(dst)\ + :"memory");\ + src8 += src8Stride;\ + src16 += 24;\ + dst += dstStride;\ + }\ +}\ +static void OPNAME ## pixels16_l2_shift5_ ## MMX(uint8_t *dst, int16_t *src16, uint8_t *src8, int dstStride, int src8Stride, int h)\ +{\ + OPNAME ## pixels8_l2_shift5_ ## MMX(dst , src16 , src8 , dstStride, src8Stride, h);\ + OPNAME ## pixels8_l2_shift5_ ## MMX(dst+8, src16+8, src8+8, dstStride, src8Stride, h);\ +}\ + + +#define H264_MC(OPNAME, SIZE, MMX) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## MMX (uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## pixels ## SIZE ## _mmx(dst, src, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src+1, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*SIZE/8];\ + uint8_t * const half= (uint8_t*)temp;\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(half, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src, half, stride, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*SIZE/8];\ + uint8_t * const half= (uint8_t*)temp;\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(half, src, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src+stride, half, stride, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*SIZE/8];\ + uint8_t * const halfV= (uint8_t*)temp;\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(halfV, src, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*SIZE/8];\ + uint8_t * const halfV= (uint8_t*)temp;\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(halfV, src+1, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*SIZE/8];\ + uint8_t * const halfV= (uint8_t*)temp;\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(halfV, src, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*SIZE/8];\ + uint8_t * const halfV= (uint8_t*)temp;\ + put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(halfV, src+1, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*(SIZE<8?12:24)/4];\ + int16_t * const tmp= (int16_t*)temp;\ + OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(dst, tmp, src, stride, SIZE, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*(SIZE<8?12:24)/4 + SIZE*SIZE/8];\ + uint8_t * const halfHV= (uint8_t*)temp;\ + int16_t * const tmp= ((int16_t*)temp) + SIZE*SIZE/2;\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, tmp, src, SIZE, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfHV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*(SIZE<8?12:24)/4 + SIZE*SIZE/8];\ + uint8_t * const halfHV= (uint8_t*)temp;\ + int16_t * const tmp= ((int16_t*)temp) + SIZE*SIZE/2;\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, tmp, src, SIZE, SIZE, stride);\ + OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfHV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*(SIZE<8?12:24)/4 + SIZE*SIZE/8];\ + int16_t * const halfV= ((int16_t*)temp) + SIZE*SIZE/2;\ + uint8_t * const halfHV= ((uint8_t*)temp);\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_shift5_ ## MMX(dst, halfV+2, halfHV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## MMX(uint8_t *dst, uint8_t *src, int stride){\ + uint64_t temp[SIZE*(SIZE<8?12:24)/4 + SIZE*SIZE/8];\ + int16_t * const halfV= ((int16_t*)temp) + SIZE*SIZE/2;\ + uint8_t * const halfHV= ((uint8_t*)temp);\ + put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + OPNAME ## pixels ## SIZE ## _l2_shift5_ ## MMX(dst, halfV+3, halfHV, stride, SIZE, SIZE);\ +}\ + + +#define PUT_OP(a,b,temp, size) "mov" #size " " #a ", " #b " \n\t" +#define AVG_3DNOW_OP(a,b,temp, size) \ +"mov" #size " " #b ", " #temp " \n\t"\ +"pavgusb " #temp ", " #a " \n\t"\ +"mov" #size " " #a ", " #b " \n\t" +#define AVG_MMX2_OP(a,b,temp, size) \ +"mov" #size " " #b ", " #temp " \n\t"\ +"pavgb " #temp ", " #a " \n\t"\ +"mov" #size " " #a ", " #b " \n\t" + +#define PAVGB "pavgusb" +QPEL_H264(put_, PUT_OP, 3dnow) +QPEL_H264(avg_, AVG_3DNOW_OP, 3dnow) +#undef PAVGB +#define PAVGB "pavgb" +QPEL_H264(put_, PUT_OP, mmx2) +QPEL_H264(avg_, AVG_MMX2_OP, mmx2) +#undef PAVGB + +H264_MC(put_, 4, 3dnow) +H264_MC(put_, 8, 3dnow) +H264_MC(put_, 16,3dnow) +H264_MC(avg_, 4, 3dnow) +H264_MC(avg_, 8, 3dnow) +H264_MC(avg_, 16,3dnow) +H264_MC(put_, 4, mmx2) +H264_MC(put_, 8, mmx2) +H264_MC(put_, 16,mmx2) +H264_MC(avg_, 4, mmx2) +H264_MC(avg_, 8, mmx2) +H264_MC(avg_, 16,mmx2) + + +#define H264_CHROMA_OP(S,D) +#define H264_CHROMA_OP4(S,D,T) +#define H264_CHROMA_MC8_TMPL put_h264_chroma_mc8_mmx +#define H264_CHROMA_MC4_TMPL put_h264_chroma_mc4_mmx +#define H264_CHROMA_MC2_TMPL put_h264_chroma_mc2_mmx2 +#define H264_CHROMA_MC8_MV0 put_pixels8_mmx +#include "dsputil_h264_template_mmx.c" +#undef H264_CHROMA_OP +#undef H264_CHROMA_OP4 +#undef H264_CHROMA_MC8_TMPL +#undef H264_CHROMA_MC4_TMPL +#undef H264_CHROMA_MC2_TMPL +#undef H264_CHROMA_MC8_MV0 + +#define H264_CHROMA_OP(S,D) "pavgb " #S ", " #D " \n\t" +#define H264_CHROMA_OP4(S,D,T) "movd " #S ", " #T " \n\t"\ + "pavgb " #T ", " #D " \n\t" +#define H264_CHROMA_MC8_TMPL avg_h264_chroma_mc8_mmx2 +#define H264_CHROMA_MC4_TMPL avg_h264_chroma_mc4_mmx2 +#define H264_CHROMA_MC2_TMPL avg_h264_chroma_mc2_mmx2 +#define H264_CHROMA_MC8_MV0 avg_pixels8_mmx2 +#include "dsputil_h264_template_mmx.c" +#undef H264_CHROMA_OP +#undef H264_CHROMA_OP4 +#undef H264_CHROMA_MC8_TMPL +#undef H264_CHROMA_MC4_TMPL +#undef H264_CHROMA_MC2_TMPL +#undef H264_CHROMA_MC8_MV0 + +#define H264_CHROMA_OP(S,D) "pavgusb " #S ", " #D " \n\t" +#define H264_CHROMA_OP4(S,D,T) "movd " #S ", " #T " \n\t"\ + "pavgusb " #T ", " #D " \n\t" +#define H264_CHROMA_MC8_TMPL avg_h264_chroma_mc8_3dnow +#define H264_CHROMA_MC4_TMPL avg_h264_chroma_mc4_3dnow +#define H264_CHROMA_MC8_MV0 avg_pixels8_3dnow +#include "dsputil_h264_template_mmx.c" +#undef H264_CHROMA_OP +#undef H264_CHROMA_OP4 +#undef H264_CHROMA_MC8_TMPL +#undef H264_CHROMA_MC4_TMPL +#undef H264_CHROMA_MC8_MV0 + +/***********************************/ +/* weighted prediction */ + +static inline void ff_h264_weight_WxH_mmx2(uint8_t *dst, int stride, int log2_denom, int weight, int offset, int w, int h) +{ + int x, y; + offset <<= log2_denom; + offset += (1 << log2_denom) >> 1; + asm volatile( + "movd %0, %%mm4 \n\t" + "movd %1, %%mm5 \n\t" + "movd %2, %%mm6 \n\t" + "pshufw $0, %%mm4, %%mm4 \n\t" + "pshufw $0, %%mm5, %%mm5 \n\t" + "pxor %%mm7, %%mm7 \n\t" + :: "g"(weight), "g"(offset), "g"(log2_denom) + ); + for(y=0; y + * + * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. + * + * mpeg2dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "common.h" +#include "../dsputil.h" + +#include "mmx.h" + +#define ATTR_ALIGN(align) __attribute__ ((__aligned__ (align))) + +#define ROW_SHIFT 11 +#define COL_SHIFT 6 + +#define round(bias) ((int)(((bias)+0.5) * (1<> ROW_SHIFT; + row[1] = (a1 + b1) >> ROW_SHIFT; + row[2] = (a2 + b2) >> ROW_SHIFT; + row[3] = (a3 + b3) >> ROW_SHIFT; + row[4] = (a3 - b3) >> ROW_SHIFT; + row[5] = (a2 - b2) >> ROW_SHIFT; + row[6] = (a1 - b1) >> ROW_SHIFT; + row[7] = (a0 - b0) >> ROW_SHIFT; +} +#endif + + +/* MMXEXT row IDCT */ + +#define mmxext_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, -c4, -c2, \ + c4, c6, c4, c6, \ + c1, c3, -c1, -c5, \ + c5, c7, c3, -c7, \ + c4, -c6, c4, -c6, \ + -c4, c2, c4, -c2, \ + c5, -c1, c3, -c1, \ + c7, c3, c7, -c5 } + +static inline void mmxext_row_head (int16_t * row, int offset, const int16_t * table) +{ + movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + + movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 + movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + + movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 + movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + + movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 + pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 + + pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 +} + +static inline void mmxext_row (const int16_t * table, const int32_t * rounder) +{ + movq_m2r (*(table+8), mm1); // mm1 = -C5 -C1 C3 C1 + pmaddwd_r2r (mm2, mm4); // mm4 = C4*x0+C6*x2 C4*x4+C6*x6 + + pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x4-C6*x6 C4*x0-C6*x2 + pshufw_r2r (mm6, mm6, 0x4e); // mm6 = x3 x1 x7 x5 + + movq_m2r (*(table+12), mm7); // mm7 = -C7 C3 C7 C5 + pmaddwd_r2r (mm5, mm1); // mm1 = -C1*x5-C5*x7 C1*x1+C3*x3 + + paddd_m2r (*rounder, mm3); // mm3 += rounder + pmaddwd_r2r (mm6, mm7); // mm7 = C3*x1-C7*x3 C5*x5+C7*x7 + + pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x0-C2*x2 -C4*x4+C2*x6 + paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder + + pmaddwd_m2r (*(table+24), mm5); // mm5 = C3*x5-C1*x7 C5*x1-C1*x3 + movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder + + pmaddwd_m2r (*(table+28), mm6); // mm6 = C7*x1-C5*x3 C7*x5+C3*x7 + paddd_r2r (mm7, mm1); // mm1 = b1 b0 + + paddd_m2r (*rounder, mm0); // mm0 += rounder + psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder + + psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 + paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder + + paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder + psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 + + paddd_r2r (mm6, mm5); // mm5 = b3 b2 + movq_r2r (mm0, mm4); // mm4 = a3 a2 + rounder + + paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder + psubd_r2r (mm5, mm4); // mm4 = a3-b3 a2-b2 + rounder +} + +static inline void mmxext_row_tail (int16_t * row, int store) +{ + psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + + psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 + + packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + + packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 + + movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 + pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 + + /* slot */ + + movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 +} + +static inline void mmxext_row_mid (int16_t * row, int store, + int offset, const int16_t * table) +{ + movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + + movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 + psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 + + packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + + packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 + movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + + movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 + pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 + + movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 + movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 + + pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 + + movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 + pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 +} + + +/* MMX row IDCT */ + +#define mmx_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, c4, c6, \ + c4, c6, -c4, -c2, \ + c1, c3, c3, -c7, \ + c5, c7, -c1, -c5, \ + c4, -c6, c4, -c2, \ + -c4, c2, c4, -c6, \ + c5, -c1, c7, -c5, \ + c7, c3, c3, -c1 } + +static inline void mmx_row_head (int16_t * row, int offset, const int16_t * table) +{ + movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + + movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 + movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + + movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 + movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + + punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 + + movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 + pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 + + movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 + punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 +} + +static inline void mmx_row (const int16_t * table, const int32_t * rounder) +{ + pmaddwd_r2r (mm2, mm4); // mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 + punpckldq_r2r (mm5, mm5); // mm5 = x3 x1 x3 x1 + + pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x0-C2*x2 C4*x0-C6*x2 + punpckhdq_r2r (mm6, mm6); // mm6 = x7 x5 x7 x5 + + movq_m2r (*(table+12), mm7); // mm7 = -C5 -C1 C7 C5 + pmaddwd_r2r (mm5, mm1); // mm1 = C3*x1-C7*x3 C1*x1+C3*x3 + + paddd_m2r (*rounder, mm3); // mm3 += rounder + pmaddwd_r2r (mm6, mm7); // mm7 = -C1*x5-C5*x7 C5*x5+C7*x7 + + pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x4-C6*x6 -C4*x4+C2*x6 + paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder + + pmaddwd_m2r (*(table+24), mm5); // mm5 = C7*x1-C5*x3 C5*x1-C1*x3 + movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder + + pmaddwd_m2r (*(table+28), mm6); // mm6 = C3*x5-C1*x7 C7*x5+C3*x7 + paddd_r2r (mm7, mm1); // mm1 = b1 b0 + + paddd_m2r (*rounder, mm0); // mm0 += rounder + psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder + + psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 + paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder + + paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder + psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 + + paddd_r2r (mm6, mm5); // mm5 = b3 b2 + movq_r2r (mm0, mm7); // mm7 = a3 a2 + rounder + + paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder + psubd_r2r (mm5, mm7); // mm7 = a3-b3 a2-b2 + rounder +} + +static inline void mmx_row_tail (int16_t * row, int store) +{ + psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + + psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 + + packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + + packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 + + movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 + movq_r2r (mm7, mm4); // mm4 = y6 y7 y4 y5 + + pslld_i2r (16, mm7); // mm7 = y7 0 y5 0 + + psrld_i2r (16, mm4); // mm4 = 0 y6 0 y4 + + por_r2r (mm4, mm7); // mm7 = y7 y6 y5 y4 + + /* slot */ + + movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 +} + +static inline void mmx_row_mid (int16_t * row, int store, + int offset, const int16_t * table) +{ + movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 + psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 + + movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 + psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 + + packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 + movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 + + packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 + movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 + + movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 + movq_r2r (mm7, mm1); // mm1 = y6 y7 y4 y5 + + punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 + psrld_i2r (16, mm7); // mm7 = 0 y6 0 y4 + + movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 + pslld_i2r (16, mm1); // mm1 = y7 0 y5 0 + + movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 + por_r2r (mm1, mm7); // mm7 = y7 y6 y5 y4 + + movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 + punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 + + movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 + pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 +} + + +#if 0 +// C column IDCT - its just here to document the MMXEXT and MMX versions +static inline void idct_col (int16_t * col, int offset) +{ +/* multiplication - as implemented on mmx */ +#define F(c,x) (((c) * (x)) >> 16) + +/* saturation - it helps us handle torture test cases */ +#define S(x) (((x)>32767) ? 32767 : ((x)<-32768) ? -32768 : (x)) + + int16_t x0, x1, x2, x3, x4, x5, x6, x7; + int16_t y0, y1, y2, y3, y4, y5, y6, y7; + int16_t a0, a1, a2, a3, b0, b1, b2, b3; + int16_t u04, v04, u26, v26, u17, v17, u35, v35, u12, v12; + + col += offset; + + x0 = col[0*8]; + x1 = col[1*8]; + x2 = col[2*8]; + x3 = col[3*8]; + x4 = col[4*8]; + x5 = col[5*8]; + x6 = col[6*8]; + x7 = col[7*8]; + + u04 = S (x0 + x4); + v04 = S (x0 - x4); + u26 = S (F (T2, x6) + x2); + v26 = S (F (T2, x2) - x6); + + a0 = S (u04 + u26); + a1 = S (v04 + v26); + a2 = S (v04 - v26); + a3 = S (u04 - u26); + + u17 = S (F (T1, x7) + x1); + v17 = S (F (T1, x1) - x7); + u35 = S (F (T3, x5) + x3); + v35 = S (F (T3, x3) - x5); + + b0 = S (u17 + u35); + b3 = S (v17 - v35); + u12 = S (u17 - u35); + v12 = S (v17 + v35); + u12 = S (2 * F (C4, u12)); + v12 = S (2 * F (C4, v12)); + b1 = S (u12 + v12); + b2 = S (u12 - v12); + + y0 = S (a0 + b0) >> COL_SHIFT; + y1 = S (a1 + b1) >> COL_SHIFT; + y2 = S (a2 + b2) >> COL_SHIFT; + y3 = S (a3 + b3) >> COL_SHIFT; + + y4 = S (a3 - b3) >> COL_SHIFT; + y5 = S (a2 - b2) >> COL_SHIFT; + y6 = S (a1 - b1) >> COL_SHIFT; + y7 = S (a0 - b0) >> COL_SHIFT; + + col[0*8] = y0; + col[1*8] = y1; + col[2*8] = y2; + col[3*8] = y3; + col[4*8] = y4; + col[5*8] = y5; + col[6*8] = y6; + col[7*8] = y7; +} +#endif + + +// MMX column IDCT +static inline void idct_col (int16_t * col, int offset) +{ +#define T1 13036 +#define T2 27146 +#define T3 43790 +#define C4 23170 + + static const short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; + static const short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; + static const short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; + static const short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; + + /* column code adapted from peter gubanov */ + /* http://www.elecard.com/peter/idct.shtml */ + + movq_m2r (*_T1, mm0); // mm0 = T1 + + movq_m2r (*(col+offset+1*8), mm1); // mm1 = x1 + movq_r2r (mm0, mm2); // mm2 = T1 + + movq_m2r (*(col+offset+7*8), mm4); // mm4 = x7 + pmulhw_r2r (mm1, mm0); // mm0 = T1*x1 + + movq_m2r (*_T3, mm5); // mm5 = T3 + pmulhw_r2r (mm4, mm2); // mm2 = T1*x7 + + movq_m2r (*(col+offset+5*8), mm6); // mm6 = x5 + movq_r2r (mm5, mm7); // mm7 = T3-1 + + movq_m2r (*(col+offset+3*8), mm3); // mm3 = x3 + psubsw_r2r (mm4, mm0); // mm0 = v17 + + movq_m2r (*_T2, mm4); // mm4 = T2 + pmulhw_r2r (mm3, mm5); // mm5 = (T3-1)*x3 + + paddsw_r2r (mm2, mm1); // mm1 = u17 + pmulhw_r2r (mm6, mm7); // mm7 = (T3-1)*x5 + + /* slot */ + + movq_r2r (mm4, mm2); // mm2 = T2 + paddsw_r2r (mm3, mm5); // mm5 = T3*x3 + + pmulhw_m2r (*(col+offset+2*8), mm4);// mm4 = T2*x2 + paddsw_r2r (mm6, mm7); // mm7 = T3*x5 + + psubsw_r2r (mm6, mm5); // mm5 = v35 + paddsw_r2r (mm3, mm7); // mm7 = u35 + + movq_m2r (*(col+offset+6*8), mm3); // mm3 = x6 + movq_r2r (mm0, mm6); // mm6 = v17 + + pmulhw_r2r (mm3, mm2); // mm2 = T2*x6 + psubsw_r2r (mm5, mm0); // mm0 = b3 + + psubsw_r2r (mm3, mm4); // mm4 = v26 + paddsw_r2r (mm6, mm5); // mm5 = v12 + + movq_r2m (mm0, *(col+offset+3*8)); // save b3 in scratch0 + movq_r2r (mm1, mm6); // mm6 = u17 + + paddsw_m2r (*(col+offset+2*8), mm2);// mm2 = u26 + paddsw_r2r (mm7, mm6); // mm6 = b0 + + psubsw_r2r (mm7, mm1); // mm1 = u12 + movq_r2r (mm1, mm7); // mm7 = u12 + + movq_m2r (*(col+offset+0*8), mm3); // mm3 = x0 + paddsw_r2r (mm5, mm1); // mm1 = u12+v12 + + movq_m2r (*_C4, mm0); // mm0 = C4/2 + psubsw_r2r (mm5, mm7); // mm7 = u12-v12 + + movq_r2m (mm6, *(col+offset+5*8)); // save b0 in scratch1 + pmulhw_r2r (mm0, mm1); // mm1 = b1/2 + + movq_r2r (mm4, mm6); // mm6 = v26 + pmulhw_r2r (mm0, mm7); // mm7 = b2/2 + + movq_m2r (*(col+offset+4*8), mm5); // mm5 = x4 + movq_r2r (mm3, mm0); // mm0 = x0 + + psubsw_r2r (mm5, mm3); // mm3 = v04 + paddsw_r2r (mm5, mm0); // mm0 = u04 + + paddsw_r2r (mm3, mm4); // mm4 = a1 + movq_r2r (mm0, mm5); // mm5 = u04 + + psubsw_r2r (mm6, mm3); // mm3 = a2 + paddsw_r2r (mm2, mm5); // mm5 = a0 + + paddsw_r2r (mm1, mm1); // mm1 = b1 + psubsw_r2r (mm2, mm0); // mm0 = a3 + + paddsw_r2r (mm7, mm7); // mm7 = b2 + movq_r2r (mm3, mm2); // mm2 = a2 + + movq_r2r (mm4, mm6); // mm6 = a1 + paddsw_r2r (mm7, mm3); // mm3 = a2+b2 + + psraw_i2r (COL_SHIFT, mm3); // mm3 = y2 + paddsw_r2r (mm1, mm4); // mm4 = a1+b1 + + psraw_i2r (COL_SHIFT, mm4); // mm4 = y1 + psubsw_r2r (mm1, mm6); // mm6 = a1-b1 + + movq_m2r (*(col+offset+5*8), mm1); // mm1 = b0 + psubsw_r2r (mm7, mm2); // mm2 = a2-b2 + + psraw_i2r (COL_SHIFT, mm6); // mm6 = y6 + movq_r2r (mm5, mm7); // mm7 = a0 + + movq_r2m (mm4, *(col+offset+1*8)); // save y1 + psraw_i2r (COL_SHIFT, mm2); // mm2 = y5 + + movq_r2m (mm3, *(col+offset+2*8)); // save y2 + paddsw_r2r (mm1, mm5); // mm5 = a0+b0 + + movq_m2r (*(col+offset+3*8), mm4); // mm4 = b3 + psubsw_r2r (mm1, mm7); // mm7 = a0-b0 + + psraw_i2r (COL_SHIFT, mm5); // mm5 = y0 + movq_r2r (mm0, mm3); // mm3 = a3 + + movq_r2m (mm2, *(col+offset+5*8)); // save y5 + psubsw_r2r (mm4, mm3); // mm3 = a3-b3 + + psraw_i2r (COL_SHIFT, mm7); // mm7 = y7 + paddsw_r2r (mm0, mm4); // mm4 = a3+b3 + + movq_r2m (mm5, *(col+offset+0*8)); // save y0 + psraw_i2r (COL_SHIFT, mm3); // mm3 = y4 + + movq_r2m (mm6, *(col+offset+6*8)); // save y6 + psraw_i2r (COL_SHIFT, mm4); // mm4 = y3 + + movq_r2m (mm7, *(col+offset+7*8)); // save y7 + + movq_r2m (mm3, *(col+offset+4*8)); // save y4 + + movq_r2m (mm4, *(col+offset+3*8)); // save y3 + +#undef T1 +#undef T2 +#undef T3 +#undef C4 +} + +static const int32_t rounder0[] ATTR_ALIGN(8) = + rounder ((1 << (COL_SHIFT - 1)) - 0.5); +static const int32_t rounder4[] ATTR_ALIGN(8) = rounder (0); +static const int32_t rounder1[] ATTR_ALIGN(8) = + rounder (1.25683487303); /* C1*(C1/C4+C1+C7)/2 */ +static const int32_t rounder7[] ATTR_ALIGN(8) = + rounder (-0.25); /* C1*(C7/C4+C7-C1)/2 */ +static const int32_t rounder2[] ATTR_ALIGN(8) = + rounder (0.60355339059); /* C2 * (C6+C2)/2 */ +static const int32_t rounder6[] ATTR_ALIGN(8) = + rounder (-0.25); /* C2 * (C6-C2)/2 */ +static const int32_t rounder3[] ATTR_ALIGN(8) = + rounder (0.087788325588); /* C3*(-C3/C4+C3+C5)/2 */ +static const int32_t rounder5[] ATTR_ALIGN(8) = + rounder (-0.441341716183); /* C3*(-C5/C4+C5-C3)/2 */ + +#undef COL_SHIFT +#undef ROW_SHIFT + +#define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \ +void idct (int16_t * block) \ +{ \ + static const int16_t table04[] ATTR_ALIGN(16) = \ + table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \ + static const int16_t table17[] ATTR_ALIGN(16) = \ + table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \ + static const int16_t table26[] ATTR_ALIGN(16) = \ + table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \ + static const int16_t table35[] ATTR_ALIGN(16) = \ + table (26722, 25172, 22654, 19266, 15137, 10426, 5315); \ + \ + idct_row_head (block, 0*8, table04); \ + idct_row (table04, rounder0); \ + idct_row_mid (block, 0*8, 4*8, table04); \ + idct_row (table04, rounder4); \ + idct_row_mid (block, 4*8, 1*8, table17); \ + idct_row (table17, rounder1); \ + idct_row_mid (block, 1*8, 7*8, table17); \ + idct_row (table17, rounder7); \ + idct_row_mid (block, 7*8, 2*8, table26); \ + idct_row (table26, rounder2); \ + idct_row_mid (block, 2*8, 6*8, table26); \ + idct_row (table26, rounder6); \ + idct_row_mid (block, 6*8, 3*8, table35); \ + idct_row (table35, rounder3); \ + idct_row_mid (block, 3*8, 5*8, table35); \ + idct_row (table35, rounder5); \ + idct_row_tail (block, 5*8); \ + \ + idct_col (block, 0); \ + idct_col (block, 4); \ +} + +void ff_mmx_idct(DCTELEM *block); +void ff_mmxext_idct(DCTELEM *block); + +declare_idct (ff_mmxext_idct, mmxext_table, + mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid) + +declare_idct (ff_mmx_idct, mmx_table, + mmx_row_head, mmx_row, mmx_row_tail, mmx_row_mid) + diff --git a/mpeg4/src/libavcodec/i386/idct_mmx_xvid.c b/mpeg4/src/libavcodec/i386/idct_mmx_xvid.c new file mode 100644 index 00000000..ce5f0d43 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/idct_mmx_xvid.c @@ -0,0 +1,534 @@ +///**************************************************************************** +// * +// * XVID MPEG-4 VIDEO CODEC +// * - MMX and XMM forward discrete cosine transform - +// * +// * Copyright(C) 2001 Peter Ross +// * +// * This program is free software; you can redistribute it and/or modify it +// * under the terms of the GNU General Public License as published by +// * the Free Software Foundation; either version 2 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program; if not, write to the Free Software Foundation, +// * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// * +// * $Id: idct_mmx_xvid.c,v 1.4 2006/01/12 22:43:18 diego Exp $ +// * +// ***************************************************************************/ + +// **************************************************************************** +// +// Originally provided by Intel at AP-922 +// http://developer.intel.com/vtune/cbts/strmsimd/922down.htm +// (See more app notes at http://developer.intel.com/vtune/cbts/strmsimd/appnotes.htm) +// but in a limited edition. +// New macro implements a column part for precise iDCT +// The routine precision now satisfies IEEE standard 1180-1990. +// +// Copyright(C) 2000-2001 Peter Gubanov +// Rounding trick Copyright(C) 2000 Michel Lespinasse +// +// http://www.elecard.com/peter/idct.html +// http://www.linuxvideo.org/mpeg2dec/ +// +// ***************************************************************************/ +// +// These examples contain code fragments for first stage iDCT 8x8 +// (for rows) and first stage DCT 8x8 (for columns) +// + +// conversion to gcc syntax by michael niedermayer + + +#include +#include "../avcodec.h" + +//============================================================================= +// Macros and other preprocessor constants +//============================================================================= + +#define BITS_INV_ACC 5 // 4 or 5 for IEEE +#define SHIFT_INV_ROW (16 - BITS_INV_ACC) //11 +#define SHIFT_INV_COL (1 + BITS_INV_ACC) //6 +#define RND_INV_ROW (1024 * (6 - BITS_INV_ACC)) +#define RND_INV_COL (16 * (BITS_INV_ACC - 3)) +#define RND_INV_CORR (RND_INV_COL - 1) + +#define BITS_FRW_ACC 3 // 2 or 3 for accuracy +#define SHIFT_FRW_COL BITS_FRW_ACC +#define SHIFT_FRW_ROW (BITS_FRW_ACC + 17) +#define RND_FRW_ROW (262144*(BITS_FRW_ACC - 1)) + + +//----------------------------------------------------------------------------- +// Various memory constants (trigonometric values or rounding values) +//----------------------------------------------------------------------------- + + +static const int16_t tg_1_16[4*4] attribute_used __attribute__ ((aligned(8))) = { + 13036,13036,13036,13036, // tg * (2<<16) + 0.5 + 27146,27146,27146,27146, // tg * (2<<16) + 0.5 + -21746,-21746,-21746,-21746, // tg * (2<<16) + 0.5 + 23170,23170,23170,23170}; // cos * (2<<15) + 0.5 + +static const int32_t rounder_0[2*8] attribute_used __attribute__ ((aligned(8))) = { + 65536,65536, + 3597,3597, + 2260,2260, + 1203,1203, + 0,0, + 120,120, + 512,512, + 512,512}; + +//----------------------------------------------------------------------------- +// +// The first stage iDCT 8x8 - inverse DCTs of rows +// +//----------------------------------------------------------------------------- +// The 8-point inverse DCT direct algorithm +//----------------------------------------------------------------------------- +// +// static const short w[32] = { +// FIX(cos_4_16), FIX(cos_2_16), FIX(cos_4_16), FIX(cos_6_16), +// FIX(cos_4_16), FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16), +// FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16), FIX(cos_2_16), +// FIX(cos_4_16), -FIX(cos_2_16), FIX(cos_4_16), -FIX(cos_6_16), +// FIX(cos_1_16), FIX(cos_3_16), FIX(cos_5_16), FIX(cos_7_16), +// FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16), +// FIX(cos_5_16), -FIX(cos_1_16), FIX(cos_7_16), FIX(cos_3_16), +// FIX(cos_7_16), -FIX(cos_5_16), FIX(cos_3_16), -FIX(cos_1_16) }; +// +// #define DCT_8_INV_ROW(x, y) +// { +// int a0, a1, a2, a3, b0, b1, b2, b3; +// +// a0 =x[0]*w[0]+x[2]*w[1]+x[4]*w[2]+x[6]*w[3]; +// a1 =x[0]*w[4]+x[2]*w[5]+x[4]*w[6]+x[6]*w[7]; +// a2 = x[0] * w[ 8] + x[2] * w[ 9] + x[4] * w[10] + x[6] * w[11]; +// a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15]; +// b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19]; +// b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23]; +// b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27]; +// b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31]; +// +// y[0] = SHIFT_ROUND ( a0 + b0 ); +// y[1] = SHIFT_ROUND ( a1 + b1 ); +// y[2] = SHIFT_ROUND ( a2 + b2 ); +// y[3] = SHIFT_ROUND ( a3 + b3 ); +// y[4] = SHIFT_ROUND ( a3 - b3 ); +// y[5] = SHIFT_ROUND ( a2 - b2 ); +// y[6] = SHIFT_ROUND ( a1 - b1 ); +// y[7] = SHIFT_ROUND ( a0 - b0 ); +// } +// +//----------------------------------------------------------------------------- +// +// In this implementation the outputs of the iDCT-1D are multiplied +// for rows 0,4 - by cos_4_16, +// for rows 1,7 - by cos_1_16, +// for rows 2,6 - by cos_2_16, +// for rows 3,5 - by cos_3_16 +// and are shifted to the left for better accuracy +// +// For the constants used, +// FIX(float_const) = (short) (float_const * (1<<15) + 0.5) +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Tables for mmx processors +//----------------------------------------------------------------------------- + +// Table for rows 0,4 - constants are multiplied by cos_4_16 +static const int16_t tab_i_04_mmx[32*4] attribute_used __attribute__ ((aligned(8))) = { + 16384,16384,16384,-16384, // movq-> w06 w04 w02 w00 + 21407,8867,8867,-21407, // w07 w05 w03 w01 + 16384,-16384,16384,16384, // w14 w12 w10 w08 + -8867,21407,-21407,-8867, // w15 w13 w11 w09 + 22725,12873,19266,-22725, // w22 w20 w18 w16 + 19266,4520,-4520,-12873, // w23 w21 w19 w17 + 12873,4520,4520,19266, // w30 w28 w26 w24 + -22725,19266,-12873,-22725, // w31 w29 w27 w25 +// Table for rows 1,7 - constants are multiplied by cos_1_16 + 22725,22725,22725,-22725, // movq-> w06 w04 w02 w00 + 29692,12299,12299,-29692, // w07 w05 w03 w01 + 22725,-22725,22725,22725, // w14 w12 w10 w08 + -12299,29692,-29692,-12299, // w15 w13 w11 w09 + 31521,17855,26722,-31521, // w22 w20 w18 w16 + 26722,6270,-6270,-17855, // w23 w21 w19 w17 + 17855,6270,6270,26722, // w30 w28 w26 w24 + -31521,26722,-17855,-31521, // w31 w29 w27 w25 +// Table for rows 2,6 - constants are multiplied by cos_2_16 + 21407,21407,21407,-21407, // movq-> w06 w04 w02 w00 + 27969,11585,11585,-27969, // w07 w05 w03 w01 + 21407,-21407,21407,21407, // w14 w12 w10 w08 + -11585,27969,-27969,-11585, // w15 w13 w11 w09 + 29692,16819,25172,-29692, // w22 w20 w18 w16 + 25172,5906,-5906,-16819, // w23 w21 w19 w17 + 16819,5906,5906,25172, // w30 w28 w26 w24 + -29692,25172,-16819,-29692, // w31 w29 w27 w25 +// Table for rows 3,5 - constants are multiplied by cos_3_16 + 19266,19266,19266,-19266, // movq-> w06 w04 w02 w00 + 25172,10426,10426,-25172, // w07 w05 w03 w01 + 19266,-19266,19266,19266, // w14 w12 w10 w08 + -10426,25172,-25172,-10426, // w15 w13 w11 w09 + 26722,15137,22654,-26722, // w22 w20 w18 w16 + 22654,5315,-5315,-15137, // w23 w21 w19 w17 + 15137,5315,5315,22654, // w30 w28 w26 w24 + -26722,22654,-15137,-26722, // w31 w29 w27 w25 +}; +//----------------------------------------------------------------------------- +// Tables for xmm processors +//----------------------------------------------------------------------------- + +// %3 for rows 0,4 - constants are multiplied by cos_4_16 +static const int16_t tab_i_04_xmm[32*4] attribute_used __attribute__ ((aligned(8))) = { + 16384,21407,16384,8867, // movq-> w05 w04 w01 w00 + 16384,8867,-16384,-21407, // w07 w06 w03 w02 + 16384,-8867,16384,-21407, // w13 w12 w09 w08 + -16384,21407,16384,-8867, // w15 w14 w11 w10 + 22725,19266,19266,-4520, // w21 w20 w17 w16 + 12873,4520,-22725,-12873, // w23 w22 w19 w18 + 12873,-22725,4520,-12873, // w29 w28 w25 w24 + 4520,19266,19266,-22725, // w31 w30 w27 w26 +// %3 for rows 1,7 - constants are multiplied by cos_1_16 + 22725,29692,22725,12299, // movq-> w05 w04 w01 w00 + 22725,12299,-22725,-29692, // w07 w06 w03 w02 + 22725,-12299,22725,-29692, // w13 w12 w09 w08 + -22725,29692,22725,-12299, // w15 w14 w11 w10 + 31521,26722,26722,-6270, // w21 w20 w17 w16 + 17855,6270,-31521,-17855, // w23 w22 w19 w18 + 17855,-31521,6270,-17855, // w29 w28 w25 w24 + 6270,26722,26722,-31521, // w31 w30 w27 w26 +// %3 for rows 2,6 - constants are multiplied by cos_2_16 + 21407,27969,21407,11585, // movq-> w05 w04 w01 w00 + 21407,11585,-21407,-27969, // w07 w06 w03 w02 + 21407,-11585,21407,-27969, // w13 w12 w09 w08 + -21407,27969,21407,-11585, // w15 w14 w11 w10 + 29692,25172,25172,-5906, // w21 w20 w17 w16 + 16819,5906,-29692,-16819, // w23 w22 w19 w18 + 16819,-29692,5906,-16819, // w29 w28 w25 w24 + 5906,25172,25172,-29692, // w31 w30 w27 w26 +// %3 for rows 3,5 - constants are multiplied by cos_3_16 + 19266,25172,19266,10426, // movq-> w05 w04 w01 w00 + 19266,10426,-19266,-25172, // w07 w06 w03 w02 + 19266,-10426,19266,-25172, // w13 w12 w09 w08 + -19266,25172,19266,-10426, // w15 w14 w11 w10 + 26722,22654,22654,-5315, // w21 w20 w17 w16 + 15137,5315,-26722,-15137, // w23 w22 w19 w18 + 15137,-26722,5315,-15137, // w29 w28 w25 w24 + 5315,22654,22654,-26722, // w31 w30 w27 w26 +}; +//============================================================================= +// Helper macros for the code +//============================================================================= + +//----------------------------------------------------------------------------- +// DCT_8_INV_ROW_MMX( INP, OUT, TABLE, ROUNDER +//----------------------------------------------------------------------------- + +#define DCT_8_INV_ROW_MMX(A1,A2,A3,A4)\ + "movq " #A1 ",%%mm0 \n\t"/* 0 ; x3 x2 x1 x0*/\ + "movq 8+" #A1 ",%%mm1 \n\t"/* 1 ; x7 x6 x5 x4*/\ + "movq %%mm0,%%mm2 \n\t"/* 2 ; x3 x2 x1 x0*/\ + "movq " #A3 ",%%mm3 \n\t"/* 3 ; w06 w04 w02 w00*/\ + "punpcklwd %%mm1,%%mm0 \n\t"/* x5 x1 x4 x0*/\ + "movq %%mm0,%%mm5 \n\t"/* 5 ; x5 x1 x4 x0*/\ + "punpckldq %%mm0,%%mm0 \n\t"/* x4 x0 x4 x0*/\ + "movq 8+" #A3 ",%%mm4 \n\t"/* 4 ; w07 w05 w03 w01*/\ + "punpckhwd %%mm1,%%mm2 \n\t"/* 1 ; x7 x3 x6 x2*/\ + "pmaddwd %%mm0,%%mm3 \n\t"/* x4*w06+x0*w04 x4*w02+x0*w00*/\ + "movq %%mm2,%%mm6 \n\t"/* 6 ; x7 x3 x6 x2*/\ + "movq 32+" #A3 ",%%mm1 \n\t"/* 1 ; w22 w20 w18 w16*/\ + "punpckldq %%mm2,%%mm2 \n\t"/* x6 x2 x6 x2*/\ + "pmaddwd %%mm2,%%mm4 \n\t"/* x6*w07+x2*w05 x6*w03+x2*w01*/\ + "punpckhdq %%mm5,%%mm5 \n\t"/* x5 x1 x5 x1*/\ + "pmaddwd 16+" #A3 ",%%mm0 \n\t"/* x4*w14+x0*w12 x4*w10+x0*w08*/\ + "punpckhdq %%mm6,%%mm6 \n\t"/* x7 x3 x7 x3*/\ + "movq 40+" #A3 ",%%mm7 \n\t"/* 7 ; w23 w21 w19 w17*/\ + "pmaddwd %%mm5,%%mm1 \n\t"/* x5*w22+x1*w20 x5*w18+x1*w16*/\ + "paddd " #A4 ",%%mm3 \n\t"/* +%4*/\ + "pmaddwd %%mm6,%%mm7 \n\t"/* x7*w23+x3*w21 x7*w19+x3*w17*/\ + "pmaddwd 24+" #A3 ",%%mm2 \n\t"/* x6*w15+x2*w13 x6*w11+x2*w09*/\ + "paddd %%mm4,%%mm3 \n\t"/* 4 ; a1=sum(even1) a0=sum(even0)*/\ + "pmaddwd 48+" #A3 ",%%mm5 \n\t"/* x5*w30+x1*w28 x5*w26+x1*w24*/\ + "movq %%mm3,%%mm4 \n\t"/* 4 ; a1 a0*/\ + "pmaddwd 56+" #A3 ",%%mm6 \n\t"/* x7*w31+x3*w29 x7*w27+x3*w25*/\ + "paddd %%mm7,%%mm1 \n\t"/* 7 ; b1=sum(odd1) b0=sum(odd0)*/\ + "paddd " #A4 ",%%mm0 \n\t"/* +%4*/\ + "psubd %%mm1,%%mm3 \n\t"/* a1-b1 a0-b0*/\ + "psrad $11,%%mm3 \n\t"/* y6=a1-b1 y7=a0-b0*/\ + "paddd %%mm4,%%mm1 \n\t"/* 4 ; a1+b1 a0+b0*/\ + "paddd %%mm2,%%mm0 \n\t"/* 2 ; a3=sum(even3) a2=sum(even2)*/\ + "psrad $11,%%mm1 \n\t"/* y1=a1+b1 y0=a0+b0*/\ + "paddd %%mm6,%%mm5 \n\t"/* 6 ; b3=sum(odd3) b2=sum(odd2)*/\ + "movq %%mm0,%%mm4 \n\t"/* 4 ; a3 a2*/\ + "paddd %%mm5,%%mm0 \n\t"/* a3+b3 a2+b2*/\ + "psubd %%mm5,%%mm4 \n\t"/* 5 ; a3-b3 a2-b2*/\ + "psrad $11,%%mm0 \n\t"/* y3=a3+b3 y2=a2+b2*/\ + "psrad $11,%%mm4 \n\t"/* y4=a3-b3 y5=a2-b2*/\ + "packssdw %%mm0,%%mm1 \n\t"/* 0 ; y3 y2 y1 y0*/\ + "packssdw %%mm3,%%mm4 \n\t"/* 3 ; y6 y7 y4 y5*/\ + "movq %%mm4,%%mm7 \n\t"/* 7 ; y6 y7 y4 y5*/\ + "psrld $16,%%mm4 \n\t"/* 0 y6 0 y4*/\ + "pslld $16,%%mm7 \n\t"/* y7 0 y5 0*/\ + "movq %%mm1," #A2 " \n\t"/* 1 ; save y3 y2 y1 y0*/\ + "por %%mm4,%%mm7 \n\t"/* 4 ; y7 y6 y5 y4*/\ + "movq %%mm7,8 +" #A2 "\n\t"/* 7 ; save y7 y6 y5 y4*/\ + + +//----------------------------------------------------------------------------- +// DCT_8_INV_ROW_XMM( INP, OUT, TABLE, ROUNDER +//----------------------------------------------------------------------------- + +#define DCT_8_INV_ROW_XMM(A1,A2,A3,A4)\ + "movq " #A1 ",%%mm0 \n\t"/* 0 ; x3 x2 x1 x0*/\ + "movq 8+" #A1 ",%%mm1 \n\t"/* 1 ; x7 x6 x5 x4*/\ + "movq %%mm0,%%mm2 \n\t"/* 2 ; x3 x2 x1 x0*/\ + "movq " #A3 ",%%mm3 \n\t"/* 3 ; w05 w04 w01 w00*/\ + "pshufw $0b10001000,%%mm0,%%mm0 \n\t"/* x2 x0 x2 x0*/\ + "movq 8+" #A3 ",%%mm4 \n\t"/* 4 ; w07 w06 w03 w02*/\ + "movq %%mm1,%%mm5 \n\t"/* 5 ; x7 x6 x5 x4*/\ + "pmaddwd %%mm0,%%mm3 \n\t"/* x2*w05+x0*w04 x2*w01+x0*w00*/\ + "movq 32+" #A3 ",%%mm6 \n\t"/* 6 ; w21 w20 w17 w16*/\ + "pshufw $0b10001000,%%mm1,%%mm1 \n\t"/* x6 x4 x6 x4*/\ + "pmaddwd %%mm1,%%mm4 \n\t"/* x6*w07+x4*w06 x6*w03+x4*w02*/\ + "movq 40+" #A3 ",%%mm7 \n\t"/* 7 ; w23 w22 w19 w18*/\ + "pshufw $0b11011101,%%mm2,%%mm2 \n\t"/* x3 x1 x3 x1*/\ + "pmaddwd %%mm2,%%mm6 \n\t"/* x3*w21+x1*w20 x3*w17+x1*w16*/\ + "pshufw $0b11011101,%%mm5,%%mm5 \n\t"/* x7 x5 x7 x5*/\ + "pmaddwd %%mm5,%%mm7 \n\t"/* x7*w23+x5*w22 x7*w19+x5*w18*/\ + "paddd " #A4 ",%%mm3 \n\t"/* +%4*/\ + "pmaddwd 16+" #A3 ",%%mm0 \n\t"/* x2*w13+x0*w12 x2*w09+x0*w08*/\ + "paddd %%mm4,%%mm3 \n\t"/* 4 ; a1=sum(even1) a0=sum(even0)*/\ + "pmaddwd 24+" #A3 ",%%mm1 \n\t"/* x6*w15+x4*w14 x6*w11+x4*w10*/\ + "movq %%mm3,%%mm4 \n\t"/* 4 ; a1 a0*/\ + "pmaddwd 48+" #A3 ",%%mm2 \n\t"/* x3*w29+x1*w28 x3*w25+x1*w24*/\ + "paddd %%mm7,%%mm6 \n\t"/* 7 ; b1=sum(odd1) b0=sum(odd0)*/\ + "pmaddwd 56+" #A3 ",%%mm5 \n\t"/* x7*w31+x5*w30 x7*w27+x5*w26*/\ + "paddd %%mm6,%%mm3 \n\t"/* a1+b1 a0+b0*/\ + "paddd " #A4 ",%%mm0 \n\t"/* +%4*/\ + "psrad $11,%%mm3 \n\t"/* y1=a1+b1 y0=a0+b0*/\ + "paddd %%mm1,%%mm0 \n\t"/* 1 ; a3=sum(even3) a2=sum(even2)*/\ + "psubd %%mm6,%%mm4 \n\t"/* 6 ; a1-b1 a0-b0*/\ + "movq %%mm0,%%mm7 \n\t"/* 7 ; a3 a2*/\ + "paddd %%mm5,%%mm2 \n\t"/* 5 ; b3=sum(odd3) b2=sum(odd2)*/\ + "paddd %%mm2,%%mm0 \n\t"/* a3+b3 a2+b2*/\ + "psrad $11,%%mm4 \n\t"/* y6=a1-b1 y7=a0-b0*/\ + "psubd %%mm2,%%mm7 \n\t"/* 2 ; a3-b3 a2-b2*/\ + "psrad $11,%%mm0 \n\t"/* y3=a3+b3 y2=a2+b2*/\ + "psrad $11,%%mm7 \n\t"/* y4=a3-b3 y5=a2-b2*/\ + "packssdw %%mm0,%%mm3 \n\t"/* 0 ; y3 y2 y1 y0*/\ + "packssdw %%mm4,%%mm7 \n\t"/* 4 ; y6 y7 y4 y5*/\ + "movq %%mm3, " #A2 " \n\t"/* 3 ; save y3 y2 y1 y0*/\ + "pshufw $0b10110001,%%mm7,%%mm7 \n\t"/* y7 y6 y5 y4*/\ + "movq %%mm7,8 +" #A2 "\n\t"/* 7 ; save y7 y6 y5 y4*/\ + + +//----------------------------------------------------------------------------- +// +// The first stage DCT 8x8 - forward DCTs of columns +// +// The %2puts are multiplied +// for rows 0,4 - on cos_4_16, +// for rows 1,7 - on cos_1_16, +// for rows 2,6 - on cos_2_16, +// for rows 3,5 - on cos_3_16 +// and are shifted to the left for rise of accuracy +// +//----------------------------------------------------------------------------- +// +// The 8-point scaled forward DCT algorithm (26a8m) +// +//----------------------------------------------------------------------------- +// +// #define DCT_8_FRW_COL(x, y) +//{ +// short t0, t1, t2, t3, t4, t5, t6, t7; +// short tp03, tm03, tp12, tm12, tp65, tm65; +// short tp465, tm465, tp765, tm765; +// +// t0 = LEFT_SHIFT ( x[0] + x[7] ); +// t1 = LEFT_SHIFT ( x[1] + x[6] ); +// t2 = LEFT_SHIFT ( x[2] + x[5] ); +// t3 = LEFT_SHIFT ( x[3] + x[4] ); +// t4 = LEFT_SHIFT ( x[3] - x[4] ); +// t5 = LEFT_SHIFT ( x[2] - x[5] ); +// t6 = LEFT_SHIFT ( x[1] - x[6] ); +// t7 = LEFT_SHIFT ( x[0] - x[7] ); +// +// tp03 = t0 + t3; +// tm03 = t0 - t3; +// tp12 = t1 + t2; +// tm12 = t1 - t2; +// +// y[0] = tp03 + tp12; +// y[4] = tp03 - tp12; +// +// y[2] = tm03 + tm12 * tg_2_16; +// y[6] = tm03 * tg_2_16 - tm12; +// +// tp65 =(t6 +t5 )*cos_4_16; +// tm65 =(t6 -t5 )*cos_4_16; +// +// tp765 = t7 + tp65; +// tm765 = t7 - tp65; +// tp465 = t4 + tm65; +// tm465 = t4 - tm65; +// +// y[1] = tp765 + tp465 * tg_1_16; +// y[7] = tp765 * tg_1_16 - tp465; +// y[5] = tm765 * tg_3_16 + tm465; +// y[3] = tm765 - tm465 * tg_3_16; +//} +// +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// DCT_8_INV_COL_4 INP,OUT +//----------------------------------------------------------------------------- + +#define DCT_8_INV_COL(A1,A2)\ + "movq 2*8(%3),%%mm0\n\t"\ + "movq 16*3+" #A1 ",%%mm3\n\t"\ + "movq %%mm0,%%mm1 \n\t"/* tg_3_16*/\ + "movq 16*5+" #A1 ",%%mm5\n\t"\ + "pmulhw %%mm3,%%mm0 \n\t"/* x3*(tg_3_16-1)*/\ + "movq (%3),%%mm4\n\t"\ + "pmulhw %%mm5,%%mm1 \n\t"/* x5*(tg_3_16-1)*/\ + "movq 16*7+" #A1 ",%%mm7\n\t"\ + "movq %%mm4,%%mm2 \n\t"/* tg_1_16*/\ + "movq 16*1+" #A1 ",%%mm6\n\t"\ + "pmulhw %%mm7,%%mm4 \n\t"/* x7*tg_1_16*/\ + "paddsw %%mm3,%%mm0 \n\t"/* x3*tg_3_16*/\ + "pmulhw %%mm6,%%mm2 \n\t"/* x1*tg_1_16*/\ + "paddsw %%mm3,%%mm1 \n\t"/* x3+x5*(tg_3_16-1)*/\ + "psubsw %%mm5,%%mm0 \n\t"/* x3*tg_3_16-x5 = tm35*/\ + "movq 3*8(%3),%%mm3\n\t"\ + "paddsw %%mm5,%%mm1 \n\t"/* x3+x5*tg_3_16 = tp35*/\ + "paddsw %%mm6,%%mm4 \n\t"/* x1+tg_1_16*x7 = tp17*/\ + "psubsw %%mm7,%%mm2 \n\t"/* x1*tg_1_16-x7 = tm17*/\ + "movq %%mm4,%%mm5 \n\t"/* tp17*/\ + "movq %%mm2,%%mm6 \n\t"/* tm17*/\ + "paddsw %%mm1,%%mm5 \n\t"/* tp17+tp35 = b0*/\ + "psubsw %%mm0,%%mm6 \n\t"/* tm17-tm35 = b3*/\ + "psubsw %%mm1,%%mm4 \n\t"/* tp17-tp35 = t1*/\ + "paddsw %%mm0,%%mm2 \n\t"/* tm17+tm35 = t2*/\ + "movq 1*8(%3),%%mm7\n\t"\ + "movq %%mm4,%%mm1 \n\t"/* t1*/\ + "movq %%mm5,3*16 +" #A2 "\n\t"/* save b0*/\ + "paddsw %%mm2,%%mm1 \n\t"/* t1+t2*/\ + "movq %%mm6,5*16 +" #A2 "\n\t"/* save b3*/\ + "psubsw %%mm2,%%mm4 \n\t"/* t1-t2*/\ + "movq 2*16+" #A1 ",%%mm5\n\t"\ + "movq %%mm7,%%mm0 \n\t"/* tg_2_16*/\ + "movq 6*16+" #A1 ",%%mm6\n\t"\ + "pmulhw %%mm5,%%mm0 \n\t"/* x2*tg_2_16*/\ + "pmulhw %%mm6,%%mm7 \n\t"/* x6*tg_2_16*/\ + "pmulhw %%mm3,%%mm1 \n\t"/* ocos_4_16*(t1+t2) = b1/2*/\ + "movq 0*16+" #A1 ",%%mm2\n\t"\ + "pmulhw %%mm3,%%mm4 \n\t"/* ocos_4_16*(t1-t2) = b2/2*/\ + "psubsw %%mm6,%%mm0 \n\t"/* t2*tg_2_16-x6 = tm26*/\ + "movq %%mm2,%%mm3 \n\t"/* x0*/\ + "movq 4*16+" #A1 ",%%mm6\n\t"\ + "paddsw %%mm5,%%mm7 \n\t"/* x2+x6*tg_2_16 = tp26*/\ + "paddsw %%mm6,%%mm2 \n\t"/* x0+x4 = tp04*/\ + "psubsw %%mm6,%%mm3 \n\t"/* x0-x4 = tm04*/\ + "movq %%mm2,%%mm5 \n\t"/* tp04*/\ + "movq %%mm3,%%mm6 \n\t"/* tm04*/\ + "psubsw %%mm7,%%mm2 \n\t"/* tp04-tp26 = a3*/\ + "paddsw %%mm0,%%mm3 \n\t"/* tm04+tm26 = a1*/\ + "paddsw %%mm1,%%mm1 \n\t"/* b1*/\ + "paddsw %%mm4,%%mm4 \n\t"/* b2*/\ + "paddsw %%mm7,%%mm5 \n\t"/* tp04+tp26 = a0*/\ + "psubsw %%mm0,%%mm6 \n\t"/* tm04-tm26 = a2*/\ + "movq %%mm3,%%mm7 \n\t"/* a1*/\ + "movq %%mm6,%%mm0 \n\t"/* a2*/\ + "paddsw %%mm1,%%mm3 \n\t"/* a1+b1*/\ + "paddsw %%mm4,%%mm6 \n\t"/* a2+b2*/\ + "psraw $6,%%mm3 \n\t"/* dst1*/\ + "psubsw %%mm1,%%mm7 \n\t"/* a1-b1*/\ + "psraw $6,%%mm6 \n\t"/* dst2*/\ + "psubsw %%mm4,%%mm0 \n\t"/* a2-b2*/\ + "movq 3*16+" #A2 ",%%mm1 \n\t"/* load b0*/\ + "psraw $6,%%mm7 \n\t"/* dst6*/\ + "movq %%mm5,%%mm4 \n\t"/* a0*/\ + "psraw $6,%%mm0 \n\t"/* dst5*/\ + "movq %%mm3,1*16+" #A2 "\n\t"\ + "paddsw %%mm1,%%mm5 \n\t"/* a0+b0*/\ + "movq %%mm6,2*16+" #A2 "\n\t"\ + "psubsw %%mm1,%%mm4 \n\t"/* a0-b0*/\ + "movq 5*16+" #A2 ",%%mm3 \n\t"/* load b3*/\ + "psraw $6,%%mm5 \n\t"/* dst0*/\ + "movq %%mm2,%%mm6 \n\t"/* a3*/\ + "psraw $6,%%mm4 \n\t"/* dst7*/\ + "movq %%mm0,5*16+" #A2 "\n\t"\ + "paddsw %%mm3,%%mm2 \n\t"/* a3+b3*/\ + "movq %%mm7,6*16+" #A2 "\n\t"\ + "psubsw %%mm3,%%mm6 \n\t"/* a3-b3*/\ + "movq %%mm5,0*16+" #A2 "\n\t"\ + "psraw $6,%%mm2 \n\t"/* dst3*/\ + "movq %%mm4,7*16+" #A2 "\n\t"\ + "psraw $6,%%mm6 \n\t"/* dst4*/\ + "movq %%mm2,3*16+" #A2 "\n\t"\ + "movq %%mm6,4*16+" #A2 "\n\t" + +//============================================================================= +// Code +//============================================================================= + +//----------------------------------------------------------------------------- +// void idct_mmx(uint16_t block[64]); +//----------------------------------------------------------------------------- + + +void ff_idct_xvid_mmx(short *block){ +asm volatile( + //# Process each row + DCT_8_INV_ROW_MMX(0*16(%0), 0*16(%0), 64*0(%2), 8*0(%1)) + DCT_8_INV_ROW_MMX(1*16(%0), 1*16(%0), 64*1(%2), 8*1(%1)) + DCT_8_INV_ROW_MMX(2*16(%0), 2*16(%0), 64*2(%2), 8*2(%1)) + DCT_8_INV_ROW_MMX(3*16(%0), 3*16(%0), 64*3(%2), 8*3(%1)) + DCT_8_INV_ROW_MMX(4*16(%0), 4*16(%0), 64*0(%2), 8*4(%1)) + DCT_8_INV_ROW_MMX(5*16(%0), 5*16(%0), 64*3(%2), 8*5(%1)) + DCT_8_INV_ROW_MMX(6*16(%0), 6*16(%0), 64*2(%2), 8*6(%1)) + DCT_8_INV_ROW_MMX(7*16(%0), 7*16(%0), 64*1(%2), 8*7(%1)) + + //# Process the columns (4 at a time) + DCT_8_INV_COL(0(%0), 0(%0)) + DCT_8_INV_COL(8(%0), 8(%0)) + :: "r"(block), "r"(rounder_0), "r"(tab_i_04_mmx), "r"(tg_1_16)); +} + +//----------------------------------------------------------------------------- +// void idct_xmm(uint16_t block[64]); +//----------------------------------------------------------------------------- + + +void ff_idct_xvid_mmx2(short *block){ +asm volatile( + //# Process each row + DCT_8_INV_ROW_XMM(0*16(%0), 0*16(%0), 64*0(%2), 8*0(%1)) + DCT_8_INV_ROW_XMM(1*16(%0), 1*16(%0), 64*1(%2), 8*1(%1)) + DCT_8_INV_ROW_XMM(2*16(%0), 2*16(%0), 64*2(%2), 8*2(%1)) + DCT_8_INV_ROW_XMM(3*16(%0), 3*16(%0), 64*3(%2), 8*3(%1)) + DCT_8_INV_ROW_XMM(4*16(%0), 4*16(%0), 64*0(%2), 8*4(%1)) + DCT_8_INV_ROW_XMM(5*16(%0), 5*16(%0), 64*3(%2), 8*5(%1)) + DCT_8_INV_ROW_XMM(6*16(%0), 6*16(%0), 64*2(%2), 8*6(%1)) + DCT_8_INV_ROW_XMM(7*16(%0), 7*16(%0), 64*1(%2), 8*7(%1)) + + //# Process the columns (4 at a time) + DCT_8_INV_COL(0(%0), 0(%0)) + DCT_8_INV_COL(8(%0), 8(%0)) + :: "r"(block), "r"(rounder_0), "r"(tab_i_04_xmm), "r"(tg_1_16)); +} + diff --git a/mpeg4/src/libavcodec/i386/mmx.h b/mpeg4/src/libavcodec/i386/mmx.h new file mode 100644 index 00000000..df179182 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/mmx.h @@ -0,0 +1,285 @@ +/* + * mmx.h + * Copyright (C) 1997-2001 H. Dietz and R. Fisher + */ +#ifndef AVCODEC_I386MMX_H +#define AVCODEC_I386MMX_H + +#ifdef ARCH_X86_64 +# define REG_a "rax" +# define REG_b "rbx" +# define REG_c "rcx" +# define REG_d "rdx" +# define REG_D "rdi" +# define REG_S "rsi" +# define PTR_SIZE "8" +#else +# define REG_a "eax" +# define REG_b "ebx" +# define REG_c "ecx" +# define REG_d "edx" +# define REG_D "edi" +# define REG_S "esi" +# define PTR_SIZE "4" +#endif + +/* + * The type of an value that fits in an MMX register (note that long + * long constant values MUST be suffixed by LL and unsigned long long + * values by ULL, lest they be truncated by the compiler) + */ + +typedef union { + long long q; /* Quadword (64-bit) value */ + unsigned long long uq; /* Unsigned Quadword */ + int d[2]; /* 2 Doubleword (32-bit) values */ + unsigned int ud[2]; /* 2 Unsigned Doubleword */ + short w[4]; /* 4 Word (16-bit) values */ + unsigned short uw[4]; /* 4 Unsigned Word */ + char b[8]; /* 8 Byte (8-bit) values */ + unsigned char ub[8]; /* 8 Unsigned Byte */ + float s[2]; /* Single-precision (32-bit) value */ +} mmx_t; /* On an 8-byte (64-bit) boundary */ + + +#define mmx_i2r(op,imm,reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "i" (imm) ) + +#define mmx_m2r(op,mem,reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "m" (mem)) + +#define mmx_r2m(op,reg,mem) \ + __asm__ __volatile__ (#op " %%" #reg ", %0" \ + : "=m" (mem) \ + : /* nothing */ ) + +#define mmx_r2r(op,regs,regd) \ + __asm__ __volatile__ (#op " %" #regs ", %" #regd) + + +#define emms() __asm__ __volatile__ ("emms") + +#define movd_m2r(var,reg) mmx_m2r (movd, var, reg) +#define movd_r2m(reg,var) mmx_r2m (movd, reg, var) +#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd) + +#define movq_m2r(var,reg) mmx_m2r (movq, var, reg) +#define movq_r2m(reg,var) mmx_r2m (movq, reg, var) +#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd) + +#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg) +#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd) +#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg) +#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd) + +#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg) +#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd) + +#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg) +#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd) +#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg) +#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd) +#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg) +#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd) + +#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg) +#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd) +#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg) +#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd) + +#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg) +#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd) +#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg) +#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd) + +#define pand_m2r(var,reg) mmx_m2r (pand, var, reg) +#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd) + +#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg) +#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd) + +#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg) +#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd) +#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg) +#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd) +#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg) +#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd) + +#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg) +#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd) +#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg) +#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd) +#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg) +#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd) + +#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg) +#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd) + +#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg) +#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd) + +#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg) +#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd) + +#define por_m2r(var,reg) mmx_m2r (por, var, reg) +#define por_r2r(regs,regd) mmx_r2r (por, regs, regd) + +#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg) +#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg) +#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd) +#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg) +#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg) +#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd) +#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg) +#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg) +#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd) + +#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg) +#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg) +#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd) +#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg) +#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg) +#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd) + +#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg) +#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg) +#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd) +#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg) +#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg) +#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd) +#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg) +#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg) +#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd) + +#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg) +#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd) +#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg) +#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd) +#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg) +#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd) + +#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg) +#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd) +#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg) +#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd) + +#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg) +#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd) +#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg) +#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd) + +#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg) +#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd) +#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg) +#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd) +#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg) +#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd) + +#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg) +#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd) +#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg) +#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd) +#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg) +#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd) + +#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg) +#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd) + + +/* 3DNOW extensions */ + +#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg) +#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd) + + +/* AMD MMX extensions - also available in intel SSE */ + + +#define mmx_m2ri(op,mem,reg,imm) \ + __asm__ __volatile__ (#op " %1, %0, %%" #reg \ + : /* nothing */ \ + : "X" (mem), "X" (imm)) +#define mmx_r2ri(op,regs,regd,imm) \ + __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ + : /* nothing */ \ + : "X" (imm) ) + +#define mmx_fetch(mem,hint) \ + __asm__ __volatile__ ("prefetch" #hint " %0" \ + : /* nothing */ \ + : "X" (mem)) + + +#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg) + +#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var) + +#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg) +#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd) +#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg) +#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd) + +#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm) + +#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm) + +#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg) +#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd) + +#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg) +#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd) + +#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg) +#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd) + +#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg) +#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd) + +#define pmovmskb(mmreg,reg) \ + __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg) + +#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg) +#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd) + +#define prefetcht0(mem) mmx_fetch (mem, t0) +#define prefetcht1(mem) mmx_fetch (mem, t1) +#define prefetcht2(mem) mmx_fetch (mem, t2) +#define prefetchnta(mem) mmx_fetch (mem, nta) + +#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg) +#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd) + +#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm) +#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm) + +#define sfence() __asm__ __volatile__ ("sfence\n\t") + +/* SSE2 */ +#define pshufhw_m2r(var,reg,imm) mmx_m2ri(pshufhw, var, reg, imm) +#define pshufhw_r2r(regs,regd,imm) mmx_r2ri(pshufhw, regs, regd, imm) +#define pshuflw_m2r(var,reg,imm) mmx_m2ri(pshuflw, var, reg, imm) +#define pshuflw_r2r(regs,regd,imm) mmx_r2ri(pshuflw, regs, regd, imm) + +#define pshufd_r2r(regs,regd,imm) mmx_r2ri(pshufd, regs, regd, imm) + +#define movdqa_m2r(var,reg) mmx_m2r (movdqa, var, reg) +#define movdqa_r2m(reg,var) mmx_r2m (movdqa, reg, var) +#define movdqa_r2r(regs,regd) mmx_r2r (movdqa, regs, regd) +#define movdqu_m2r(var,reg) mmx_m2r (movdqu, var, reg) +#define movdqu_r2m(reg,var) mmx_r2m (movdqu, reg, var) +#define movdqu_r2r(regs,regd) mmx_r2r (movdqu, regs, regd) + +#define pmullw_r2m(reg,var) mmx_r2m (pmullw, reg, var) + +#define pslldq_i2r(imm,reg) mmx_i2r (pslldq, imm, reg) +#define psrldq_i2r(imm,reg) mmx_i2r (psrldq, imm, reg) + +#define punpcklqdq_r2r(regs,regd) mmx_r2r (punpcklqdq, regs, regd) +#define punpckhqdq_r2r(regs,regd) mmx_r2r (punpckhqdq, regs, regd) + + +#endif /* AVCODEC_I386MMX_H */ diff --git a/mpeg4/src/libavcodec/i386/motion_est_mmx.c b/mpeg4/src/libavcodec/i386/motion_est_mmx.c new file mode 100644 index 00000000..c14b7938 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/motion_est_mmx.c @@ -0,0 +1,406 @@ +/* + * MMX optimized motion estimation + * Copyright (c) 2001 Fabrice Bellard. + * Copyright (c) 2002-2004 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * mostly by Michael Niedermayer + */ +#include "../dsputil.h" +#include "mmx.h" + +static const __attribute__ ((aligned(8))) uint64_t round_tab[3]={ +0x0000000000000000ULL, +0x0001000100010001ULL, +0x0002000200020002ULL, +}; + +static attribute_used __attribute__ ((aligned(8))) uint64_t bone= 0x0101010101010101LL; + +static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) +{ + long len= -(stride*h); + asm volatile( + ".balign 16 \n\t" + "1: \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "movq (%2, %%"REG_a"), %%mm2 \n\t" + "movq (%2, %%"REG_a"), %%mm4 \n\t" + "add %3, %%"REG_a" \n\t" + "psubusb %%mm0, %%mm2 \n\t" + "psubusb %%mm4, %%mm0 \n\t" + "movq (%1, %%"REG_a"), %%mm1 \n\t" + "movq (%2, %%"REG_a"), %%mm3 \n\t" + "movq (%2, %%"REG_a"), %%mm5 \n\t" + "psubusb %%mm1, %%mm3 \n\t" + "psubusb %%mm5, %%mm1 \n\t" + "por %%mm2, %%mm0 \n\t" + "por %%mm1, %%mm3 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm3, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm2 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm3, %%mm2 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %3, %%"REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1 - len), "r" (blk2 - len), "r" ((long)stride) + ); +} + +static inline void sad8_1_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) +{ + long len= -(stride*h); + asm volatile( + ".balign 16 \n\t" + "1: \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "movq (%2, %%"REG_a"), %%mm2 \n\t" + "psadbw %%mm2, %%mm0 \n\t" + "add %3, %%"REG_a" \n\t" + "movq (%1, %%"REG_a"), %%mm1 \n\t" + "movq (%2, %%"REG_a"), %%mm3 \n\t" + "psadbw %%mm1, %%mm3 \n\t" + "paddw %%mm3, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %3, %%"REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1 - len), "r" (blk2 - len), "r" ((long)stride) + ); +} + +static inline void sad8_2_mmx2(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, int stride, int h) +{ + long len= -(stride*h); + asm volatile( + ".balign 16 \n\t" + "1: \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "movq (%2, %%"REG_a"), %%mm2 \n\t" + "pavgb %%mm2, %%mm0 \n\t" + "movq (%3, %%"REG_a"), %%mm2 \n\t" + "psadbw %%mm2, %%mm0 \n\t" + "add %4, %%"REG_a" \n\t" + "movq (%1, %%"REG_a"), %%mm1 \n\t" + "movq (%2, %%"REG_a"), %%mm3 \n\t" + "pavgb %%mm1, %%mm3 \n\t" + "movq (%3, %%"REG_a"), %%mm1 \n\t" + "psadbw %%mm1, %%mm3 \n\t" + "paddw %%mm3, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %4, %%"REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1a - len), "r" (blk1b -len), "r" (blk2 - len), "r" ((long)stride) + ); +} + +static inline void sad8_4_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h) +{ //FIXME reuse src + long len= -(stride*h); + asm volatile( + ".balign 16 \n\t" + "movq "MANGLE(bone)", %%mm5 \n\t" + "1: \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "movq (%2, %%"REG_a"), %%mm2 \n\t" + "movq 1(%1, %%"REG_a"), %%mm1 \n\t" + "movq 1(%2, %%"REG_a"), %%mm3 \n\t" + "pavgb %%mm2, %%mm0 \n\t" + "pavgb %%mm1, %%mm3 \n\t" + "psubusb %%mm5, %%mm3 \n\t" + "pavgb %%mm3, %%mm0 \n\t" + "movq (%3, %%"REG_a"), %%mm2 \n\t" + "psadbw %%mm2, %%mm0 \n\t" + "add %4, %%"REG_a" \n\t" + "movq (%1, %%"REG_a"), %%mm1 \n\t" + "movq (%2, %%"REG_a"), %%mm3 \n\t" + "movq 1(%1, %%"REG_a"), %%mm2 \n\t" + "movq 1(%2, %%"REG_a"), %%mm4 \n\t" + "pavgb %%mm3, %%mm1 \n\t" + "pavgb %%mm4, %%mm2 \n\t" + "psubusb %%mm5, %%mm2 \n\t" + "pavgb %%mm1, %%mm2 \n\t" + "movq (%3, %%"REG_a"), %%mm1 \n\t" + "psadbw %%mm1, %%mm2 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %4, %%"REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1 - len), "r" (blk1 - len + stride), "r" (blk2 - len), "r" ((long)stride) + ); +} + +static inline void sad8_2_mmx(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, int stride, int h) +{ + long len= -(stride*h); + asm volatile( + ".balign 16 \n\t" + "1: \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "movq (%2, %%"REG_a"), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm2 \n\t" + "movq (%2, %%"REG_a"), %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddw %%mm0, %%mm1 \n\t" + "paddw %%mm2, %%mm3 \n\t" + "movq (%3, %%"REG_a"), %%mm4 \n\t" + "movq (%3, %%"REG_a"), %%mm2 \n\t" + "paddw %%mm5, %%mm1 \n\t" + "paddw %%mm5, %%mm3 \n\t" + "psrlw $1, %%mm1 \n\t" + "psrlw $1, %%mm3 \n\t" + "packuswb %%mm3, %%mm1 \n\t" + "psubusb %%mm1, %%mm4 \n\t" + "psubusb %%mm2, %%mm1 \n\t" + "por %%mm4, %%mm1 \n\t" + "movq %%mm1, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %4, %%"REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1a - len), "r" (blk1b -len), "r" (blk2 - len), "r" ((long)stride) + ); +} + +static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h) +{ + long len= -(stride*h); + asm volatile( + ".balign 16 \n\t" + "1: \n\t" + "movq (%1, %%"REG_a"), %%mm0 \n\t" + "movq (%2, %%"REG_a"), %%mm1 \n\t" + "movq %%mm0, %%mm4 \n\t" + "movq %%mm1, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm2 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm2, %%mm4 \n\t" + "movq 1(%1, %%"REG_a"), %%mm2 \n\t" + "movq 1(%2, %%"REG_a"), %%mm3 \n\t" + "movq %%mm2, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "paddw %%mm0, %%mm2 \n\t" + "paddw %%mm4, %%mm1 \n\t" + "movq %%mm3, %%mm4 \n\t" + "punpcklbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm4 \n\t" + "paddw %%mm3, %%mm2 \n\t" + "paddw %%mm4, %%mm1 \n\t" + "movq (%3, %%"REG_a"), %%mm3 \n\t" + "movq (%3, %%"REG_a"), %%mm4 \n\t" + "paddw %%mm5, %%mm2 \n\t" + "paddw %%mm5, %%mm1 \n\t" + "psrlw $2, %%mm2 \n\t" + "psrlw $2, %%mm1 \n\t" + "packuswb %%mm1, %%mm2 \n\t" + "psubusb %%mm2, %%mm3 \n\t" + "psubusb %%mm4, %%mm2 \n\t" + "por %%mm3, %%mm2 \n\t" + "movq %%mm2, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm2 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %4, %%"REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1 - len), "r" (blk1 -len + stride), "r" (blk2 - len), "r" ((long)stride) + ); +} + +static inline int sum_mmx(void) +{ + int ret; + asm volatile( + "movq %%mm6, %%mm0 \n\t" + "psrlq $32, %%mm6 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "movq %%mm6, %%mm0 \n\t" + "psrlq $16, %%mm6 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "movd %%mm6, %0 \n\t" + : "=r" (ret) + ); + return ret&0xFFFF; +} + +static inline int sum_mmx2(void) +{ + int ret; + asm volatile( + "movd %%mm6, %0 \n\t" + : "=r" (ret) + ); + return ret; +} + + +#define PIX_SAD(suf)\ +static int sad8_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\ +{\ + assert(h==8);\ + asm volatile("pxor %%mm7, %%mm7 \n\t"\ + "pxor %%mm6, %%mm6 \n\t":);\ +\ + sad8_1_ ## suf(blk1, blk2, stride, 8);\ +\ + return sum_ ## suf();\ +}\ +static int sad8_x2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\ +{\ + assert(h==8);\ + asm volatile("pxor %%mm7, %%mm7 \n\t"\ + "pxor %%mm6, %%mm6 \n\t"\ + "movq %0, %%mm5 \n\t"\ + :: "m"(round_tab[1]) \ + );\ +\ + sad8_2_ ## suf(blk1, blk1+1, blk2, stride, 8);\ +\ + return sum_ ## suf();\ +}\ +\ +static int sad8_y2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\ +{\ + assert(h==8);\ + asm volatile("pxor %%mm7, %%mm7 \n\t"\ + "pxor %%mm6, %%mm6 \n\t"\ + "movq %0, %%mm5 \n\t"\ + :: "m"(round_tab[1]) \ + );\ +\ + sad8_2_ ## suf(blk1, blk1+stride, blk2, stride, 8);\ +\ + return sum_ ## suf();\ +}\ +\ +static int sad8_xy2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\ +{\ + assert(h==8);\ + asm volatile("pxor %%mm7, %%mm7 \n\t"\ + "pxor %%mm6, %%mm6 \n\t"\ + "movq %0, %%mm5 \n\t"\ + :: "m"(round_tab[2]) \ + );\ +\ + sad8_4_ ## suf(blk1, blk2, stride, 8);\ +\ + return sum_ ## suf();\ +}\ +\ +static int sad16_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\ +{\ + asm volatile("pxor %%mm7, %%mm7 \n\t"\ + "pxor %%mm6, %%mm6 \n\t":);\ +\ + sad8_1_ ## suf(blk1 , blk2 , stride, h);\ + sad8_1_ ## suf(blk1+8, blk2+8, stride, h);\ +\ + return sum_ ## suf();\ +}\ +static int sad16_x2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\ +{\ + asm volatile("pxor %%mm7, %%mm7 \n\t"\ + "pxor %%mm6, %%mm6 \n\t"\ + "movq %0, %%mm5 \n\t"\ + :: "m"(round_tab[1]) \ + );\ +\ + sad8_2_ ## suf(blk1 , blk1+1, blk2 , stride, h);\ + sad8_2_ ## suf(blk1+8, blk1+9, blk2+8, stride, h);\ +\ + return sum_ ## suf();\ +}\ +static int sad16_y2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\ +{\ + asm volatile("pxor %%mm7, %%mm7 \n\t"\ + "pxor %%mm6, %%mm6 \n\t"\ + "movq %0, %%mm5 \n\t"\ + :: "m"(round_tab[1]) \ + );\ +\ + sad8_2_ ## suf(blk1 , blk1+stride, blk2 , stride, h);\ + sad8_2_ ## suf(blk1+8, blk1+stride+8,blk2+8, stride, h);\ +\ + return sum_ ## suf();\ +}\ +static int sad16_xy2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\ +{\ + asm volatile("pxor %%mm7, %%mm7 \n\t"\ + "pxor %%mm6, %%mm6 \n\t"\ + "movq %0, %%mm5 \n\t"\ + :: "m"(round_tab[2]) \ + );\ +\ + sad8_4_ ## suf(blk1 , blk2 , stride, h);\ + sad8_4_ ## suf(blk1+8, blk2+8, stride, h);\ +\ + return sum_ ## suf();\ +}\ + +PIX_SAD(mmx) +PIX_SAD(mmx2) + +void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx) +{ + if (mm_flags & MM_MMX) { + c->pix_abs[0][0] = sad16_mmx; + c->pix_abs[0][1] = sad16_x2_mmx; + c->pix_abs[0][2] = sad16_y2_mmx; + c->pix_abs[0][3] = sad16_xy2_mmx; + c->pix_abs[1][0] = sad8_mmx; + c->pix_abs[1][1] = sad8_x2_mmx; + c->pix_abs[1][2] = sad8_y2_mmx; + c->pix_abs[1][3] = sad8_xy2_mmx; + + c->sad[0]= sad16_mmx; + c->sad[1]= sad8_mmx; + } + if (mm_flags & MM_MMXEXT) { + c->pix_abs[0][0] = sad16_mmx2; + c->pix_abs[1][0] = sad8_mmx2; + + c->sad[0]= sad16_mmx2; + c->sad[1]= sad8_mmx2; + + if(!(avctx->flags & CODEC_FLAG_BITEXACT)){ + c->pix_abs[0][1] = sad16_x2_mmx2; + c->pix_abs[0][2] = sad16_y2_mmx2; + c->pix_abs[0][3] = sad16_xy2_mmx2; + c->pix_abs[1][1] = sad8_x2_mmx2; + c->pix_abs[1][2] = sad8_y2_mmx2; + c->pix_abs[1][3] = sad8_xy2_mmx2; + } + } +} diff --git a/mpeg4/src/libavcodec/i386/mpegvideo_mmx.c b/mpeg4/src/libavcodec/i386/mpegvideo_mmx.c new file mode 100644 index 00000000..f83df3a1 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/mpegvideo_mmx.c @@ -0,0 +1,723 @@ +/* + * The simplest mpeg encoder (well, it was the simplest!) + * Copyright (c) 2000,2001 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Optimized for ia32 cpus by Nick Kurshev + * h263, mpeg1, mpeg2 dequantizer & draw_edges by Michael Niedermayer + */ + +#include "../dsputil.h" +#include "../mpegvideo.h" +#include "../avcodec.h" +#include "mmx.h" + +extern uint8_t zigzag_direct_noperm[64]; +extern uint16_t inv_zigzag_direct16[64]; + +static const unsigned long long int mm_wabs __attribute__ ((aligned(8))) = 0xffffffffffffffffULL; +static const unsigned long long int mm_wone __attribute__ ((aligned(8))) = 0x0001000100010001ULL; + + +static void dct_unquantize_h263_intra_mmx(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + long level, qmul, qadd, nCoeffs; + + qmul = qscale << 1; + + assert(s->block_last_index[n]>=0 || s->h263_aic); + + if (!s->h263_aic) { + if (n < 4) + level = block[0] * s->y_dc_scale; + else + level = block[0] * s->c_dc_scale; + qadd = (qscale - 1) | 1; + }else{ + qadd = 0; + level= block[0]; + } + if(s->ac_pred) + nCoeffs=63; + else + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; +//printf("%d %d ", qmul, qadd); +asm volatile( + "movd %1, %%mm6 \n\t" //qmul + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "movd %2, %%mm5 \n\t" //qadd + "pxor %%mm7, %%mm7 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "psubw %%mm5, %%mm7 \n\t" + "pxor %%mm4, %%mm4 \n\t" + ".balign 16 \n\t" + "1: \n\t" + "movq (%0, %3), %%mm0 \n\t" + "movq 8(%0, %3), %%mm1 \n\t" + + "pmullw %%mm6, %%mm0 \n\t" + "pmullw %%mm6, %%mm1 \n\t" + + "movq (%0, %3), %%mm2 \n\t" + "movq 8(%0, %3), %%mm3 \n\t" + + "pcmpgtw %%mm4, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm4, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + + "paddw %%mm7, %%mm0 \n\t" + "paddw %%mm7, %%mm1 \n\t" + + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + + "pcmpeqw %%mm7, %%mm0 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw %%mm7, %%mm1 \n\t" // block[i] == 0 ? -1 : 0 + + "pandn %%mm2, %%mm0 \n\t" + "pandn %%mm3, %%mm1 \n\t" + + "movq %%mm0, (%0, %3) \n\t" + "movq %%mm1, 8(%0, %3) \n\t" + + "add $16, %3 \n\t" + "jng 1b \n\t" + ::"r" (block+nCoeffs), "g"(qmul), "g" (qadd), "r" (2*(-nCoeffs)) + : "memory" + ); + block[0]= level; +} + + +static void dct_unquantize_h263_inter_mmx(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + long qmul, qadd, nCoeffs; + + qmul = qscale << 1; + qadd = (qscale - 1) | 1; + + assert(s->block_last_index[n]>=0 || s->h263_aic); + + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; +//printf("%d %d ", qmul, qadd); +asm volatile( + "movd %1, %%mm6 \n\t" //qmul + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "movd %2, %%mm5 \n\t" //qadd + "pxor %%mm7, %%mm7 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "psubw %%mm5, %%mm7 \n\t" + "pxor %%mm4, %%mm4 \n\t" + ".balign 16 \n\t" + "1: \n\t" + "movq (%0, %3), %%mm0 \n\t" + "movq 8(%0, %3), %%mm1 \n\t" + + "pmullw %%mm6, %%mm0 \n\t" + "pmullw %%mm6, %%mm1 \n\t" + + "movq (%0, %3), %%mm2 \n\t" + "movq 8(%0, %3), %%mm3 \n\t" + + "pcmpgtw %%mm4, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm4, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + + "paddw %%mm7, %%mm0 \n\t" + "paddw %%mm7, %%mm1 \n\t" + + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + + "pcmpeqw %%mm7, %%mm0 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw %%mm7, %%mm1 \n\t" // block[i] == 0 ? -1 : 0 + + "pandn %%mm2, %%mm0 \n\t" + "pandn %%mm3, %%mm1 \n\t" + + "movq %%mm0, (%0, %3) \n\t" + "movq %%mm1, 8(%0, %3) \n\t" + + "add $16, %3 \n\t" + "jng 1b \n\t" + ::"r" (block+nCoeffs), "g"(qmul), "g" (qadd), "r" (2*(-nCoeffs)) + : "memory" + ); +} + + +/* + NK: + Note: looking at PARANOID: + "enable all paranoid tests for rounding, overflows, etc..." + +#ifdef PARANOID + if (level < -2048 || level > 2047) + fprintf(stderr, "unquant error %d %d\n", i, level); +#endif + We can suppose that result of two multiplications can't be greate of 0xFFFF + i.e. is 16-bit, so we use here only PMULLW instruction and can avoid + a complex multiplication. +===================================================== + Full formula for multiplication of 2 integer numbers + which are represent as high:low words: + input: value1 = high1:low1 + value2 = high2:low2 + output: value3 = value1*value2 + value3=high3:low3 (on overflow: modulus 2^32 wrap-around) + this mean that for 0x123456 * 0x123456 correct result is 0x766cb0ce4 + but this algorithm will compute only 0x66cb0ce4 + this limited by 16-bit size of operands + --------------------------------- + tlow1 = high1*low2 + tlow2 = high2*low1 + tlow1 = tlow1 + tlow2 + high3:low3 = low1*low2 + high3 += tlow1 +*/ +static void dct_unquantize_mpeg1_intra_mmx(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + long nCoeffs; + const uint16_t *quant_matrix; + int block0; + + assert(s->block_last_index[n]>=0); + + nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1; + + if (n < 4) + block0 = block[0] * s->y_dc_scale; + else + block0 = block[0] * s->c_dc_scale; + /* XXX: only mpeg1 */ + quant_matrix = s->intra_matrix; +asm volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlw $15, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"REG_a" \n\t" + ".balign 16 \n\t" + "1: \n\t" + "movq (%0, %%"REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"REG_a"), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"REG_a"), %%mm5 \n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*q + "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psraw $3, %%mm0 \n\t" + "psraw $3, %%mm1 \n\t" + "psubw %%mm7, %%mm0 \n\t" + "psubw %%mm7, %%mm1 \n\t" + "por %%mm7, %%mm0 \n\t" + "por %%mm7, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "movq %%mm4, (%0, %%"REG_a") \n\t" + "movq %%mm5, 8(%0, %%"REG_a") \n\t" + + "add $16, %%"REG_a" \n\t" + "js 1b \n\t" + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs) + : "%"REG_a, "memory" + ); + block[0]= block0; +} + +static void dct_unquantize_mpeg1_inter_mmx(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + long nCoeffs; + const uint16_t *quant_matrix; + + assert(s->block_last_index[n]>=0); + + nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1; + + quant_matrix = s->inter_matrix; +asm volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlw $15, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"REG_a" \n\t" + ".balign 16 \n\t" + "1: \n\t" + "movq (%0, %%"REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"REG_a"), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"REG_a"), %%mm5 \n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "paddw %%mm0, %%mm0 \n\t" // abs(block[i])*2 + "paddw %%mm1, %%mm1 \n\t" // abs(block[i])*2 + "paddw %%mm7, %%mm0 \n\t" // abs(block[i])*2 + 1 + "paddw %%mm7, %%mm1 \n\t" // abs(block[i])*2 + 1 + "pmullw %%mm4, %%mm0 \n\t" // (abs(block[i])*2 + 1)*q + "pmullw %%mm5, %%mm1 \n\t" // (abs(block[i])*2 + 1)*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psraw $4, %%mm0 \n\t" + "psraw $4, %%mm1 \n\t" + "psubw %%mm7, %%mm0 \n\t" + "psubw %%mm7, %%mm1 \n\t" + "por %%mm7, %%mm0 \n\t" + "por %%mm7, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "movq %%mm4, (%0, %%"REG_a") \n\t" + "movq %%mm5, 8(%0, %%"REG_a") \n\t" + + "add $16, %%"REG_a" \n\t" + "js 1b \n\t" + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs) + : "%"REG_a, "memory" + ); +} + +static void dct_unquantize_mpeg2_intra_mmx(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + long nCoeffs; + const uint16_t *quant_matrix; + int block0; + + assert(s->block_last_index[n]>=0); + + if(s->alternate_scan) nCoeffs= 63; //FIXME + else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; + + if (n < 4) + block0 = block[0] * s->y_dc_scale; + else + block0 = block[0] * s->c_dc_scale; + quant_matrix = s->intra_matrix; +asm volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlw $15, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"REG_a" \n\t" + ".balign 16 \n\t" + "1: \n\t" + "movq (%0, %%"REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"REG_a"), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"REG_a"), %%mm5 \n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*q + "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psraw $3, %%mm0 \n\t" + "psraw $3, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "movq %%mm4, (%0, %%"REG_a") \n\t" + "movq %%mm5, 8(%0, %%"REG_a") \n\t" + + "add $16, %%"REG_a" \n\t" + "jng 1b \n\t" + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs) + : "%"REG_a, "memory" + ); + block[0]= block0; + //Note, we dont do mismatch control for intra as errors cannot accumulate +} + +static void dct_unquantize_mpeg2_inter_mmx(MpegEncContext *s, + DCTELEM *block, int n, int qscale) +{ + long nCoeffs; + const uint16_t *quant_matrix; + + assert(s->block_last_index[n]>=0); + + if(s->alternate_scan) nCoeffs= 63; //FIXME + else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; + + quant_matrix = s->inter_matrix; +asm volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlq $48, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"REG_a" \n\t" + ".balign 16 \n\t" + "1: \n\t" + "movq (%0, %%"REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"REG_a"), %%mm1 \n\t" + "movq (%1, %%"REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"REG_a"), %%mm5 \n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "paddw %%mm0, %%mm0 \n\t" // abs(block[i])*2 + "paddw %%mm1, %%mm1 \n\t" // abs(block[i])*2 + "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*2*q + "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*2*q + "paddw %%mm4, %%mm0 \n\t" // (abs(block[i])*2 + 1)*q + "paddw %%mm5, %%mm1 \n\t" // (abs(block[i])*2 + 1)*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psrlw $4, %%mm0 \n\t" + "psrlw $4, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "pxor %%mm4, %%mm7 \n\t" + "pxor %%mm5, %%mm7 \n\t" + "movq %%mm4, (%0, %%"REG_a") \n\t" + "movq %%mm5, 8(%0, %%"REG_a") \n\t" + + "add $16, %%"REG_a" \n\t" + "jng 1b \n\t" + "movd 124(%0, %3), %%mm0 \n\t" + "movq %%mm7, %%mm6 \n\t" + "psrlq $32, %%mm7 \n\t" + "pxor %%mm6, %%mm7 \n\t" + "movq %%mm7, %%mm6 \n\t" + "psrlq $16, %%mm7 \n\t" + "pxor %%mm6, %%mm7 \n\t" + "pslld $31, %%mm7 \n\t" + "psrlq $15, %%mm7 \n\t" + "pxor %%mm7, %%mm0 \n\t" + "movd %%mm0, 124(%0, %3) \n\t" + + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "r" (-2*nCoeffs) + : "%"REG_a, "memory" + ); +} + +/* draw the edges of width 'w' of an image of size width, height + this mmx version can only handle w==8 || w==16 */ +static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w) +{ + uint8_t *ptr, *last_line; + int i; + + last_line = buf + (height - 1) * wrap; + /* left and right */ + ptr = buf; + if(w==8) + { + asm volatile( + "1: \n\t" + "movd (%0), %%mm0 \n\t" + "punpcklbw %%mm0, %%mm0 \n\t" + "punpcklwd %%mm0, %%mm0 \n\t" + "punpckldq %%mm0, %%mm0 \n\t" + "movq %%mm0, -8(%0) \n\t" + "movq -8(%0, %2), %%mm1 \n\t" + "punpckhbw %%mm1, %%mm1 \n\t" + "punpckhwd %%mm1, %%mm1 \n\t" + "punpckhdq %%mm1, %%mm1 \n\t" + "movq %%mm1, (%0, %2) \n\t" + "add %1, %0 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (ptr) + : "r" ((long)wrap), "r" ((long)width), "r" (ptr + wrap*height) + ); + } + else + { + asm volatile( + "1: \n\t" + "movd (%0), %%mm0 \n\t" + "punpcklbw %%mm0, %%mm0 \n\t" + "punpcklwd %%mm0, %%mm0 \n\t" + "punpckldq %%mm0, %%mm0 \n\t" + "movq %%mm0, -8(%0) \n\t" + "movq %%mm0, -16(%0) \n\t" + "movq -8(%0, %2), %%mm1 \n\t" + "punpckhbw %%mm1, %%mm1 \n\t" + "punpckhwd %%mm1, %%mm1 \n\t" + "punpckhdq %%mm1, %%mm1 \n\t" + "movq %%mm1, (%0, %2) \n\t" + "movq %%mm1, 8(%0, %2) \n\t" + "add %1, %0 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (ptr) + : "r" ((long)wrap), "r" ((long)width), "r" (ptr + wrap*height) + ); + } + + for(i=0;imb_intra; + int *sum= s->dct_error_sum[intra]; + uint16_t *offset= s->dct_offset[intra]; + + s->dct_count[intra]++; + + asm volatile( + "pxor %%mm7, %%mm7 \n\t" + "1: \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "movq (%0), %%mm2 \n\t" + "movq 8(%0), %%mm3 \n\t" + "pcmpgtw %%mm2, %%mm0 \n\t" + "pcmpgtw %%mm3, %%mm1 \n\t" + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + "psubw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq %%mm3, %%mm5 \n\t" + "psubusw (%2), %%mm2 \n\t" + "psubusw 8(%2), %%mm3 \n\t" + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + "psubw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" + "movq %%mm2, (%0) \n\t" + "movq %%mm3, 8(%0) \n\t" + "movq %%mm4, %%mm2 \n\t" + "movq %%mm5, %%mm3 \n\t" + "punpcklwd %%mm7, %%mm4 \n\t" + "punpckhwd %%mm7, %%mm2 \n\t" + "punpcklwd %%mm7, %%mm5 \n\t" + "punpckhwd %%mm7, %%mm3 \n\t" + "paddd (%1), %%mm4 \n\t" + "paddd 8(%1), %%mm2 \n\t" + "paddd 16(%1), %%mm5 \n\t" + "paddd 24(%1), %%mm3 \n\t" + "movq %%mm4, (%1) \n\t" + "movq %%mm2, 8(%1) \n\t" + "movq %%mm5, 16(%1) \n\t" + "movq %%mm3, 24(%1) \n\t" + "add $16, %0 \n\t" + "add $32, %1 \n\t" + "add $16, %2 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (block), "+r" (sum), "+r" (offset) + : "r"(block+64) + ); +} + +static void denoise_dct_sse2(MpegEncContext *s, DCTELEM *block){ + const int intra= s->mb_intra; + int *sum= s->dct_error_sum[intra]; + uint16_t *offset= s->dct_offset[intra]; + + s->dct_count[intra]++; + + asm volatile( + "pxor %%xmm7, %%xmm7 \n\t" + "1: \n\t" + "pxor %%xmm0, %%xmm0 \n\t" + "pxor %%xmm1, %%xmm1 \n\t" + "movdqa (%0), %%xmm2 \n\t" + "movdqa 16(%0), %%xmm3 \n\t" + "pcmpgtw %%xmm2, %%xmm0 \n\t" + "pcmpgtw %%xmm3, %%xmm1 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm3 \n\t" + "psubw %%xmm0, %%xmm2 \n\t" + "psubw %%xmm1, %%xmm3 \n\t" + "movdqa %%xmm2, %%xmm4 \n\t" + "movdqa %%xmm3, %%xmm5 \n\t" + "psubusw (%2), %%xmm2 \n\t" + "psubusw 16(%2), %%xmm3 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm3 \n\t" + "psubw %%xmm0, %%xmm2 \n\t" + "psubw %%xmm1, %%xmm3 \n\t" + "movdqa %%xmm2, (%0) \n\t" + "movdqa %%xmm3, 16(%0) \n\t" + "movdqa %%xmm4, %%xmm6 \n\t" + "movdqa %%xmm5, %%xmm0 \n\t" + "punpcklwd %%xmm7, %%xmm4 \n\t" + "punpckhwd %%xmm7, %%xmm6 \n\t" + "punpcklwd %%xmm7, %%xmm5 \n\t" + "punpckhwd %%xmm7, %%xmm0 \n\t" + "paddd (%1), %%xmm4 \n\t" + "paddd 16(%1), %%xmm6 \n\t" + "paddd 32(%1), %%xmm5 \n\t" + "paddd 48(%1), %%xmm0 \n\t" + "movdqa %%xmm4, (%1) \n\t" + "movdqa %%xmm6, 16(%1) \n\t" + "movdqa %%xmm5, 32(%1) \n\t" + "movdqa %%xmm0, 48(%1) \n\t" + "add $32, %0 \n\t" + "add $64, %1 \n\t" + "add $32, %2 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (block), "+r" (sum), "+r" (offset) + : "r"(block+64) + ); +} + +#undef HAVE_MMX2 +#define RENAME(a) a ## _MMX +#define RENAMEl(a) a ## _mmx +#include "mpegvideo_mmx_template.c" + +#define HAVE_MMX2 +#undef RENAME +#undef RENAMEl +#define RENAME(a) a ## _MMX2 +#define RENAMEl(a) a ## _mmx2 +#include "mpegvideo_mmx_template.c" + +#undef RENAME +#undef RENAMEl +#define RENAME(a) a ## _SSE2 +#define RENAMEl(a) a ## _sse2 +#include "mpegvideo_mmx_template.c" + +void MPV_common_init_mmx(MpegEncContext *s) +{ + if (mm_flags & MM_MMX) { + const int dct_algo = s->avctx->dct_algo; + + s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_mmx; + s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_mmx; + s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_mmx; + s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_mmx; + s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx; + s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx; + + draw_edges = draw_edges_mmx; + + if (mm_flags & MM_SSE2) { + s->denoise_dct= denoise_dct_sse2; + } else { + s->denoise_dct= denoise_dct_mmx; + } + + if(dct_algo==FF_DCT_AUTO || dct_algo==FF_DCT_MMX){ + if(mm_flags & MM_SSE2){ + s->dct_quantize= dct_quantize_SSE2; + } else if(mm_flags & MM_MMXEXT){ + s->dct_quantize= dct_quantize_MMX2; + } else { + s->dct_quantize= dct_quantize_MMX; + } + } + } +} diff --git a/mpeg4/src/libavcodec/i386/mpegvideo_mmx_template.c b/mpeg4/src/libavcodec/i386/mpegvideo_mmx_template.c new file mode 100644 index 00000000..2c50df23 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/mpegvideo_mmx_template.c @@ -0,0 +1,345 @@ +/* + * MPEG video MMX templates + * + * Copyright (c) 2002 Michael Niedermayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#undef SPREADW +#undef PMAXW +#ifdef HAVE_MMX2 +#define SPREADW(a) "pshufw $0, " #a ", " #a " \n\t" +#define PMAXW(a,b) "pmaxsw " #a ", " #b " \n\t" +#define PMAX(a,b) \ + "pshufw $0x0E," #a ", " #b " \n\t"\ + PMAXW(b, a)\ + "pshufw $0x01," #a ", " #b " \n\t"\ + PMAXW(b, a) +#else +#define SPREADW(a) \ + "punpcklwd " #a ", " #a " \n\t"\ + "punpcklwd " #a ", " #a " \n\t" +#define PMAXW(a,b) \ + "psubusw " #a ", " #b " \n\t"\ + "paddw " #a ", " #b " \n\t" +#define PMAX(a,b) \ + "movq " #a ", " #b " \n\t"\ + "psrlq $32, " #a " \n\t"\ + PMAXW(b, a)\ + "movq " #a ", " #b " \n\t"\ + "psrlq $16, " #a " \n\t"\ + PMAXW(b, a) + +#endif + +static int RENAME(dct_quantize)(MpegEncContext *s, + DCTELEM *block, int n, + int qscale, int *overflow) +{ + long last_non_zero_p1; + int level=0, q; //=0 is cuz gcc says uninitalized ... + const uint16_t *qmat, *bias; + DECLARE_ALIGNED_8(int16_t, temp_block[64]); + + assert((7&(int)(&temp_block[0])) == 0); //did gcc align it correctly? + + //s->fdct (block); + RENAMEl(ff_fdct) (block); //cant be anything else ... + + if(s->dct_error_sum) + s->denoise_dct(s, block); + + if (s->mb_intra) { + int dummy; + if (n < 4) + q = s->y_dc_scale; + else + q = s->c_dc_scale; + /* note: block[0] is assumed to be positive */ + if (!s->h263_aic) { +#if 1 + asm volatile ( + "mul %%ecx \n\t" + : "=d" (level), "=a"(dummy) + : "a" ((block[0]>>2) + q), "c" (inverse[q<<1]) + ); +#else + asm volatile ( + "xorl %%edx, %%edx \n\t" + "divw %%cx \n\t" + "movzwl %%ax, %%eax \n\t" + : "=a" (level) + : "a" ((block[0]>>2) + q), "c" (q<<1) + : "%edx" + ); +#endif + } else + /* For AIC we skip quant/dequant of INTRADC */ + level = (block[0] + 4)>>3; + + block[0]=0; //avoid fake overflow +// temp_block[0] = (block[0] + (q >> 1)) / q; + last_non_zero_p1 = 1; + bias = s->q_intra_matrix16[qscale][1]; + qmat = s->q_intra_matrix16[qscale][0]; + } else { + last_non_zero_p1 = 0; + bias = s->q_inter_matrix16[qscale][1]; + qmat = s->q_inter_matrix16[qscale][0]; + } + + if((s->out_format == FMT_H263 || s->out_format == FMT_H261) && s->mpeg_quant==0){ + + asm volatile( + "movd %%"REG_a", %%mm3 \n\t" // last_non_zero_p1 + SPREADW(%%mm3) + "pxor %%mm7, %%mm7 \n\t" // 0 + "pxor %%mm4, %%mm4 \n\t" // 0 + "movq (%2), %%mm5 \n\t" // qmat[0] + "pxor %%mm6, %%mm6 \n\t" + "psubw (%3), %%mm6 \n\t" // -bias[0] + "mov $-128, %%"REG_a" \n\t" + ".balign 16 \n\t" + "1: \n\t" + "pxor %%mm1, %%mm1 \n\t" // 0 + "movq (%1, %%"REG_a"), %%mm0 \n\t" // block[i] + "pcmpgtw %%mm0, %%mm1 \n\t" // block[i] <= 0 ? 0xFF : 0x00 + "pxor %%mm1, %%mm0 \n\t" + "psubw %%mm1, %%mm0 \n\t" // ABS(block[i]) + "psubusw %%mm6, %%mm0 \n\t" // ABS(block[i]) + bias[0] + "pmulhw %%mm5, %%mm0 \n\t" // (ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16 + "por %%mm0, %%mm4 \n\t" + "pxor %%mm1, %%mm0 \n\t" + "psubw %%mm1, %%mm0 \n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) + "movq %%mm0, (%5, %%"REG_a") \n\t" + "pcmpeqw %%mm7, %%mm0 \n\t" // out==0 ? 0xFF : 0x00 + "movq (%4, %%"REG_a"), %%mm1 \n\t" + "movq %%mm7, (%1, %%"REG_a") \n\t" // 0 + "pandn %%mm1, %%mm0 \n\t" + PMAXW(%%mm0, %%mm3) + "add $8, %%"REG_a" \n\t" + " js 1b \n\t" + PMAX(%%mm3, %%mm0) + "movd %%mm3, %%"REG_a" \n\t" + "movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1 + : "+a" (last_non_zero_p1) + : "r" (block+64), "r" (qmat), "r" (bias), + "r" (inv_zigzag_direct16+64), "r" (temp_block+64) + ); + // note the asm is split cuz gcc doesnt like that many operands ... + asm volatile( + "movd %1, %%mm1 \n\t" // max_qcoeff + SPREADW(%%mm1) + "psubusw %%mm1, %%mm4 \n\t" + "packuswb %%mm4, %%mm4 \n\t" + "movd %%mm4, %0 \n\t" // *overflow + : "=g" (*overflow) + : "g" (s->max_qcoeff) + ); + }else{ // FMT_H263 + asm volatile( + "movd %%"REG_a", %%mm3 \n\t" // last_non_zero_p1 + SPREADW(%%mm3) + "pxor %%mm7, %%mm7 \n\t" // 0 + "pxor %%mm4, %%mm4 \n\t" // 0 + "mov $-128, %%"REG_a" \n\t" + ".balign 16 \n\t" + "1: \n\t" + "pxor %%mm1, %%mm1 \n\t" // 0 + "movq (%1, %%"REG_a"), %%mm0 \n\t" // block[i] + "pcmpgtw %%mm0, %%mm1 \n\t" // block[i] <= 0 ? 0xFF : 0x00 + "pxor %%mm1, %%mm0 \n\t" + "psubw %%mm1, %%mm0 \n\t" // ABS(block[i]) + "movq (%3, %%"REG_a"), %%mm6 \n\t" // bias[0] + "paddusw %%mm6, %%mm0 \n\t" // ABS(block[i]) + bias[0] + "movq (%2, %%"REG_a"), %%mm5 \n\t" // qmat[i] + "pmulhw %%mm5, %%mm0 \n\t" // (ABS(block[i])*qmat[0] + bias[0]*qmat[0])>>16 + "por %%mm0, %%mm4 \n\t" + "pxor %%mm1, %%mm0 \n\t" + "psubw %%mm1, %%mm0 \n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) + "movq %%mm0, (%5, %%"REG_a") \n\t" + "pcmpeqw %%mm7, %%mm0 \n\t" // out==0 ? 0xFF : 0x00 + "movq (%4, %%"REG_a"), %%mm1 \n\t" + "movq %%mm7, (%1, %%"REG_a") \n\t" // 0 + "pandn %%mm1, %%mm0 \n\t" + PMAXW(%%mm0, %%mm3) + "add $8, %%"REG_a" \n\t" + " js 1b \n\t" + PMAX(%%mm3, %%mm0) + "movd %%mm3, %%"REG_a" \n\t" + "movzb %%al, %%"REG_a" \n\t" // last_non_zero_p1 + : "+a" (last_non_zero_p1) + : "r" (block+64), "r" (qmat+64), "r" (bias+64), + "r" (inv_zigzag_direct16+64), "r" (temp_block+64) + ); + // note the asm is split cuz gcc doesnt like that many operands ... + asm volatile( + "movd %1, %%mm1 \n\t" // max_qcoeff + SPREADW(%%mm1) + "psubusw %%mm1, %%mm4 \n\t" + "packuswb %%mm4, %%mm4 \n\t" + "movd %%mm4, %0 \n\t" // *overflow + : "=g" (*overflow) + : "g" (s->max_qcoeff) + ); + } + + if(s->mb_intra) block[0]= level; + else block[0]= temp_block[0]; + + if(s->dsp.idct_permutation_type == FF_SIMPLE_IDCT_PERM){ + if(last_non_zero_p1 <= 1) goto end; + block[0x08] = temp_block[0x01]; block[0x10] = temp_block[0x08]; + block[0x20] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x18] = temp_block[0x09]; block[0x04] = temp_block[0x02]; + block[0x09] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x14] = temp_block[0x0A]; block[0x28] = temp_block[0x11]; + block[0x12] = temp_block[0x18]; block[0x02] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x1A] = temp_block[0x19]; block[0x24] = temp_block[0x12]; + block[0x19] = temp_block[0x0B]; block[0x01] = temp_block[0x04]; + block[0x0C] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x11] = temp_block[0x0C]; block[0x29] = temp_block[0x13]; + block[0x16] = temp_block[0x1A]; block[0x0A] = temp_block[0x21]; + block[0x30] = temp_block[0x28]; block[0x22] = temp_block[0x30]; + block[0x38] = temp_block[0x29]; block[0x06] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1B] = temp_block[0x1B]; block[0x21] = temp_block[0x14]; + block[0x1C] = temp_block[0x0D]; block[0x05] = temp_block[0x06]; + block[0x0D] = temp_block[0x07]; block[0x15] = temp_block[0x0E]; + block[0x2C] = temp_block[0x15]; block[0x13] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x0B] = temp_block[0x23]; block[0x34] = temp_block[0x2A]; + block[0x2A] = temp_block[0x31]; block[0x32] = temp_block[0x38]; + block[0x3A] = temp_block[0x39]; block[0x26] = temp_block[0x32]; + block[0x39] = temp_block[0x2B]; block[0x03] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x1E] = temp_block[0x1D]; block[0x25] = temp_block[0x16]; + block[0x1D] = temp_block[0x0F]; block[0x2D] = temp_block[0x17]; + block[0x17] = temp_block[0x1E]; block[0x0E] = temp_block[0x25]; + block[0x31] = temp_block[0x2C]; block[0x2B] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x36] = temp_block[0x3A]; block[0x3B] = temp_block[0x3B]; + block[0x23] = temp_block[0x34]; block[0x3C] = temp_block[0x2D]; + block[0x07] = temp_block[0x26]; block[0x1F] = temp_block[0x1F]; + block[0x0F] = temp_block[0x27]; block[0x35] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x2E] = temp_block[0x35]; block[0x33] = temp_block[0x3C]; + block[0x3E] = temp_block[0x3D]; block[0x27] = temp_block[0x36]; + block[0x3D] = temp_block[0x2F]; block[0x2F] = temp_block[0x37]; + block[0x37] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + }else if(s->dsp.idct_permutation_type == FF_LIBMPEG2_IDCT_PERM){ + if(last_non_zero_p1 <= 1) goto end; + block[0x04] = temp_block[0x01]; + block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x0C] = temp_block[0x09]; block[0x01] = temp_block[0x02]; + block[0x05] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x09] = temp_block[0x0A]; block[0x14] = temp_block[0x11]; + block[0x18] = temp_block[0x18]; block[0x20] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x1C] = temp_block[0x19]; + block[0x11] = temp_block[0x12]; block[0x0D] = temp_block[0x0B]; + block[0x02] = temp_block[0x04]; block[0x06] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x0A] = temp_block[0x0C]; block[0x15] = temp_block[0x13]; + block[0x19] = temp_block[0x1A]; block[0x24] = temp_block[0x21]; + block[0x28] = temp_block[0x28]; block[0x30] = temp_block[0x30]; + block[0x2C] = temp_block[0x29]; block[0x21] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1D] = temp_block[0x1B]; block[0x12] = temp_block[0x14]; + block[0x0E] = temp_block[0x0D]; block[0x03] = temp_block[0x06]; + block[0x07] = temp_block[0x07]; block[0x0B] = temp_block[0x0E]; + block[0x16] = temp_block[0x15]; block[0x1A] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x25] = temp_block[0x23]; block[0x29] = temp_block[0x2A]; + block[0x34] = temp_block[0x31]; block[0x38] = temp_block[0x38]; + block[0x3C] = temp_block[0x39]; block[0x31] = temp_block[0x32]; + block[0x2D] = temp_block[0x2B]; block[0x22] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x1E] = temp_block[0x1D]; block[0x13] = temp_block[0x16]; + block[0x0F] = temp_block[0x0F]; block[0x17] = temp_block[0x17]; + block[0x1B] = temp_block[0x1E]; block[0x26] = temp_block[0x25]; + block[0x2A] = temp_block[0x2C]; block[0x35] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x39] = temp_block[0x3A]; block[0x3D] = temp_block[0x3B]; + block[0x32] = temp_block[0x34]; block[0x2E] = temp_block[0x2D]; + block[0x23] = temp_block[0x26]; block[0x1F] = temp_block[0x1F]; + block[0x27] = temp_block[0x27]; block[0x2B] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x36] = temp_block[0x35]; block[0x3A] = temp_block[0x3C]; + block[0x3E] = temp_block[0x3D]; block[0x33] = temp_block[0x36]; + block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37]; + block[0x3B] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + }else{ + if(last_non_zero_p1 <= 1) goto end; + block[0x01] = temp_block[0x01]; + block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x09] = temp_block[0x09]; block[0x02] = temp_block[0x02]; + block[0x03] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x0A] = temp_block[0x0A]; block[0x11] = temp_block[0x11]; + block[0x18] = temp_block[0x18]; block[0x20] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x19] = temp_block[0x19]; + block[0x12] = temp_block[0x12]; block[0x0B] = temp_block[0x0B]; + block[0x04] = temp_block[0x04]; block[0x05] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x0C] = temp_block[0x0C]; block[0x13] = temp_block[0x13]; + block[0x1A] = temp_block[0x1A]; block[0x21] = temp_block[0x21]; + block[0x28] = temp_block[0x28]; block[0x30] = temp_block[0x30]; + block[0x29] = temp_block[0x29]; block[0x22] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1B] = temp_block[0x1B]; block[0x14] = temp_block[0x14]; + block[0x0D] = temp_block[0x0D]; block[0x06] = temp_block[0x06]; + block[0x07] = temp_block[0x07]; block[0x0E] = temp_block[0x0E]; + block[0x15] = temp_block[0x15]; block[0x1C] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x23] = temp_block[0x23]; block[0x2A] = temp_block[0x2A]; + block[0x31] = temp_block[0x31]; block[0x38] = temp_block[0x38]; + block[0x39] = temp_block[0x39]; block[0x32] = temp_block[0x32]; + block[0x2B] = temp_block[0x2B]; block[0x24] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x1D] = temp_block[0x1D]; block[0x16] = temp_block[0x16]; + block[0x0F] = temp_block[0x0F]; block[0x17] = temp_block[0x17]; + block[0x1E] = temp_block[0x1E]; block[0x25] = temp_block[0x25]; + block[0x2C] = temp_block[0x2C]; block[0x33] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x3A] = temp_block[0x3A]; block[0x3B] = temp_block[0x3B]; + block[0x34] = temp_block[0x34]; block[0x2D] = temp_block[0x2D]; + block[0x26] = temp_block[0x26]; block[0x1F] = temp_block[0x1F]; + block[0x27] = temp_block[0x27]; block[0x2E] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x35] = temp_block[0x35]; block[0x3C] = temp_block[0x3C]; + block[0x3D] = temp_block[0x3D]; block[0x36] = temp_block[0x36]; + block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37]; + block[0x3E] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + } + end: +/* + for(i=0; i + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "../dsputil.h" +#include "../simple_idct.h" + +/* +23170.475006 +22725.260826 +21406.727617 +19265.545870 +16384.000000 +12872.826198 +8866.956905 +4520.335430 +*/ +#define C0 23170 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define C1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define C2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define C3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#if 0 +#define C4 16384 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#else +#define C4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) - 0.5 +#endif +#define C5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define C6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +#define C7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + +#define ROW_SHIFT 11 +#define COL_SHIFT 20 // 6 + +static const uint64_t attribute_used __attribute__((aligned(8))) wm1010= 0xFFFF0000FFFF0000ULL; +static const uint64_t attribute_used __attribute__((aligned(8))) d40000= 0x0000000000040000ULL; + +static const int16_t __attribute__((aligned(8))) coeffs[]= { + 1<<(ROW_SHIFT-1), 0, 1<<(ROW_SHIFT-1), 0, +// 1<<(COL_SHIFT-1), 0, 1<<(COL_SHIFT-1), 0, +// 0, 1<<(COL_SHIFT-1-16), 0, 1<<(COL_SHIFT-1-16), + 1<<(ROW_SHIFT-1), 1, 1<<(ROW_SHIFT-1), 0, + // the 1 = ((1<<(COL_SHIFT-1))/C4)<> COL_SHIFT; + col[8*1] = (a1 + b1) >> COL_SHIFT; + col[8*2] = (a2 + b2) >> COL_SHIFT; + col[8*3] = (a3 + b3) >> COL_SHIFT; + col[8*4] = (a3 - b3) >> COL_SHIFT; + col[8*5] = (a2 - b2) >> COL_SHIFT; + col[8*6] = (a1 - b1) >> COL_SHIFT; + col[8*7] = (a0 - b0) >> COL_SHIFT; +} + +static void inline idctRow (int16_t * output, int16_t * input) +{ + int16_t row[8]; + + int a0, a1, a2, a3, b0, b1, b2, b3; + const int C0 = 23170; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + const int C1 = 22725; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + const int C2 = 21407; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + const int C3 = 19266; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + const int C4 = 16383; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + const int C5 = 12873; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + const int C6 = 8867; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + const int C7 = 4520; //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + +row[0] = input[0]; +row[2] = input[1]; +row[4] = input[4]; +row[6] = input[5]; +row[1] = input[8]; +row[3] = input[9]; +row[5] = input[12]; +row[7] = input[13]; + + if( !(row[1] | row[2] |row[3] |row[4] |row[5] |row[6] | row[7]) ) { + row[0] = row[1] = row[2] = row[3] = row[4] = + row[5] = row[6] = row[7] = row[0]<<3; + output[0] = row[0]; + output[2] = row[1]; + output[4] = row[2]; + output[6] = row[3]; + output[8] = row[4]; + output[10] = row[5]; + output[12] = row[6]; + output[14] = row[7]; + return; + } + + a0 = C4*row[0] + C2*row[2] + C4*row[4] + C6*row[6] + (1<<(ROW_SHIFT-1)); + a1 = C4*row[0] + C6*row[2] - C4*row[4] - C2*row[6] + (1<<(ROW_SHIFT-1)); + a2 = C4*row[0] - C6*row[2] - C4*row[4] + C2*row[6] + (1<<(ROW_SHIFT-1)); + a3 = C4*row[0] - C2*row[2] + C4*row[4] - C6*row[6] + (1<<(ROW_SHIFT-1)); + + b0 = C1*row[1] + C3*row[3] + C5*row[5] + C7*row[7]; + b1 = C3*row[1] - C7*row[3] - C1*row[5] - C5*row[7]; + b2 = C5*row[1] - C1*row[3] + C7*row[5] + C3*row[7]; + b3 = C7*row[1] - C5*row[3] + C3*row[5] - C1*row[7]; + + row[0] = (a0 + b0) >> ROW_SHIFT; + row[1] = (a1 + b1) >> ROW_SHIFT; + row[2] = (a2 + b2) >> ROW_SHIFT; + row[3] = (a3 + b3) >> ROW_SHIFT; + row[4] = (a3 - b3) >> ROW_SHIFT; + row[5] = (a2 - b2) >> ROW_SHIFT; + row[6] = (a1 - b1) >> ROW_SHIFT; + row[7] = (a0 - b0) >> ROW_SHIFT; + + output[0] = row[0]; + output[2] = row[1]; + output[4] = row[2]; + output[6] = row[3]; + output[8] = row[4]; + output[10] = row[5]; + output[12] = row[6]; + output[14] = row[7]; +} +#endif + +static inline void idct(int16_t *block) +{ + int64_t __attribute__((aligned(8))) align_tmp[16]; + int16_t * const temp= (int16_t*)align_tmp; + + asm volatile( +#if 0 //Alternative, simpler variant + +#define ROW_IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq 56(%2), %%mm5 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + #rounder ", %%mm0 \n\t"\ + "paddd %%mm0, %%mm1 \n\t" /* A1 a1 */\ + "paddd %%mm0, %%mm0 \n\t" \ + "psubd %%mm1, %%mm0 \n\t" /* A2 a2 */\ + "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm5, %%mm7 \n\t" /* B0 b0 */\ + "movq 72(%2), %%mm5 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "paddd %%mm2, %%mm5 \n\t" /* B1 b1 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm1, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm5, %%mm1 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm5, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm1 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm1, %%mm7 \n\t" /* A1+B1 a1+b1 A0+B0 a0+b0 */\ + "packssdw %%mm4, %%mm2 \n\t" /* A0-B0 a0-b0 A1-B1 a1-b1 */\ + "movq %%mm7, " #dst " \n\t"\ + "movq " #src1 ", %%mm1 \n\t" /* R3 R1 r3 r1 */\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "movq %%mm2, 24+" #dst " \n\t"\ + "pmaddwd %%mm1, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd 96(%2), %%mm1 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm0, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ + "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm0 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm0 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm1, %%mm3 \n\t" /* B3 b3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "packssdw %%mm6, %%mm2 \n\t" /* A3+B3 a3+b3 A2+B2 a2+b2 */\ + "movq %%mm2, 8+" #dst " \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm0, %%mm4 \n\t" /* A2-B2 a2-b2 A3-B3 a3-b3 */\ + "movq %%mm4, 16+" #dst " \n\t"\ + +#define COL_IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + #rounder ", %%mm0 \n\t"\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq %%mm0, %%mm5 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "paddd %%mm1, %%mm0 \n\t" /* A1 a1 */\ + "psubd %%mm1, %%mm5 \n\t" /* A2 a2 */\ + "movq 56(%2), %%mm1 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm1, %%mm7 \n\t" /* B0 b0 */\ + "movq 72(%2), %%mm1 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "paddd %%mm2, %%mm1 \n\t" /* B1 b1 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm0, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm1, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm1, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm0 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm7, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "movd %%mm7, " #dst " \n\t"\ + "packssdw %%mm0, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "movd %%mm0, 16+" #dst " \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "movd %%mm2, 96+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "movd %%mm4, 112+" #dst " \n\t"\ + "movq " #src1 ", %%mm0 \n\t" /* R3 R1 r3 r1 */\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd 96(%2), %%mm0 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm5, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ + "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm5 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm5 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm0, %%mm3 \n\t" /* B3 b3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "packssdw %%mm6, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "movd %%mm2, 32+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A3-B3 a3-b3 */\ + "packssdw %%mm5, %%mm5 \n\t" /* A2-B2 a2-b2 */\ + "movd %%mm6, 48+" #dst " \n\t"\ + "movd %%mm4, 64+" #dst " \n\t"\ + "movd %%mm5, 80+" #dst " \n\t"\ + + +#define DC_COND_ROW_IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq "MANGLE(wm1010)", %%mm4 \n\t"\ + "pand %%mm0, %%mm4 \n\t"\ + "por %%mm1, %%mm4 \n\t"\ + "por %%mm2, %%mm4 \n\t"\ + "por %%mm3, %%mm4 \n\t"\ + "packssdw %%mm4,%%mm4 \n\t"\ + "movd %%mm4, %%eax \n\t"\ + "orl %%eax, %%eax \n\t"\ + "jz 1f \n\t"\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq 56(%2), %%mm5 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + #rounder ", %%mm0 \n\t"\ + "paddd %%mm0, %%mm1 \n\t" /* A1 a1 */\ + "paddd %%mm0, %%mm0 \n\t" \ + "psubd %%mm1, %%mm0 \n\t" /* A2 a2 */\ + "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm5, %%mm7 \n\t" /* B0 b0 */\ + "movq 72(%2), %%mm5 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "paddd %%mm2, %%mm5 \n\t" /* B1 b1 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm1, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm5, %%mm1 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm5, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm1 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm1, %%mm7 \n\t" /* A1+B1 a1+b1 A0+B0 a0+b0 */\ + "packssdw %%mm4, %%mm2 \n\t" /* A0-B0 a0-b0 A1-B1 a1-b1 */\ + "movq %%mm7, " #dst " \n\t"\ + "movq " #src1 ", %%mm1 \n\t" /* R3 R1 r3 r1 */\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "movq %%mm2, 24+" #dst " \n\t"\ + "pmaddwd %%mm1, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd 96(%2), %%mm1 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm0, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ + "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm0 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm0 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm1, %%mm3 \n\t" /* B3 b3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "packssdw %%mm6, %%mm2 \n\t" /* A3+B3 a3+b3 A2+B2 a2+b2 */\ + "movq %%mm2, 8+" #dst " \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm0, %%mm4 \n\t" /* A2-B2 a2-b2 A3-B3 a3-b3 */\ + "movq %%mm4, 16+" #dst " \n\t"\ + "jmp 2f \n\t"\ + "1: \n\t"\ + "pslld $16, %%mm0 \n\t"\ + "#paddd "MANGLE(d40000)", %%mm0 \n\t"\ + "psrad $13, %%mm0 \n\t"\ + "packssdw %%mm0, %%mm0 \n\t"\ + "movq %%mm0, " #dst " \n\t"\ + "movq %%mm0, 8+" #dst " \n\t"\ + "movq %%mm0, 16+" #dst " \n\t"\ + "movq %%mm0, 24+" #dst " \n\t"\ + "2: \n\t" + + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +ROW_IDCT( (%0), 8(%0), 16(%0), 24(%0), 0(%1),paddd 8(%2), 11) +/*ROW_IDCT( 32(%0), 40(%0), 48(%0), 56(%0), 32(%1), paddd (%2), 11) +ROW_IDCT( 64(%0), 72(%0), 80(%0), 88(%0), 64(%1), paddd (%2), 11) +ROW_IDCT( 96(%0),104(%0),112(%0),120(%0), 96(%1), paddd (%2), 11)*/ + +DC_COND_ROW_IDCT( 32(%0), 40(%0), 48(%0), 56(%0), 32(%1),paddd (%2), 11) +DC_COND_ROW_IDCT( 64(%0), 72(%0), 80(%0), 88(%0), 64(%1),paddd (%2), 11) +DC_COND_ROW_IDCT( 96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11) + + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +COL_IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0),/nop, 20) +COL_IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0),/nop, 20) +COL_IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0),/nop, 20) +COL_IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0),/nop, 20) + +#else + +#define DC_COND_IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq "MANGLE(wm1010)", %%mm4 \n\t"\ + "pand %%mm0, %%mm4 \n\t"\ + "por %%mm1, %%mm4 \n\t"\ + "por %%mm2, %%mm4 \n\t"\ + "por %%mm3, %%mm4 \n\t"\ + "packssdw %%mm4,%%mm4 \n\t"\ + "movd %%mm4, %%eax \n\t"\ + "orl %%eax, %%eax \n\t"\ + "jz 1f \n\t"\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq 56(%2), %%mm5 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + #rounder ", %%mm0 \n\t"\ + "paddd %%mm0, %%mm1 \n\t" /* A1 a1 */\ + "paddd %%mm0, %%mm0 \n\t" \ + "psubd %%mm1, %%mm0 \n\t" /* A2 a2 */\ + "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm5, %%mm7 \n\t" /* B0 b0 */\ + "movq 72(%2), %%mm5 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "paddd %%mm2, %%mm5 \n\t" /* B1 b1 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm1, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm5, %%mm1 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm5, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm1 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm1, %%mm7 \n\t" /* A1+B1 a1+b1 A0+B0 a0+b0 */\ + "packssdw %%mm4, %%mm2 \n\t" /* A0-B0 a0-b0 A1-B1 a1-b1 */\ + "movq %%mm7, " #dst " \n\t"\ + "movq " #src1 ", %%mm1 \n\t" /* R3 R1 r3 r1 */\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "movq %%mm2, 24+" #dst " \n\t"\ + "pmaddwd %%mm1, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd 96(%2), %%mm1 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm0, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ + "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm0 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm0 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm1, %%mm3 \n\t" /* B3 b3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "packssdw %%mm6, %%mm2 \n\t" /* A3+B3 a3+b3 A2+B2 a2+b2 */\ + "movq %%mm2, 8+" #dst " \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm0, %%mm4 \n\t" /* A2-B2 a2-b2 A3-B3 a3-b3 */\ + "movq %%mm4, 16+" #dst " \n\t"\ + "jmp 2f \n\t"\ + "1: \n\t"\ + "pslld $16, %%mm0 \n\t"\ + "paddd "MANGLE(d40000)", %%mm0 \n\t"\ + "psrad $13, %%mm0 \n\t"\ + "packssdw %%mm0, %%mm0 \n\t"\ + "movq %%mm0, " #dst " \n\t"\ + "movq %%mm0, 8+" #dst " \n\t"\ + "movq %%mm0, 16+" #dst " \n\t"\ + "movq %%mm0, 24+" #dst " \n\t"\ + "2: \n\t" + +#define Z_COND_IDCT(src0, src4, src1, src5, dst, rounder, shift, bt) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq %%mm0, %%mm4 \n\t"\ + "por %%mm1, %%mm4 \n\t"\ + "por %%mm2, %%mm4 \n\t"\ + "por %%mm3, %%mm4 \n\t"\ + "packssdw %%mm4,%%mm4 \n\t"\ + "movd %%mm4, %%eax \n\t"\ + "orl %%eax, %%eax \n\t"\ + "jz " #bt " \n\t"\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq 56(%2), %%mm5 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + #rounder ", %%mm0 \n\t"\ + "paddd %%mm0, %%mm1 \n\t" /* A1 a1 */\ + "paddd %%mm0, %%mm0 \n\t" \ + "psubd %%mm1, %%mm0 \n\t" /* A2 a2 */\ + "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm5, %%mm7 \n\t" /* B0 b0 */\ + "movq 72(%2), %%mm5 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "paddd %%mm2, %%mm5 \n\t" /* B1 b1 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm1, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm5, %%mm1 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm5, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm1 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm1, %%mm7 \n\t" /* A1+B1 a1+b1 A0+B0 a0+b0 */\ + "packssdw %%mm4, %%mm2 \n\t" /* A0-B0 a0-b0 A1-B1 a1-b1 */\ + "movq %%mm7, " #dst " \n\t"\ + "movq " #src1 ", %%mm1 \n\t" /* R3 R1 r3 r1 */\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "movq %%mm2, 24+" #dst " \n\t"\ + "pmaddwd %%mm1, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd 96(%2), %%mm1 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm0, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ + "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm0 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm0 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm1, %%mm3 \n\t" /* B3 b3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "packssdw %%mm6, %%mm2 \n\t" /* A3+B3 a3+b3 A2+B2 a2+b2 */\ + "movq %%mm2, 8+" #dst " \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm0, %%mm4 \n\t" /* A2-B2 a2-b2 A3-B3 a3-b3 */\ + "movq %%mm4, 16+" #dst " \n\t"\ + +#define ROW_IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq 56(%2), %%mm5 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + #rounder ", %%mm0 \n\t"\ + "paddd %%mm0, %%mm1 \n\t" /* A1 a1 */\ + "paddd %%mm0, %%mm0 \n\t" \ + "psubd %%mm1, %%mm0 \n\t" /* A2 a2 */\ + "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm5, %%mm7 \n\t" /* B0 b0 */\ + "movq 72(%2), %%mm5 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm5 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "paddd %%mm2, %%mm5 \n\t" /* B1 b1 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm1, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm5, %%mm1 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm5, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm1 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm1, %%mm7 \n\t" /* A1+B1 a1+b1 A0+B0 a0+b0 */\ + "packssdw %%mm4, %%mm2 \n\t" /* A0-B0 a0-b0 A1-B1 a1-b1 */\ + "movq %%mm7, " #dst " \n\t"\ + "movq " #src1 ", %%mm1 \n\t" /* R3 R1 r3 r1 */\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "movq %%mm2, 24+" #dst " \n\t"\ + "pmaddwd %%mm1, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd 96(%2), %%mm1 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm0, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ + "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm0 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm0 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm1, %%mm3 \n\t" /* B3 b3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "packssdw %%mm6, %%mm2 \n\t" /* A3+B3 a3+b3 A2+B2 a2+b2 */\ + "movq %%mm2, 8+" #dst " \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm0, %%mm4 \n\t" /* A2-B2 a2-b2 A3-B3 a3-b3 */\ + "movq %%mm4, 16+" #dst " \n\t"\ + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +DC_COND_IDCT( 0(%0), 8(%0), 16(%0), 24(%0), 0(%1),paddd 8(%2), 11) +Z_COND_IDCT( 32(%0), 40(%0), 48(%0), 56(%0), 32(%1),paddd (%2), 11, 4f) +Z_COND_IDCT( 64(%0), 72(%0), 80(%0), 88(%0), 64(%1),paddd (%2), 11, 2f) +Z_COND_IDCT( 96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11, 1f) + +#undef IDCT +#define IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + #rounder ", %%mm0 \n\t"\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq %%mm0, %%mm5 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "paddd %%mm1, %%mm0 \n\t" /* A1 a1 */\ + "psubd %%mm1, %%mm5 \n\t" /* A2 a2 */\ + "movq 56(%2), %%mm1 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm1, %%mm7 \n\t" /* B0 b0 */\ + "movq 72(%2), %%mm1 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "paddd %%mm2, %%mm1 \n\t" /* B1 b1 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm0, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm1, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm1, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm0 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm7, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "movd %%mm7, " #dst " \n\t"\ + "packssdw %%mm0, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "movd %%mm0, 16+" #dst " \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "movd %%mm2, 96+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "movd %%mm4, 112+" #dst " \n\t"\ + "movq " #src1 ", %%mm0 \n\t" /* R3 R1 r3 r1 */\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd 96(%2), %%mm0 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm5, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ + "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm5 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm5 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm0, %%mm3 \n\t" /* B3 b3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "packssdw %%mm6, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "movd %%mm2, 32+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A3-B3 a3-b3 */\ + "packssdw %%mm5, %%mm5 \n\t" /* A2-B2 a2-b2 */\ + "movd %%mm6, 48+" #dst " \n\t"\ + "movd %%mm4, 64+" #dst " \n\t"\ + "movd %%mm5, 80+" #dst " \n\t" + + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0),/nop, 20) +IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0),/nop, 20) +IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0),/nop, 20) +IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0),/nop, 20) + "jmp 9f \n\t" + + "#.balign 16 \n\t"\ + "4: \n\t" +Z_COND_IDCT( 64(%0), 72(%0), 80(%0), 88(%0), 64(%1),paddd (%2), 11, 6f) +Z_COND_IDCT( 96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11, 5f) + +#undef IDCT +#define IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + #rounder ", %%mm0 \n\t"\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq %%mm0, %%mm5 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "paddd %%mm1, %%mm0 \n\t" /* A1 a1 */\ + "psubd %%mm1, %%mm5 \n\t" /* A2 a2 */\ + "movq 56(%2), %%mm1 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + "movq 72(%2), %%mm7 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm1 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm1, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "psrad $" #shift ", %%mm1 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm0, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm7, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm7, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm0 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm1, %%mm1 \n\t" /* A0+B0 a0+b0 */\ + "movd %%mm1, " #dst " \n\t"\ + "packssdw %%mm0, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "movd %%mm0, 16+" #dst " \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "movd %%mm2, 96+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "movd %%mm4, 112+" #dst " \n\t"\ + "movq 88(%2), %%mm1 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm5, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm1, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm1, %%mm5 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm5 \n\t"\ + "movq %%mm6, %%mm1 \n\t" /* A3 a3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm1 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "psrad $" #shift ", %%mm1 \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "packssdw %%mm6, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "movd %%mm2, 32+" #dst " \n\t"\ + "packssdw %%mm1, %%mm1 \n\t" /* A3-B3 a3-b3 */\ + "packssdw %%mm5, %%mm5 \n\t" /* A2-B2 a2-b2 */\ + "movd %%mm6, 48+" #dst " \n\t"\ + "movd %%mm1, 64+" #dst " \n\t"\ + "movd %%mm5, 80+" #dst " \n\t" + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0),/nop, 20) +IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0),/nop, 20) +IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0),/nop, 20) +IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0),/nop, 20) + "jmp 9f \n\t" + + "#.balign 16 \n\t"\ + "6: \n\t" +Z_COND_IDCT( 96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11, 7f) + +#undef IDCT +#define IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + #rounder ", %%mm0 \n\t"\ + "movq %%mm0, %%mm5 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 56(%2), %%mm1 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + "movq 72(%2), %%mm7 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm1 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm1, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "psrad $" #shift ", %%mm1 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm0, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm7, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm7, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm0 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm1, %%mm1 \n\t" /* A0+B0 a0+b0 */\ + "movd %%mm1, " #dst " \n\t"\ + "packssdw %%mm0, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "movd %%mm0, 16+" #dst " \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "movd %%mm2, 96+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "movd %%mm4, 112+" #dst " \n\t"\ + "movq 88(%2), %%mm1 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm5, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm1, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm1, %%mm5 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm5 \n\t"\ + "movq %%mm6, %%mm1 \n\t" /* A3 a3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm1 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "psrad $" #shift ", %%mm1 \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "packssdw %%mm6, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "movd %%mm2, 32+" #dst " \n\t"\ + "packssdw %%mm1, %%mm1 \n\t" /* A3-B3 a3-b3 */\ + "packssdw %%mm5, %%mm5 \n\t" /* A2-B2 a2-b2 */\ + "movd %%mm6, 48+" #dst " \n\t"\ + "movd %%mm1, 64+" #dst " \n\t"\ + "movd %%mm5, 80+" #dst " \n\t" + + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0),/nop, 20) +IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0),/nop, 20) +IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0),/nop, 20) +IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0),/nop, 20) + "jmp 9f \n\t" + + "#.balign 16 \n\t"\ + "2: \n\t" +Z_COND_IDCT( 96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11, 3f) + +#undef IDCT +#define IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq " #src5 ", %%mm3 \n\t" /* R7 R5 r7 r5 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + #rounder ", %%mm0 \n\t"\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + "movq %%mm0, %%mm5 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 56(%2), %%mm1 \n\t" /* C7 C5 C7 C5 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* C7R7+C5R5 C7r7+C5r5 */\ + "pmaddwd 64(%2), %%mm2 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm1, %%mm7 \n\t" /* B0 b0 */\ + "movq 72(%2), %%mm1 \n\t" /* -C5 -C1 -C5 -C1 */\ + "pmaddwd %%mm3, %%mm1 \n\t" /* -C5R7-C1R5 -C5r7-C1r5 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "paddd %%mm2, %%mm1 \n\t" /* B1 b1 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm0, %%mm2 \n\t" /* A1 a1 */\ + "paddd %%mm1, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm1, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm0 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm7, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "movd %%mm7, " #dst " \n\t"\ + "packssdw %%mm0, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "movd %%mm0, 16+" #dst " \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A1-B1 a1-b1 */\ + "movd %%mm2, 96+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "movd %%mm4, 112+" #dst " \n\t"\ + "movq " #src1 ", %%mm0 \n\t" /* R3 R1 r3 r1 */\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "movq 88(%2), %%mm7 \n\t" /* C3 C7 C3 C7 */\ + "pmaddwd 96(%2), %%mm0 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* C3R7+C7R5 C3r7+C7r5 */\ + "movq %%mm5, %%mm2 \n\t" /* A2 a2 */\ + "pmaddwd 104(%2), %%mm3 \n\t" /* -C1R7+C3R5 -C1r7+C3r5 */\ + "paddd %%mm7, %%mm4 \n\t" /* B2 b2 */\ + "paddd %%mm4, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm5 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm5 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm0, %%mm3 \n\t" /* B3 b3 */\ + "paddd %%mm3, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm3, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm2, %%mm2 \n\t" /* A2+B2 a2+b2 */\ + "packssdw %%mm6, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "movd %%mm2, 32+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A3-B3 a3-b3 */\ + "packssdw %%mm5, %%mm5 \n\t" /* A2-B2 a2-b2 */\ + "movd %%mm6, 48+" #dst " \n\t"\ + "movd %%mm4, 64+" #dst " \n\t"\ + "movd %%mm5, 80+" #dst " \n\t" + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0),/nop, 20) +IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0),/nop, 20) +IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0),/nop, 20) +IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0),/nop, 20) + "jmp 9f \n\t" + + "#.balign 16 \n\t"\ + "3: \n\t" +#undef IDCT +#define IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + #rounder ", %%mm0 \n\t"\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + "movq %%mm0, %%mm5 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 64(%2), %%mm3 \n\t"\ + "pmaddwd %%mm2, %%mm3 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm0, %%mm1 \n\t" /* A1 a1 */\ + "paddd %%mm3, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm3, %%mm1 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm0 \n\t"\ + "psrad $" #shift ", %%mm1 \n\t"\ + "packssdw %%mm7, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "movd %%mm7, " #dst " \n\t"\ + "packssdw %%mm0, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "movd %%mm0, 16+" #dst " \n\t"\ + "packssdw %%mm1, %%mm1 \n\t" /* A1-B1 a1-b1 */\ + "movd %%mm1, 96+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "movd %%mm4, 112+" #dst " \n\t"\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "pmaddwd %%mm2, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "pmaddwd 96(%2), %%mm2 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "movq %%mm5, %%mm1 \n\t" /* A2 a2 */\ + "paddd %%mm4, %%mm1 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm5 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm1 \n\t"\ + "psrad $" #shift ", %%mm5 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm2, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm2, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm1, %%mm1 \n\t" /* A2+B2 a2+b2 */\ + "packssdw %%mm6, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "movd %%mm1, 32+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A3-B3 a3-b3 */\ + "packssdw %%mm5, %%mm5 \n\t" /* A2-B2 a2-b2 */\ + "movd %%mm6, 48+" #dst " \n\t"\ + "movd %%mm4, 64+" #dst " \n\t"\ + "movd %%mm5, 80+" #dst " \n\t" + + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0),/nop, 20) +IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0),/nop, 20) +IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0),/nop, 20) +IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0),/nop, 20) + "jmp 9f \n\t" + + "#.balign 16 \n\t"\ + "5: \n\t" +#undef IDCT +#define IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + #rounder ", %%mm0 \n\t"\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq %%mm0, %%mm5 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "paddd %%mm1, %%mm0 \n\t" /* A1 a1 */\ + "psubd %%mm1, %%mm5 \n\t" /* A2 a2 */\ + "movq 8+" #src0 ", %%mm2 \n\t" /* R4 R0 r4 r0 */\ + "movq 8+" #src4 ", %%mm3 \n\t" /* R6 R2 r6 r2 */\ + "movq 16(%2), %%mm1 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm2, %%mm1 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm7 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm7, %%mm2 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm7 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm3, %%mm7 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "pmaddwd 40(%2), %%mm3 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + #rounder ", %%mm1 \n\t"\ + "paddd %%mm1, %%mm7 \n\t" /* A0 a0 */\ + "paddd %%mm1, %%mm1 \n\t" /* 2C0 2c0 */\ + #rounder ", %%mm2 \n\t"\ + "psubd %%mm7, %%mm1 \n\t" /* A3 a3 */\ + "paddd %%mm2, %%mm3 \n\t" /* A1 a1 */\ + "paddd %%mm2, %%mm2 \n\t" /* 2C1 2c1 */\ + "psubd %%mm3, %%mm2 \n\t" /* A2 a2 */\ + "psrad $" #shift ", %%mm4 \n\t"\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm3 \n\t"\ + "packssdw %%mm7, %%mm4 \n\t" /* A0 a0 */\ + "movq %%mm4, " #dst " \n\t"\ + "psrad $" #shift ", %%mm0 \n\t"\ + "packssdw %%mm3, %%mm0 \n\t" /* A1 a1 */\ + "movq %%mm0, 16+" #dst " \n\t"\ + "movq %%mm0, 96+" #dst " \n\t"\ + "movq %%mm4, 112+" #dst " \n\t"\ + "psrad $" #shift ", %%mm5 \n\t"\ + "psrad $" #shift ", %%mm6 \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm2, %%mm5 \n\t" /* A2-B2 a2-b2 */\ + "movq %%mm5, 32+" #dst " \n\t"\ + "psrad $" #shift ", %%mm1 \n\t"\ + "packssdw %%mm1, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "movq %%mm6, 48+" #dst " \n\t"\ + "movq %%mm6, 64+" #dst " \n\t"\ + "movq %%mm5, 80+" #dst " \n\t" + + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +IDCT( 0(%1), 64(%1), 32(%1), 96(%1), 0(%0),/nop, 20) +//IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0),/nop, 20) +IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0),/nop, 20) +//IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0),/nop, 20) + "jmp 9f \n\t" + + + "#.balign 16 \n\t"\ + "1: \n\t" +#undef IDCT +#define IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq " #src4 ", %%mm1 \n\t" /* R6 R2 r6 r2 */\ + "movq " #src1 ", %%mm2 \n\t" /* R3 R1 r3 r1 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm5 \n\t" /* C6 C2 C6 C2 */\ + "pmaddwd %%mm1, %%mm5 \n\t" /* C6R6+C2R2 C6r6+C2r2 */\ + "movq 40(%2), %%mm6 \n\t" /* -C2 C6 -C2 C6 */\ + "pmaddwd %%mm6, %%mm1 \n\t" /* -C2R6+C6R2 -C2r6+C6r2 */\ + #rounder ", %%mm4 \n\t"\ + "movq %%mm4, %%mm6 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 48(%2), %%mm7 \n\t" /* C3 C1 C3 C1 */\ + #rounder ", %%mm0 \n\t"\ + "pmaddwd %%mm2, %%mm7 \n\t" /* C3R3+C1R1 C3r3+C1r1 */\ + "paddd %%mm5, %%mm4 \n\t" /* A0 a0 */\ + "psubd %%mm5, %%mm6 \n\t" /* A3 a3 */\ + "movq %%mm0, %%mm5 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "paddd %%mm1, %%mm0 \n\t" /* A1 a1 */\ + "psubd %%mm1, %%mm5 \n\t" /* A2 a2 */\ + "movq 64(%2), %%mm1 \n\t"\ + "pmaddwd %%mm2, %%mm1 \n\t" /* -C7R3+C3R1 -C7r3+C3r1 */\ + "paddd %%mm4, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "paddd %%mm4, %%mm4 \n\t" /* 2A0 2a0 */\ + "psubd %%mm7, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "psrad $" #shift ", %%mm7 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "movq %%mm0, %%mm3 \n\t" /* A1 a1 */\ + "paddd %%mm1, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "psubd %%mm1, %%mm3 \n\t" /* A1-B1 a1-b1 */\ + "psrad $" #shift ", %%mm0 \n\t"\ + "psrad $" #shift ", %%mm3 \n\t"\ + "packssdw %%mm7, %%mm7 \n\t" /* A0+B0 a0+b0 */\ + "movd %%mm7, " #dst " \n\t"\ + "packssdw %%mm0, %%mm0 \n\t" /* A1+B1 a1+b1 */\ + "movd %%mm0, 16+" #dst " \n\t"\ + "packssdw %%mm3, %%mm3 \n\t" /* A1-B1 a1-b1 */\ + "movd %%mm3, 96+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A0-B0 a0-b0 */\ + "movd %%mm4, 112+" #dst " \n\t"\ + "movq 80(%2), %%mm4 \n\t" /* -C1 C5 -C1 C5 */\ + "pmaddwd %%mm2, %%mm4 \n\t" /* -C1R3+C5R1 -C1r3+C5r1 */\ + "pmaddwd 96(%2), %%mm2 \n\t" /* -C5R3+C7R1 -C5r3+C7r1 */\ + "movq %%mm5, %%mm3 \n\t" /* A2 a2 */\ + "paddd %%mm4, %%mm3 \n\t" /* A2+B2 a2+b2 */\ + "psubd %%mm4, %%mm5 \n\t" /* a2-B2 a2-b2 */\ + "psrad $" #shift ", %%mm3 \n\t"\ + "psrad $" #shift ", %%mm5 \n\t"\ + "movq %%mm6, %%mm4 \n\t" /* A3 a3 */\ + "paddd %%mm2, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "psubd %%mm2, %%mm4 \n\t" /* a3-B3 a3-b3 */\ + "psrad $" #shift ", %%mm6 \n\t"\ + "packssdw %%mm3, %%mm3 \n\t" /* A2+B2 a2+b2 */\ + "movd %%mm3, 32+" #dst " \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "packssdw %%mm6, %%mm6 \n\t" /* A3+B3 a3+b3 */\ + "movd %%mm6, 48+" #dst " \n\t"\ + "packssdw %%mm4, %%mm4 \n\t" /* A3-B3 a3-b3 */\ + "packssdw %%mm5, %%mm5 \n\t" /* A2-B2 a2-b2 */\ + "movd %%mm4, 64+" #dst " \n\t"\ + "movd %%mm5, 80+" #dst " \n\t" + + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +IDCT( (%1), 64(%1), 32(%1), 96(%1), 0(%0),/nop, 20) +IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0),/nop, 20) +IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0),/nop, 20) +IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0),/nop, 20) + "jmp 9f \n\t" + + + "#.balign 16 \n\t" + "7: \n\t" +#undef IDCT +#define IDCT(src0, src4, src1, src5, dst, rounder, shift) \ + "movq " #src0 ", %%mm0 \n\t" /* R4 R0 r4 r0 */\ + "movq 16(%2), %%mm4 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm0, %%mm4 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm5 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm5, %%mm0 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + #rounder ", %%mm4 \n\t"\ + #rounder ", %%mm0 \n\t"\ + "psrad $" #shift ", %%mm4 \n\t"\ + "psrad $" #shift ", %%mm0 \n\t"\ + "movq 8+" #src0 ", %%mm2 \n\t" /* R4 R0 r4 r0 */\ + "movq 16(%2), %%mm1 \n\t" /* C4 C4 C4 C4 */\ + "pmaddwd %%mm2, %%mm1 \n\t" /* C4R4+C4R0 C4r4+C4r0 */\ + "movq 24(%2), %%mm7 \n\t" /* -C4 C4 -C4 C4 */\ + "pmaddwd %%mm7, %%mm2 \n\t" /* -C4R4+C4R0 -C4r4+C4r0 */\ + "movq 32(%2), %%mm7 \n\t" /* C6 C2 C6 C2 */\ + #rounder ", %%mm1 \n\t"\ + #rounder ", %%mm2 \n\t"\ + "psrad $" #shift ", %%mm1 \n\t"\ + "packssdw %%mm1, %%mm4 \n\t" /* A0 a0 */\ + "movq %%mm4, " #dst " \n\t"\ + "psrad $" #shift ", %%mm2 \n\t"\ + "packssdw %%mm2, %%mm0 \n\t" /* A1 a1 */\ + "movq %%mm0, 16+" #dst " \n\t"\ + "movq %%mm0, 96+" #dst " \n\t"\ + "movq %%mm4, 112+" #dst " \n\t"\ + "movq %%mm0, 32+" #dst " \n\t"\ + "movq %%mm4, 48+" #dst " \n\t"\ + "movq %%mm4, 64+" #dst " \n\t"\ + "movq %%mm0, 80+" #dst " \n\t" + +//IDCT( src0, src4, src1, src5, dst, rounder, shift) +IDCT( 0(%1), 64(%1), 32(%1), 96(%1), 0(%0),/nop, 20) +//IDCT( 8(%1), 72(%1), 40(%1), 104(%1), 4(%0),/nop, 20) +IDCT( 16(%1), 80(%1), 48(%1), 112(%1), 8(%0),/nop, 20) +//IDCT( 24(%1), 88(%1), 56(%1), 120(%1), 12(%0),/nop, 20) + + +#endif + +/* +Input + 00 40 04 44 20 60 24 64 + 10 30 14 34 50 70 54 74 + 01 41 03 43 21 61 23 63 + 11 31 13 33 51 71 53 73 + 02 42 06 46 22 62 26 66 + 12 32 16 36 52 72 56 76 + 05 45 07 47 25 65 27 67 + 15 35 17 37 55 75 57 77 + +Temp + 00 04 10 14 20 24 30 34 + 40 44 50 54 60 64 70 74 + 01 03 11 13 21 23 31 33 + 41 43 51 53 61 63 71 73 + 02 06 12 16 22 26 32 36 + 42 46 52 56 62 66 72 76 + 05 07 15 17 25 27 35 37 + 45 47 55 57 65 67 75 77 +*/ + +"9: \n\t" + :: "r" (block), "r" (temp), "r" (coeffs) + : "%eax" + ); +} + +void ff_simple_idct_mmx(int16_t *block) +{ + idct(block); +} + +//FIXME merge add/put into the idct + +void ff_simple_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block) +{ + idct(block); + put_pixels_clamped_mmx(block, dest, line_size); +} +void ff_simple_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block) +{ + idct(block); + add_pixels_clamped_mmx(block, dest, line_size); +} diff --git a/mpeg4/src/libavcodec/i386/snowdsp_mmx.c b/mpeg4/src/libavcodec/i386/snowdsp_mmx.c new file mode 100644 index 00000000..5f17e359 --- /dev/null +++ b/mpeg4/src/libavcodec/i386/snowdsp_mmx.c @@ -0,0 +1,917 @@ +/* + * MMX and SSE2 optimized snow DSP utils + * Copyright (c) 2005-2006 Robert Edele + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "../avcodec.h" +#include "../snow.h" +#include "mmx.h" + +void ff_snow_horizontal_compose97i_sse2(DWTELEM *b, int width){ + const int w2= (width+1)>>1; + // SSE2 code runs faster with pointers aligned on a 32-byte boundary. + DWTELEM temp_buf[(width>>1) + 4]; + DWTELEM * const temp = temp_buf + 4 - (((int)temp_buf & 0xF) >> 2); + const int w_l= (width>>1); + const int w_r= w2 - 1; + int i; + + { // Lift 0 + DWTELEM * const ref = b + w2 - 1; + DWTELEM b_0 = b[0]; //By allowing the first entry in b[0] to be calculated twice + // (the first time erroneously), we allow the SSE2 code to run an extra pass. + // The savings in code and time are well worth having to store this value and + // calculate b[0] correctly afterwards. + + i = 0; + asm volatile( + "pcmpeqd %%xmm7, %%xmm7 \n\t" + "pslld $31, %%xmm7 \n\t" + "psrld $29, %%xmm7 \n\t" + ::); + for(; i>W_DS); + } + + { // Lift 1 + DWTELEM * const dst = b+w2; + + i = 0; + for(; (((long)&dst[i]) & 0xF) && i> W_BS); + } + + { // Lift 3 + DWTELEM * const src = b+w2; + + i = 0; + for(; (((long)&temp[i]) & 0xF) && i>W_AS); + } + for(; i>1]; + b[i] = b[i>>1]; + } + for (i-=30; i>=0; i-=32){ + asm volatile( + "movdqa (%1), %%xmm0 \n\t" + "movdqa 16(%1), %%xmm2 \n\t" + "movdqa 32(%1), %%xmm4 \n\t" + "movdqa 48(%1), %%xmm6 \n\t" + "movdqa (%1), %%xmm1 \n\t" + "movdqa 16(%1), %%xmm3 \n\t" + "movdqa 32(%1), %%xmm5 \n\t" + "movdqa 48(%1), %%xmm7 \n\t" + "punpckldq (%2), %%xmm0 \n\t" + "punpckldq 16(%2), %%xmm2 \n\t" + "punpckldq 32(%2), %%xmm4 \n\t" + "punpckldq 48(%2), %%xmm6 \n\t" + "movdqa %%xmm0, (%0) \n\t" + "movdqa %%xmm2, 32(%0) \n\t" + "movdqa %%xmm4, 64(%0) \n\t" + "movdqa %%xmm6, 96(%0) \n\t" + "punpckhdq (%2), %%xmm1 \n\t" + "punpckhdq 16(%2), %%xmm3 \n\t" + "punpckhdq 32(%2), %%xmm5 \n\t" + "punpckhdq 48(%2), %%xmm7 \n\t" + "movdqa %%xmm1, 16(%0) \n\t" + "movdqa %%xmm3, 48(%0) \n\t" + "movdqa %%xmm5, 80(%0) \n\t" + "movdqa %%xmm7, 112(%0) \n\t" + :: "r"(&(b)[i]), "r"(&(b)[i>>1]), "r"(&(temp)[i>>1]) + : "memory" + ); + } + } +} + +void ff_snow_horizontal_compose97i_mmx(DWTELEM *b, int width){ + const int w2= (width+1)>>1; + DWTELEM temp[width >> 1]; + const int w_l= (width>>1); + const int w_r= w2 - 1; + int i; + + { // Lift 0 + DWTELEM * const ref = b + w2 - 1; + + i = 1; + b[0] = b[0] - ((W_DM * 2 * ref[1]+W_DO)>>W_DS); + asm volatile( + "pcmpeqd %%mm7, %%mm7 \n\t" + "pslld $31, %%mm7 \n\t" + "psrld $29, %%mm7 \n\t" + ::); + for(; i> W_BS); + asm volatile( + "pslld $1, %%mm7 \n\t" /* xmm7 already holds a '4' from 2 lifts ago. */ + ::); + for(; i>1]; + b[i] = b[i>>1]; + } + for (i-=14; i>=0; i-=16){ + asm volatile( + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm2 \n\t" + "movq 16(%1), %%mm4 \n\t" + "movq 24(%1), %%mm6 \n\t" + "movq (%1), %%mm1 \n\t" + "movq 8(%1), %%mm3 \n\t" + "movq 16(%1), %%mm5 \n\t" + "movq 24(%1), %%mm7 \n\t" + "punpckldq (%2), %%mm0 \n\t" + "punpckldq 8(%2), %%mm2 \n\t" + "punpckldq 16(%2), %%mm4 \n\t" + "punpckldq 24(%2), %%mm6 \n\t" + "movq %%mm0, (%0) \n\t" + "movq %%mm2, 16(%0) \n\t" + "movq %%mm4, 32(%0) \n\t" + "movq %%mm6, 48(%0) \n\t" + "punpckhdq (%2), %%mm1 \n\t" + "punpckhdq 8(%2), %%mm3 \n\t" + "punpckhdq 16(%2), %%mm5 \n\t" + "punpckhdq 24(%2), %%mm7 \n\t" + "movq %%mm1, 8(%0) \n\t" + "movq %%mm3, 24(%0) \n\t" + "movq %%mm5, 40(%0) \n\t" + "movq %%mm7, 56(%0) \n\t" + :: "r"(&b[i]), "r"(&b[i>>1]), "r"(&temp[i>>1]) + : "memory" + ); + } + } +} + +#define snow_vertical_compose_sse2_load_add(op,r,t0,t1,t2,t3)\ + ""op" (%%"r",%%"REG_d",4), %%"t0" \n\t"\ + ""op" 16(%%"r",%%"REG_d",4), %%"t1" \n\t"\ + ""op" 32(%%"r",%%"REG_d",4), %%"t2" \n\t"\ + ""op" 48(%%"r",%%"REG_d",4), %%"t3" \n\t" + +#define snow_vertical_compose_sse2_load(r,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_load_add("movdqa",r,t0,t1,t2,t3) + +#define snow_vertical_compose_sse2_add(r,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_load_add("paddd",r,t0,t1,t2,t3) + +#define snow_vertical_compose_sse2_sub(s0,s1,s2,s3,t0,t1,t2,t3)\ + "psubd %%"s0", %%"t0" \n\t"\ + "psubd %%"s1", %%"t1" \n\t"\ + "psubd %%"s2", %%"t2" \n\t"\ + "psubd %%"s3", %%"t3" \n\t" + +#define snow_vertical_compose_sse2_store(w,s0,s1,s2,s3)\ + "movdqa %%"s0", (%%"w",%%"REG_d",4) \n\t"\ + "movdqa %%"s1", 16(%%"w",%%"REG_d",4) \n\t"\ + "movdqa %%"s2", 32(%%"w",%%"REG_d",4) \n\t"\ + "movdqa %%"s3", 48(%%"w",%%"REG_d",4) \n\t" + +#define snow_vertical_compose_sse2_sra(n,t0,t1,t2,t3)\ + "psrad $"n", %%"t0" \n\t"\ + "psrad $"n", %%"t1" \n\t"\ + "psrad $"n", %%"t2" \n\t"\ + "psrad $"n", %%"t3" \n\t" + +#define snow_vertical_compose_sse2_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3)\ + "paddd %%"s0", %%"t0" \n\t"\ + "paddd %%"s1", %%"t1" \n\t"\ + "paddd %%"s2", %%"t2" \n\t"\ + "paddd %%"s3", %%"t3" \n\t" + +#define snow_vertical_compose_sse2_sll(n,t0,t1,t2,t3)\ + "pslld $"n", %%"t0" \n\t"\ + "pslld $"n", %%"t1" \n\t"\ + "pslld $"n", %%"t2" \n\t"\ + "pslld $"n", %%"t3" \n\t" + +#define snow_vertical_compose_sse2_move(s0,s1,s2,s3,t0,t1,t2,t3)\ + "movdqa %%"s0", %%"t0" \n\t"\ + "movdqa %%"s1", %%"t1" \n\t"\ + "movdqa %%"s2", %%"t2" \n\t"\ + "movdqa %%"s3", %%"t3" \n\t" + +void ff_snow_vertical_compose97i_sse2(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width){ + long i = width; + + while(i & 0xF) + { + i--; + b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; + b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; + b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; + b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; + } + + asm volatile ( + "jmp 2f \n\t" + "1: \n\t" + + "mov %6, %%"REG_a" \n\t" + "mov %4, %%"REG_b" \n\t" + + snow_vertical_compose_sse2_load(REG_b,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add(REG_a,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_move("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_sll("1","xmm0","xmm2","xmm4","xmm6")\ + snow_vertical_compose_sse2_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + + "pcmpeqd %%xmm1, %%xmm1 \n\t" + "pslld $31, %%xmm1 \n\t" + "psrld $29, %%xmm1 \n\t" + "mov %5, %%"REG_a" \n\t" + + snow_vertical_compose_sse2_r2r_add("xmm1","xmm1","xmm1","xmm1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_sra("3","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_load(REG_a,"xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_sub("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_store(REG_a,"xmm1","xmm3","xmm5","xmm7") + "mov %3, %%"REG_c" \n\t" + snow_vertical_compose_sse2_load(REG_b,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add(REG_c,"xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_sub("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store(REG_b,"xmm0","xmm2","xmm4","xmm6") + "mov %2, %%"REG_a" \n\t" + snow_vertical_compose_sse2_load(REG_c,"xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_add(REG_a,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_sll("2","xmm1","xmm3","xmm5","xmm7")\ + snow_vertical_compose_sse2_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + + "pcmpeqd %%xmm1, %%xmm1 \n\t" + "pslld $31, %%xmm1 \n\t" + "psrld $28, %%xmm1 \n\t" + "mov %1, %%"REG_b" \n\t" + + snow_vertical_compose_sse2_r2r_add("xmm1","xmm1","xmm1","xmm1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_sra("4","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add(REG_c,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store(REG_c,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add(REG_b,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_move("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_sll("1","xmm0","xmm2","xmm4","xmm6")\ + snow_vertical_compose_sse2_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_sra("1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add(REG_a,"xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store(REG_a,"xmm0","xmm2","xmm4","xmm6") + + "2: \n\t" + "sub $16, %%"REG_d" \n\t" + "jge 1b \n\t" + :"+d"(i) + : + "m"(b0),"m"(b1),"m"(b2),"m"(b3),"m"(b4),"m"(b5): + "%"REG_a"","%"REG_b"","%"REG_c""); +} + +#define snow_vertical_compose_mmx_load_add(op,r,t0,t1,t2,t3)\ + ""op" (%%"r",%%"REG_d",4), %%"t0" \n\t"\ + ""op" 8(%%"r",%%"REG_d",4), %%"t1" \n\t"\ + ""op" 16(%%"r",%%"REG_d",4), %%"t2" \n\t"\ + ""op" 24(%%"r",%%"REG_d",4), %%"t3" \n\t" + +#define snow_vertical_compose_mmx_load(r,t0,t1,t2,t3)\ + snow_vertical_compose_mmx_load_add("movq",r,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_add(r,t0,t1,t2,t3)\ + snow_vertical_compose_mmx_load_add("paddd",r,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_sub(s0,s1,s2,s3,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_sub(s0,s1,s2,s3,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_store(w,s0,s1,s2,s3)\ + "movq %%"s0", (%%"w",%%"REG_d",4) \n\t"\ + "movq %%"s1", 8(%%"w",%%"REG_d",4) \n\t"\ + "movq %%"s2", 16(%%"w",%%"REG_d",4) \n\t"\ + "movq %%"s3", 24(%%"w",%%"REG_d",4) \n\t" + +#define snow_vertical_compose_mmx_sra(n,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_sra(n,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_sll(n,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_sll(n,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_move(s0,s1,s2,s3,t0,t1,t2,t3)\ + "movq %%"s0", %%"t0" \n\t"\ + "movq %%"s1", %%"t1" \n\t"\ + "movq %%"s2", %%"t2" \n\t"\ + "movq %%"s3", %%"t3" \n\t" + +void ff_snow_vertical_compose97i_mmx(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, DWTELEM *b3, DWTELEM *b4, DWTELEM *b5, int width){ + long i = width; + while(i & 0x7) + { + i--; + b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; + b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; + b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; + b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; + } + + asm volatile( + "jmp 2f \n\t" + "1: \n\t" + + "mov %6, %%"REG_a" \n\t" + "mov %4, %%"REG_b" \n\t" + + snow_vertical_compose_mmx_load(REG_b,"mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add(REG_a,"mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_move("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_sll("1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + + "pcmpeqd %%mm1, %%mm1 \n\t" + "pslld $31, %%mm1 \n\t" + "psrld $29, %%mm1 \n\t" + "mov %5, %%"REG_a" \n\t" + + snow_vertical_compose_mmx_r2r_add("mm1","mm1","mm1","mm1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_sra("3","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_load(REG_a,"mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_sub("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_store(REG_a,"mm1","mm3","mm5","mm7") + "mov %3, %%"REG_c" \n\t" + snow_vertical_compose_mmx_load(REG_b,"mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add(REG_c,"mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_sub("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store(REG_b,"mm0","mm2","mm4","mm6") + "mov %2, %%"REG_a" \n\t" + snow_vertical_compose_mmx_load(REG_c,"mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_add(REG_a,"mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_sll("2","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + + "pcmpeqd %%mm1, %%mm1 \n\t" + "pslld $31, %%mm1 \n\t" + "psrld $28, %%mm1 \n\t" + "mov %1, %%"REG_b" \n\t" + + snow_vertical_compose_mmx_r2r_add("mm1","mm1","mm1","mm1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_sra("4","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add(REG_c,"mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store(REG_c,"mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add(REG_b,"mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_move("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_sll("1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_sra("1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add(REG_a,"mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store(REG_a,"mm0","mm2","mm4","mm6") + + "2: \n\t" + "sub $8, %%"REG_d" \n\t" + "jge 1b \n\t" + :"+d"(i) + : + "m"(b0),"m"(b1),"m"(b2),"m"(b3),"m"(b4),"m"(b5): + "%"REG_a"","%"REG_b"","%"REG_c""); +} + +#define snow_inner_add_yblock_sse2_header \ + DWTELEM * * dst_array = sb->line + src_y;\ + asm volatile(\ + "mov %6, %%"REG_c" \n\t"\ + "mov %5, %%"REG_b" \n\t"\ + "mov %3, %%"REG_S" \n\t"\ + "pxor %%xmm7, %%xmm7 \n\t" /* 0 */\ + "pcmpeqd %%xmm3, %%xmm3 \n\t"\ + "pslld $31, %%xmm3 \n\t"\ + "psrld $24, %%xmm3 \n\t" /* FRAC_BITS >> 1 */\ + "1: \n\t"\ + "mov %1, %%"REG_D" \n\t"\ + "mov (%%"REG_D"), %%"REG_D" \n\t"\ + "add %2, %%"REG_D" \n\t" + +#define snow_inner_add_yblock_sse2_start_8(out_reg1, out_reg2, ptr_offset, s_offset)\ + "mov "PTR_SIZE"*"ptr_offset"(%%"REG_a"), %%"REG_d"; \n\t"\ + "movq (%%"REG_d"), %%"out_reg1" \n\t"\ + "movq (%%"REG_d", %%"REG_c"), %%"out_reg2" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg1" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg2" \n\t"\ + "movq "s_offset"(%%"REG_S"), %%xmm0 \n\t"\ + "movq "s_offset"+16(%%"REG_S"), %%xmm4 \n\t"\ + "punpcklbw %%xmm7, %%xmm0 \n\t"\ + "punpcklbw %%xmm7, %%xmm4 \n\t"\ + "pmullw %%xmm0, %%"out_reg1" \n\t"\ + "pmullw %%xmm4, %%"out_reg2" \n\t" + +#define snow_inner_add_yblock_sse2_start_16(out_reg1, out_reg2, ptr_offset, s_offset)\ + "mov "PTR_SIZE"*"ptr_offset"(%%"REG_a"), %%"REG_d"; \n\t"\ + "movq (%%"REG_d"), %%"out_reg1" \n\t"\ + "movq 8(%%"REG_d"), %%"out_reg2" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg1" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg2" \n\t"\ + "movq "s_offset"(%%"REG_S"), %%xmm0 \n\t"\ + "movq "s_offset"+8(%%"REG_S"), %%xmm4 \n\t"\ + "punpcklbw %%xmm7, %%xmm0 \n\t"\ + "punpcklbw %%xmm7, %%xmm4 \n\t"\ + "pmullw %%xmm0, %%"out_reg1" \n\t"\ + "pmullw %%xmm4, %%"out_reg2" \n\t" + +#define snow_inner_add_yblock_sse2_accum_8(ptr_offset, s_offset) \ + snow_inner_add_yblock_sse2_start_8("xmm2", "xmm6", ptr_offset, s_offset)\ + "paddusw %%xmm2, %%xmm1 \n\t"\ + "paddusw %%xmm6, %%xmm5 \n\t" + +#define snow_inner_add_yblock_sse2_accum_16(ptr_offset, s_offset) \ + snow_inner_add_yblock_sse2_start_16("xmm2", "xmm6", ptr_offset, s_offset)\ + "paddusw %%xmm2, %%xmm1 \n\t"\ + "paddusw %%xmm6, %%xmm5 \n\t" + +#define snow_inner_add_yblock_sse2_end_common1\ + "add $32, %%"REG_S" \n\t"\ + "add %%"REG_c", %0 \n\t"\ + "add %%"REG_c", "PTR_SIZE"*3(%%"REG_a");\n\t"\ + "add %%"REG_c", "PTR_SIZE"*2(%%"REG_a");\n\t"\ + "add %%"REG_c", "PTR_SIZE"*1(%%"REG_a");\n\t"\ + "add %%"REG_c", (%%"REG_a") \n\t" + +#define snow_inner_add_yblock_sse2_end_common2\ + "jnz 1b \n\t"\ + :"+m"(dst8),"+m"(dst_array)\ + :\ + "rm"((long)(src_x<<2)),"m"(obmc),"a"(block),"m"((long)b_h),"m"((long)src_stride):\ + "%"REG_b"","%"REG_c"","%"REG_S"","%"REG_D"","%"REG_d""); + +#define snow_inner_add_yblock_sse2_end_8\ + "sal $1, %%"REG_c" \n\t"\ + "add $"PTR_SIZE"*2, %1 \n\t"\ + snow_inner_add_yblock_sse2_end_common1\ + "sar $1, %%"REG_c" \n\t"\ + "sub $2, %%"REG_b" \n\t"\ + snow_inner_add_yblock_sse2_end_common2 + +#define snow_inner_add_yblock_sse2_end_16\ + "add $"PTR_SIZE"*1, %1 \n\t"\ + snow_inner_add_yblock_sse2_end_common1\ + "dec %%"REG_b" \n\t"\ + snow_inner_add_yblock_sse2_end_common2 + +static void inner_add_yblock_bw_8_obmc_16_bh_even_sse2(uint8_t *obmc, const long obmc_stride, uint8_t * * block, int b_w, long b_h, + int src_x, int src_y, long src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_sse2_header +snow_inner_add_yblock_sse2_start_8("xmm1", "xmm5", "3", "0") +snow_inner_add_yblock_sse2_accum_8("2", "8") +snow_inner_add_yblock_sse2_accum_8("1", "128") +snow_inner_add_yblock_sse2_accum_8("0", "136") + + "mov %0, %%"REG_d" \n\t" + "movdqa (%%"REG_D"), %%xmm0 \n\t" + "movdqa %%xmm1, %%xmm2 \n\t" + + "punpckhwd %%xmm7, %%xmm1 \n\t" + "punpcklwd %%xmm7, %%xmm2 \n\t" + "paddd %%xmm2, %%xmm0 \n\t" + "movdqa 16(%%"REG_D"), %%xmm2 \n\t" + "paddd %%xmm1, %%xmm2 \n\t" + "paddd %%xmm3, %%xmm0 \n\t" + "paddd %%xmm3, %%xmm2 \n\t" + + "mov %1, %%"REG_D" \n\t" + "mov "PTR_SIZE"(%%"REG_D"), %%"REG_D";\n\t" + "add %2, %%"REG_D" \n\t" + + "movdqa (%%"REG_D"), %%xmm4 \n\t" + "movdqa %%xmm5, %%xmm6 \n\t" + "punpckhwd %%xmm7, %%xmm5 \n\t" + "punpcklwd %%xmm7, %%xmm6 \n\t" + "paddd %%xmm6, %%xmm4 \n\t" + "movdqa 16(%%"REG_D"), %%xmm6 \n\t" + "paddd %%xmm5, %%xmm6 \n\t" + "paddd %%xmm3, %%xmm4 \n\t" + "paddd %%xmm3, %%xmm6 \n\t" + + "psrad $8, %%xmm0 \n\t" /* FRAC_BITS. */ + "psrad $8, %%xmm2 \n\t" /* FRAC_BITS. */ + "packssdw %%xmm2, %%xmm0 \n\t" + "packuswb %%xmm7, %%xmm0 \n\t" + "movq %%xmm0, (%%"REG_d") \n\t" + + "psrad $8, %%xmm4 \n\t" /* FRAC_BITS. */ + "psrad $8, %%xmm6 \n\t" /* FRAC_BITS. */ + "packssdw %%xmm6, %%xmm4 \n\t" + "packuswb %%xmm7, %%xmm4 \n\t" + "movq %%xmm4, (%%"REG_d",%%"REG_c");\n\t" +snow_inner_add_yblock_sse2_end_8 +} + +static void inner_add_yblock_bw_16_obmc_32_sse2(uint8_t *obmc, const long obmc_stride, uint8_t * * block, int b_w, long b_h, + int src_x, int src_y, long src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_sse2_header +snow_inner_add_yblock_sse2_start_16("xmm1", "xmm5", "3", "0") +snow_inner_add_yblock_sse2_accum_16("2", "16") +snow_inner_add_yblock_sse2_accum_16("1", "512") +snow_inner_add_yblock_sse2_accum_16("0", "528") + + "mov %0, %%"REG_d" \n\t" + "movdqa %%xmm1, %%xmm0 \n\t" + "movdqa %%xmm5, %%xmm4 \n\t" + "punpcklwd %%xmm7, %%xmm0 \n\t" + "paddd (%%"REG_D"), %%xmm0 \n\t" + "punpckhwd %%xmm7, %%xmm1 \n\t" + "paddd 16(%%"REG_D"), %%xmm1 \n\t" + "punpcklwd %%xmm7, %%xmm4 \n\t" + "paddd 32(%%"REG_D"), %%xmm4 \n\t" + "punpckhwd %%xmm7, %%xmm5 \n\t" + "paddd 48(%%"REG_D"), %%xmm5 \n\t" + "paddd %%xmm3, %%xmm0 \n\t" + "paddd %%xmm3, %%xmm1 \n\t" + "paddd %%xmm3, %%xmm4 \n\t" + "paddd %%xmm3, %%xmm5 \n\t" + "psrad $8, %%xmm0 \n\t" /* FRAC_BITS. */ + "psrad $8, %%xmm1 \n\t" /* FRAC_BITS. */ + "psrad $8, %%xmm4 \n\t" /* FRAC_BITS. */ + "psrad $8, %%xmm5 \n\t" /* FRAC_BITS. */ + + "packssdw %%xmm1, %%xmm0 \n\t" + "packssdw %%xmm5, %%xmm4 \n\t" + "packuswb %%xmm4, %%xmm0 \n\t" + + "movdqu %%xmm0, (%%"REG_d") \n\t" + +snow_inner_add_yblock_sse2_end_16 +} + +#define snow_inner_add_yblock_mmx_header \ + DWTELEM * * dst_array = sb->line + src_y;\ + asm volatile(\ + "mov %6, %%"REG_c" \n\t"\ + "mov %5, %%"REG_b" \n\t"\ + "mov %3, %%"REG_S" \n\t"\ + "pxor %%mm7, %%mm7 \n\t" /* 0 */\ + "pcmpeqd %%mm3, %%mm3 \n\t"\ + "pslld $31, %%mm3 \n\t"\ + "psrld $24, %%mm3 \n\t" /* FRAC_BITS >> 1 */\ + "1: \n\t"\ + "mov %1, %%"REG_D" \n\t"\ + "mov (%%"REG_D"), %%"REG_D" \n\t"\ + "add %2, %%"REG_D" \n\t" + +#define snow_inner_add_yblock_mmx_start(out_reg1, out_reg2, ptr_offset, s_offset, d_offset)\ + "mov "PTR_SIZE"*"ptr_offset"(%%"REG_a"), %%"REG_d"; \n\t"\ + "movd "d_offset"(%%"REG_d"), %%"out_reg1" \n\t"\ + "movd "d_offset"+4(%%"REG_d"), %%"out_reg2" \n\t"\ + "punpcklbw %%mm7, %%"out_reg1" \n\t"\ + "punpcklbw %%mm7, %%"out_reg2" \n\t"\ + "movd "s_offset"(%%"REG_S"), %%mm0 \n\t"\ + "movd "s_offset"+4(%%"REG_S"), %%mm4 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + "pmullw %%mm0, %%"out_reg1" \n\t"\ + "pmullw %%mm4, %%"out_reg2" \n\t" + +#define snow_inner_add_yblock_mmx_accum(ptr_offset, s_offset, d_offset) \ + snow_inner_add_yblock_mmx_start("mm2", "mm6", ptr_offset, s_offset, d_offset)\ + "paddusw %%mm2, %%mm1 \n\t"\ + "paddusw %%mm6, %%mm5 \n\t" + +#define snow_inner_add_yblock_mmx_mix(read_offset, write_offset)\ + "mov %0, %%"REG_d" \n\t"\ + "movq %%mm1, %%mm0 \n\t"\ + "movq %%mm5, %%mm4 \n\t"\ + "punpcklwd %%mm7, %%mm0 \n\t"\ + "paddd "read_offset"(%%"REG_D"), %%mm0 \n\t"\ + "punpckhwd %%mm7, %%mm1 \n\t"\ + "paddd "read_offset"+8(%%"REG_D"), %%mm1 \n\t"\ + "punpcklwd %%mm7, %%mm4 \n\t"\ + "paddd "read_offset"+16(%%"REG_D"), %%mm4 \n\t"\ + "punpckhwd %%mm7, %%mm5 \n\t"\ + "paddd "read_offset"+24(%%"REG_D"), %%mm5 \n\t"\ + "paddd %%mm3, %%mm0 \n\t"\ + "paddd %%mm3, %%mm1 \n\t"\ + "paddd %%mm3, %%mm4 \n\t"\ + "paddd %%mm3, %%mm5 \n\t"\ + "psrad $8, %%mm0 \n\t"\ + "psrad $8, %%mm1 \n\t"\ + "psrad $8, %%mm4 \n\t"\ + "psrad $8, %%mm5 \n\t"\ +\ + "packssdw %%mm1, %%mm0 \n\t"\ + "packssdw %%mm5, %%mm4 \n\t"\ + "packuswb %%mm4, %%mm0 \n\t"\ + "movq %%mm0, "write_offset"(%%"REG_d") \n\t" + +#define snow_inner_add_yblock_mmx_end(s_step)\ + "add $"s_step", %%"REG_S" \n\t"\ + "add %%"REG_c", "PTR_SIZE"*3(%%"REG_a");\n\t"\ + "add %%"REG_c", "PTR_SIZE"*2(%%"REG_a");\n\t"\ + "add %%"REG_c", "PTR_SIZE"*1(%%"REG_a");\n\t"\ + "add %%"REG_c", (%%"REG_a") \n\t"\ + "add $"PTR_SIZE"*1, %1 \n\t"\ + "add %%"REG_c", %0 \n\t"\ + "dec %%"REG_b" \n\t"\ + "jnz 1b \n\t"\ + :"+m"(dst8),"+m"(dst_array)\ + :\ + "rm"((long)(src_x<<2)),"m"(obmc),"a"(block),"m"((long)b_h),"m"((long)src_stride):\ + "%"REG_b"","%"REG_c"","%"REG_S"","%"REG_D"","%"REG_d""); + +static void inner_add_yblock_bw_8_obmc_16_mmx(uint8_t *obmc, const long obmc_stride, uint8_t * * block, int b_w, long b_h, + int src_x, int src_y, long src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_mmx_header +snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0") +snow_inner_add_yblock_mmx_accum("2", "8", "0") +snow_inner_add_yblock_mmx_accum("1", "128", "0") +snow_inner_add_yblock_mmx_accum("0", "136", "0") +snow_inner_add_yblock_mmx_mix("0", "0") +snow_inner_add_yblock_mmx_end("16") +} + +static void inner_add_yblock_bw_16_obmc_32_mmx(uint8_t *obmc, const long obmc_stride, uint8_t * * block, int b_w, long b_h, + int src_x, int src_y, long src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_mmx_header +snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0") +snow_inner_add_yblock_mmx_accum("2", "16", "0") +snow_inner_add_yblock_mmx_accum("1", "512", "0") +snow_inner_add_yblock_mmx_accum("0", "528", "0") +snow_inner_add_yblock_mmx_mix("0", "0") + +snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "8", "8") +snow_inner_add_yblock_mmx_accum("2", "24", "8") +snow_inner_add_yblock_mmx_accum("1", "520", "8") +snow_inner_add_yblock_mmx_accum("0", "536", "8") +snow_inner_add_yblock_mmx_mix("32", "8") +snow_inner_add_yblock_mmx_end("32") +} + +void ff_snow_inner_add_yblock_sse2(uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, + int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){ + + if (b_w == 16) + inner_add_yblock_bw_16_obmc_32_sse2(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else if (b_w == 8 && obmc_stride == 16) { + if (!(b_h & 1)) + inner_add_yblock_bw_8_obmc_16_bh_even_sse2(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else + inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + } else + ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); +} + +void ff_snow_inner_add_yblock_mmx(uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, + int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){ + if (b_w == 16) + inner_add_yblock_bw_16_obmc_32_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else if (b_w == 8 && obmc_stride == 16) + inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else + ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); +} diff --git a/mpeg4/src/libavcodec/i386/vp3dsp_mmx.c b/mpeg4/src/libavcodec/i386/vp3dsp_mmx.c new file mode 100644 index 00000000..0684531a --- /dev/null +++ b/mpeg4/src/libavcodec/i386/vp3dsp_mmx.c @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2004 the ffmpeg project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file vp3dsp_mmx.c + * MMX-optimized functions cribbed from the original VP3 source code. + */ + +#include "../dsputil.h" +#include "mmx.h" + +#define IdctAdjustBeforeShift 8 + +/* (12 * 4) 2-byte memory locations ( = 96 bytes total) + * idct_constants[0..15] = Mask table (M(I)) + * idct_constants[16..43] = Cosine table (C(I)) + * idct_constants[44..47] = 8 + */ +static uint16_t idct_constants[(4 + 7 + 1) * 4]; +static const uint16_t idct_cosine_table[7] = { + 64277, 60547, 54491, 46341, 36410, 25080, 12785 +}; + +#define r0 mm0 +#define r1 mm1 +#define r2 mm2 +#define r3 mm3 +#define r4 mm4 +#define r5 mm5 +#define r6 mm6 +#define r7 mm7 + +/* from original comments: The Macro does IDct on 4 1-D Dcts */ +#define BeginIDCT() { \ + movq_m2r(*I(3), r2); \ + movq_m2r(*C(3), r6); \ + movq_r2r(r2, r4); \ + movq_m2r(*J(5), r7); \ + pmulhw_r2r(r6, r4); /* r4 = c3*i3 - i3 */ \ + movq_m2r(*C(5), r1); \ + pmulhw_r2r(r7, r6); /* r6 = c3*i5 - i5 */ \ + movq_r2r(r1, r5); \ + pmulhw_r2r(r2, r1); /* r1 = c5*i3 - i3 */ \ + movq_m2r(*I(1), r3); \ + pmulhw_r2r(r7, r5); /* r5 = c5*i5 - i5 */ \ + movq_m2r(*C(1), r0); /* (all registers are in use) */ \ + paddw_r2r(r2, r4); /* r4 = c3*i3 */ \ + paddw_r2r(r7, r6); /* r6 = c3*i5 */ \ + paddw_r2r(r1, r2); /* r2 = c5*i3 */ \ + movq_m2r(*J(7), r1); \ + paddw_r2r(r5, r7); /* r7 = c5*i5 */ \ + movq_r2r(r0, r5); /* r5 = c1 */ \ + pmulhw_r2r(r3, r0); /* r0 = c1*i1 - i1 */ \ + paddsw_r2r(r7, r4); /* r4 = C = c3*i3 + c5*i5 */ \ + pmulhw_r2r(r1, r5); /* r5 = c1*i7 - i7 */ \ + movq_m2r(*C(7), r7); \ + psubsw_r2r(r2, r6); /* r6 = D = c3*i5 - c5*i3 */ \ + paddw_r2r(r3, r0); /* r0 = c1*i1 */ \ + pmulhw_r2r(r7, r3); /* r3 = c7*i1 */ \ + movq_m2r(*I(2), r2); \ + pmulhw_r2r(r1, r7); /* r7 = c7*i7 */ \ + paddw_r2r(r1, r5); /* r5 = c1*i7 */ \ + movq_r2r(r2, r1); /* r1 = i2 */ \ + pmulhw_m2r(*C(2), r2); /* r2 = c2*i2 - i2 */ \ + psubsw_r2r(r5, r3); /* r3 = B = c7*i1 - c1*i7 */ \ + movq_m2r(*J(6), r5); \ + paddsw_r2r(r7, r0); /* r0 = A = c1*i1 + c7*i7 */ \ + movq_r2r(r5, r7); /* r7 = i6 */ \ + psubsw_r2r(r4, r0); /* r0 = A - C */ \ + pmulhw_m2r(*C(2), r5); /* r5 = c2*i6 - i6 */ \ + paddw_r2r(r1, r2); /* r2 = c2*i2 */ \ + pmulhw_m2r(*C(6), r1); /* r1 = c6*i2 */ \ + paddsw_r2r(r4, r4); /* r4 = C + C */ \ + paddsw_r2r(r0, r4); /* r4 = C. = A + C */ \ + psubsw_r2r(r6, r3); /* r3 = B - D */ \ + paddw_r2r(r7, r5); /* r5 = c2*i6 */ \ + paddsw_r2r(r6, r6); /* r6 = D + D */ \ + pmulhw_m2r(*C(6), r7); /* r7 = c6*i6 */ \ + paddsw_r2r(r3, r6); /* r6 = D. = B + D */ \ + movq_r2m(r4, *I(1)); /* save C. at I(1) */ \ + psubsw_r2r(r5, r1); /* r1 = H = c6*i2 - c2*i6 */ \ + movq_m2r(*C(4), r4); \ + movq_r2r(r3, r5); /* r5 = B - D */ \ + pmulhw_r2r(r4, r3); /* r3 = (c4 - 1) * (B - D) */ \ + paddsw_r2r(r2, r7); /* r7 = G = c6*i6 + c2*i2 */ \ + movq_r2m(r6, *I(2)); /* save D. at I(2) */ \ + movq_r2r(r0, r2); /* r2 = A - C */ \ + movq_m2r(*I(0), r6); \ + pmulhw_r2r(r4, r0); /* r0 = (c4 - 1) * (A - C) */ \ + paddw_r2r(r3, r5); /* r5 = B. = c4 * (B - D) */ \ + movq_m2r(*J(4), r3); \ + psubsw_r2r(r1, r5); /* r5 = B.. = B. - H */ \ + paddw_r2r(r0, r2); /* r0 = A. = c4 * (A - C) */ \ + psubsw_r2r(r3, r6); /* r6 = i0 - i4 */ \ + movq_r2r(r6, r0); \ + pmulhw_r2r(r4, r6); /* r6 = (c4 - 1) * (i0 - i4) */ \ + paddsw_r2r(r3, r3); /* r3 = i4 + i4 */ \ + paddsw_r2r(r1, r1); /* r1 = H + H */ \ + paddsw_r2r(r0, r3); /* r3 = i0 + i4 */ \ + paddsw_r2r(r5, r1); /* r1 = H. = B + H */ \ + pmulhw_r2r(r3, r4); /* r4 = (c4 - 1) * (i0 + i4) */ \ + paddsw_r2r(r0, r6); /* r6 = F = c4 * (i0 - i4) */ \ + psubsw_r2r(r2, r6); /* r6 = F. = F - A. */ \ + paddsw_r2r(r2, r2); /* r2 = A. + A. */ \ + movq_m2r(*I(1), r0); /* r0 = C. */ \ + paddsw_r2r(r6, r2); /* r2 = A.. = F + A. */ \ + paddw_r2r(r3, r4); /* r4 = E = c4 * (i0 + i4) */ \ + psubsw_r2r(r1, r2); /* r2 = R2 = A.. - H. */ \ +} + +/* RowIDCT gets ready to transpose */ +#define RowIDCT() { \ + \ + BeginIDCT(); \ + \ + movq_m2r(*I(2), r3); /* r3 = D. */ \ + psubsw_r2r(r7, r4); /* r4 = E. = E - G */ \ + paddsw_r2r(r1, r1); /* r1 = H. + H. */ \ + paddsw_r2r(r7, r7); /* r7 = G + G */ \ + paddsw_r2r(r2, r1); /* r1 = R1 = A.. + H. */ \ + paddsw_r2r(r4, r7); /* r7 = G. = E + G */ \ + psubsw_r2r(r3, r4); /* r4 = R4 = E. - D. */ \ + paddsw_r2r(r3, r3); \ + psubsw_r2r(r5, r6); /* r6 = R6 = F. - B.. */ \ + paddsw_r2r(r5, r5); \ + paddsw_r2r(r4, r3); /* r3 = R3 = E. + D. */ \ + paddsw_r2r(r6, r5); /* r5 = R5 = F. + B.. */ \ + psubsw_r2r(r0, r7); /* r7 = R7 = G. - C. */ \ + paddsw_r2r(r0, r0); \ + movq_r2m(r1, *I(1)); /* save R1 */ \ + paddsw_r2r(r7, r0); /* r0 = R0 = G. + C. */ \ +} + +/* Column IDCT normalizes and stores final results */ +#define ColumnIDCT() { \ + \ + BeginIDCT(); \ + \ + paddsw_m2r(*Eight, r2); /* adjust R2 (and R1) for shift */ \ + paddsw_r2r(r1, r1); /* r1 = H. + H. */ \ + paddsw_r2r(r2, r1); /* r1 = R1 = A.. + H. */ \ + psraw_i2r(4, r2); /* r2 = NR2 */ \ + psubsw_r2r(r7, r4); /* r4 = E. = E - G */ \ + psraw_i2r(4, r1); /* r1 = NR1 */ \ + movq_m2r(*I(2), r3); /* r3 = D. */ \ + paddsw_r2r(r7, r7); /* r7 = G + G */ \ + movq_r2m(r2, *I(2)); /* store NR2 at I2 */ \ + paddsw_r2r(r4, r7); /* r7 = G. = E + G */ \ + movq_r2m(r1, *I(1)); /* store NR1 at I1 */ \ + psubsw_r2r(r3, r4); /* r4 = R4 = E. - D. */ \ + paddsw_m2r(*Eight, r4); /* adjust R4 (and R3) for shift */ \ + paddsw_r2r(r3, r3); /* r3 = D. + D. */ \ + paddsw_r2r(r4, r3); /* r3 = R3 = E. + D. */ \ + psraw_i2r(4, r4); /* r4 = NR4 */ \ + psubsw_r2r(r5, r6); /* r6 = R6 = F. - B.. */ \ + psraw_i2r(4, r3); /* r3 = NR3 */ \ + paddsw_m2r(*Eight, r6); /* adjust R6 (and R5) for shift */ \ + paddsw_r2r(r5, r5); /* r5 = B.. + B.. */ \ + paddsw_r2r(r6, r5); /* r5 = R5 = F. + B.. */ \ + psraw_i2r(4, r6); /* r6 = NR6 */ \ + movq_r2m(r4, *J(4)); /* store NR4 at J4 */ \ + psraw_i2r(4, r5); /* r5 = NR5 */ \ + movq_r2m(r3, *I(3)); /* store NR3 at I3 */ \ + psubsw_r2r(r0, r7); /* r7 = R7 = G. - C. */ \ + paddsw_m2r(*Eight, r7); /* adjust R7 (and R0) for shift */ \ + paddsw_r2r(r0, r0); /* r0 = C. + C. */ \ + paddsw_r2r(r7, r0); /* r0 = R0 = G. + C. */ \ + psraw_i2r(4, r7); /* r7 = NR7 */ \ + movq_r2m(r6, *J(6)); /* store NR6 at J6 */ \ + psraw_i2r(4, r0); /* r0 = NR0 */ \ + movq_r2m(r5, *J(5)); /* store NR5 at J5 */ \ + movq_r2m(r7, *J(7)); /* store NR7 at J7 */ \ + movq_r2m(r0, *I(0)); /* store NR0 at I0 */ \ +} + +/* Following macro does two 4x4 transposes in place. + + At entry (we assume): + + r0 = a3 a2 a1 a0 + I(1) = b3 b2 b1 b0 + r2 = c3 c2 c1 c0 + r3 = d3 d2 d1 d0 + + r4 = e3 e2 e1 e0 + r5 = f3 f2 f1 f0 + r6 = g3 g2 g1 g0 + r7 = h3 h2 h1 h0 + + At exit, we have: + + I(0) = d0 c0 b0 a0 + I(1) = d1 c1 b1 a1 + I(2) = d2 c2 b2 a2 + I(3) = d3 c3 b3 a3 + + J(4) = h0 g0 f0 e0 + J(5) = h1 g1 f1 e1 + J(6) = h2 g2 f2 e2 + J(7) = h3 g3 f3 e3 + + I(0) I(1) I(2) I(3) is the transpose of r0 I(1) r2 r3. + J(4) J(5) J(6) J(7) is the transpose of r4 r5 r6 r7. + + Since r1 is free at entry, we calculate the Js first. */ + +#define Transpose() { \ + movq_r2r(r4, r1); /* r1 = e3 e2 e1 e0 */ \ + punpcklwd_r2r(r5, r4); /* r4 = f1 e1 f0 e0 */ \ + movq_r2m(r0, *I(0)); /* save a3 a2 a1 a0 */ \ + punpckhwd_r2r(r5, r1); /* r1 = f3 e3 f2 e2 */ \ + movq_r2r(r6, r0); /* r0 = g3 g2 g1 g0 */ \ + punpcklwd_r2r(r7, r6); /* r6 = h1 g1 h0 g0 */ \ + movq_r2r(r4, r5); /* r5 = f1 e1 f0 e0 */ \ + punpckldq_r2r(r6, r4); /* r4 = h0 g0 f0 e0 = R4 */ \ + punpckhdq_r2r(r6, r5); /* r5 = h1 g1 f1 e1 = R5 */ \ + movq_r2r(r1, r6); /* r6 = f3 e3 f2 e2 */ \ + movq_r2m(r4, *J(4)); \ + punpckhwd_r2r(r7, r0); /* r0 = h3 g3 h2 g2 */ \ + movq_r2m(r5, *J(5)); \ + punpckhdq_r2r(r0, r6); /* r6 = h3 g3 f3 e3 = R7 */ \ + movq_m2r(*I(0), r4); /* r4 = a3 a2 a1 a0 */ \ + punpckldq_r2r(r0, r1); /* r1 = h2 g2 f2 e2 = R6 */ \ + movq_m2r(*I(1), r5); /* r5 = b3 b2 b1 b0 */ \ + movq_r2r(r4, r0); /* r0 = a3 a2 a1 a0 */ \ + movq_r2m(r6, *J(7)); \ + punpcklwd_r2r(r5, r0); /* r0 = b1 a1 b0 a0 */ \ + movq_r2m(r1, *J(6)); \ + punpckhwd_r2r(r5, r4); /* r4 = b3 a3 b2 a2 */ \ + movq_r2r(r2, r5); /* r5 = c3 c2 c1 c0 */ \ + punpcklwd_r2r(r3, r2); /* r2 = d1 c1 d0 c0 */ \ + movq_r2r(r0, r1); /* r1 = b1 a1 b0 a0 */ \ + punpckldq_r2r(r2, r0); /* r0 = d0 c0 b0 a0 = R0 */ \ + punpckhdq_r2r(r2, r1); /* r1 = d1 c1 b1 a1 = R1 */ \ + movq_r2r(r4, r2); /* r2 = b3 a3 b2 a2 */ \ + movq_r2m(r0, *I(0)); \ + punpckhwd_r2r(r3, r5); /* r5 = d3 c3 d2 c2 */ \ + movq_r2m(r1, *I(1)); \ + punpckhdq_r2r(r5, r4); /* r4 = d3 c3 b3 a3 = R3 */ \ + punpckldq_r2r(r5, r2); /* r2 = d2 c2 b2 a2 = R2 */ \ + movq_r2m(r4, *I(3)); \ + movq_r2m(r2, *I(2)); \ +} + +void ff_vp3_dsp_init_mmx(void) +{ + int j = 16; + uint16_t *p; + + j = 1; + do { + p = idct_constants + ((j + 3) << 2); + p[0] = p[1] = p[2] = p[3] = idct_cosine_table[j - 1]; + } while (++j <= 7); + + idct_constants[44] = idct_constants[45] = + idct_constants[46] = idct_constants[47] = IdctAdjustBeforeShift; +} + +void ff_vp3_idct_mmx(int16_t *output_data) +{ + /* eax = quantized input + * ebx = dequantizer matrix + * ecx = IDCT constants + * M(I) = ecx + MaskOffset(0) + I * 8 + * C(I) = ecx + CosineOffset(32) + (I-1) * 8 + * edx = output + * r0..r7 = mm0..mm7 + */ + +#define C(x) (idct_constants + 16 + (x - 1) * 4) +#define Eight (idct_constants + 44) + + /* at this point, function has completed dequantization + dezigzag + + * partial transposition; now do the idct itself */ +#define I(K) (output_data + K * 8) +#define J(K) (output_data + ((K - 4) * 8) + 4) + + RowIDCT(); + Transpose(); + +#undef I +#undef J +#define I(K) (output_data + (K * 8) + 32) +#define J(K) (output_data + ((K - 4) * 8) + 36) + + RowIDCT(); + Transpose(); + +#undef I +#undef J +#define I(K) (output_data + K * 8) +#define J(K) (output_data + K * 8) + + ColumnIDCT(); + +#undef I +#undef J +#define I(K) (output_data + (K * 8) + 4) +#define J(K) (output_data + (K * 8) + 4) + + ColumnIDCT(); + +#undef I +#undef J + +} diff --git a/mpeg4/src/libavcodec/i386/vp3dsp_sse2.c b/mpeg4/src/libavcodec/i386/vp3dsp_sse2.c new file mode 100644 index 00000000..cf822f7d --- /dev/null +++ b/mpeg4/src/libavcodec/i386/vp3dsp_sse2.c @@ -0,0 +1,825 @@ +/* + * Copyright (C) 2004 the ffmpeg project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file vp3dsp_sse2.c + * SSE2-optimized functions cribbed from the original VP3 source code. + */ + +#include "../dsputil.h" +#include "mmx.h" + +static DECLARE_ALIGNED_16(const unsigned short, SSE2_dequant_const[]) = +{ + 0,65535,65535,0,0,0,0,0, // 0x0000 0000 0000 0000 0000 FFFF FFFF 0000 + 0,0,0,0,65535,65535,0,0, // 0x0000 0000 FFFF FFFF 0000 0000 0000 0000 + 65535,65535,65535,0,0,0,0,0,// 0x0000 0000 0000 0000 0000 FFFF FFFF FFFF + 0,0,0,65535,0,0,0,0, // 0x0000 0000 0000 0000 FFFF 0000 0000 0000 + 0,0,0,65535,65535,0,0,0, // 0x0000 0000 0000 FFFF FFFF 0000 0000 0000 + 65535,0,0,0,0,65535,0,0, // 0x0000 0000 FFFF 0000 0000 0000 0000 FFFF + 0,0,65535,65535, 0,0,0,0 // 0x0000 0000 0000 0000 FFFF FFFF 0000 0000 +}; + +static DECLARE_ALIGNED_16(const unsigned int, eight_data[]) = +{ + 0x00080008, + 0x00080008, + 0x00080008, + 0x00080008 +}; + +static DECLARE_ALIGNED_16(const unsigned short, SSE2_idct_data[7 * 8]) = +{ + 64277,64277,64277,64277,64277,64277,64277,64277, + 60547,60547,60547,60547,60547,60547,60547,60547, + 54491,54491,54491,54491,54491,54491,54491,54491, + 46341,46341,46341,46341,46341,46341,46341,46341, + 36410,36410,36410,36410,36410,36410,36410,36410, + 25080,25080,25080,25080,25080,25080,25080,25080, + 12785,12785,12785,12785,12785,12785,12785,12785 +}; + + +#define SSE2_Column_IDCT() { \ + \ + movdqu_m2r(*I(3), xmm2); /* xmm2 = i3 */ \ + movdqu_m2r(*C(3), xmm6); /* xmm6 = c3 */ \ + \ + movdqu_r2r(xmm2, xmm4); /* xmm4 = i3 */ \ + movdqu_m2r(*I(5), xmm7); /* xmm7 = i5 */ \ + \ + pmulhw_r2r(xmm6, xmm4); /* xmm4 = c3 * i3 - i3 */ \ + movdqu_m2r(*C(5), xmm1); /* xmm1 = c5 */ \ + \ + pmulhw_r2r(xmm7, xmm6); /* xmm6 = c3 * i5 - i5 */ \ + movdqu_r2r(xmm1, xmm5); /* xmm5 = c5 */ \ + \ + pmulhw_r2r(xmm2, xmm1); /* xmm1 = c5 * i3 - i3 */ \ + movdqu_m2r(*I(1), xmm3); /* xmm3 = i1 */ \ + \ + pmulhw_r2r(xmm7, xmm5); /* xmm5 = c5 * i5 - i5 */ \ + movdqu_m2r(*C(1), xmm0); /* xmm0 = c1 */ \ + \ + /* all registers are in use */ \ + \ + paddw_r2r(xmm2, xmm4); /* xmm4 = c3 * i3 */ \ + paddw_r2r(xmm7, xmm6); /* xmm6 = c3 * i5 */ \ + \ + paddw_r2r(xmm1, xmm2); /* xmm2 = c5 * i3 */ \ + movdqu_m2r(*I(7), xmm1); /* xmm1 = i7 */ \ + \ + paddw_r2r(xmm5, xmm7); /* xmm7 = c5 * i5 */ \ + movdqu_r2r(xmm0, xmm5); /* xmm5 = c1 */ \ + \ + pmulhw_r2r(xmm3, xmm0); /* xmm0 = c1 * i1 - i1 */ \ + paddsw_r2r(xmm7, xmm4); /* xmm4 = c3 * i3 + c5 * i5 = C */ \ + \ + pmulhw_r2r(xmm1, xmm5); /* xmm5 = c1 * i7 - i7 */ \ + movdqu_m2r(*C(7), xmm7); /* xmm7 = c7 */ \ + \ + psubsw_r2r(xmm2, xmm6); /* xmm6 = c3 * i5 - c5 * i3 = D */ \ + paddw_r2r(xmm3, xmm0); /* xmm0 = c1 * i1 */ \ + \ + pmulhw_r2r(xmm7, xmm3); /* xmm3 = c7 * i1 */ \ + movdqu_m2r(*I(2), xmm2); /* xmm2 = i2 */ \ + \ + pmulhw_r2r(xmm1, xmm7); /* xmm7 = c7 * i7 */ \ + paddw_r2r(xmm1, xmm5); /* xmm5 = c1 * i7 */ \ + \ + movdqu_r2r(xmm2, xmm1); /* xmm1 = i2 */ \ + pmulhw_m2r(*C(2), xmm2); /* xmm2 = i2 * c2 -i2 */ \ + \ + psubsw_r2r(xmm5, xmm3); /* xmm3 = c7 * i1 - c1 * i7 = B */ \ + movdqu_m2r(*I(6), xmm5); /* xmm5 = i6 */ \ + \ + paddsw_r2r(xmm7, xmm0); /* xmm0 = c1 * i1 + c7 * i7 = A */ \ + movdqu_r2r(xmm5, xmm7); /* xmm7 = i6 */ \ + \ + psubsw_r2r(xmm4, xmm0); /* xmm0 = A - C */ \ + pmulhw_m2r(*C(2), xmm5); /* xmm5 = c2 * i6 - i6 */ \ + \ + paddw_r2r(xmm1, xmm2); /* xmm2 = i2 * c2 */ \ + pmulhw_m2r(*C(6), xmm1); /* xmm1 = c6 * i2 */ \ + \ + paddsw_r2r(xmm4, xmm4); /* xmm4 = C + C */ \ + paddsw_r2r(xmm0, xmm4); /* xmm4 = A + C = C. */ \ + \ + psubsw_r2r(xmm6, xmm3); /* xmm3 = B - D */ \ + paddw_r2r(xmm7, xmm5); /* xmm5 = c2 * i6 */ \ + \ + paddsw_r2r(xmm6, xmm6); /* xmm6 = D + D */ \ + pmulhw_m2r(*C(6), xmm7); /* xmm7 = c6 * i6 */ \ + \ + paddsw_r2r(xmm3, xmm6); /* xmm6 = B + D = D. */ \ + movdqu_r2m(xmm4, *I(1)); /* Save C. at I(1) */ \ + \ + psubsw_r2r(xmm5, xmm1); /* xmm1 = c6 * i2 - c2 * i6 = H */ \ + movdqu_m2r(*C(4), xmm4); /* xmm4 = c4 */ \ + \ + movdqu_r2r(xmm3, xmm5); /* xmm5 = B - D */ \ + pmulhw_r2r(xmm4, xmm3); /* xmm3 = ( c4 -1 ) * ( B - D ) */ \ + \ + paddsw_r2r(xmm2, xmm7); /* xmm7 = c2 * i2 + c6 * i6 = G */ \ + movdqu_r2m(xmm6, *I(2)); /* Save D. at I(2) */ \ + \ + movdqu_r2r(xmm0, xmm2); /* xmm2 = A - C */ \ + movdqu_m2r(*I(0), xmm6); /* xmm6 = i0 */ \ + \ + pmulhw_r2r(xmm4, xmm0); /* xmm0 = ( c4 - 1 ) * ( A - C ) = A. */ \ + paddw_r2r(xmm3, xmm5); /* xmm5 = c4 * ( B - D ) = B. */ \ + \ + movdqu_m2r(*I(4), xmm3); /* xmm3 = i4 */ \ + psubsw_r2r(xmm1, xmm5); /* xmm5 = B. - H = B.. */ \ + \ + paddw_r2r(xmm0, xmm2); /* xmm2 = c4 * ( A - C) = A. */ \ + psubsw_r2r(xmm3, xmm6); /* xmm6 = i0 - i4 */ \ + \ + movdqu_r2r(xmm6, xmm0); /* xmm0 = i0 - i4 */ \ + pmulhw_r2r(xmm4, xmm6); /* xmm6 = (c4 - 1) * (i0 - i4) = F */ \ + \ + paddsw_r2r(xmm3, xmm3); /* xmm3 = i4 + i4 */ \ + paddsw_r2r(xmm1, xmm1); /* xmm1 = H + H */ \ + \ + paddsw_r2r(xmm0, xmm3); /* xmm3 = i0 + i4 */ \ + paddsw_r2r(xmm5, xmm1); /* xmm1 = B. + H = H. */ \ + \ + pmulhw_r2r(xmm3, xmm4); /* xmm4 = ( c4 - 1 ) * ( i0 + i4 ) */ \ + paddw_r2r(xmm0, xmm6); /* xmm6 = c4 * ( i0 - i4 ) */ \ + \ + psubsw_r2r(xmm2, xmm6); /* xmm6 = F - A. = F. */ \ + paddsw_r2r(xmm2, xmm2); /* xmm2 = A. + A. */ \ + \ + movdqu_m2r(*I(1), xmm0); /* Load C. from I(1) */ \ + paddsw_r2r(xmm6, xmm2); /* xmm2 = F + A. = A.. */ \ + \ + paddw_r2r(xmm3, xmm4); /* xmm4 = c4 * ( i0 + i4 ) = 3 */ \ + psubsw_r2r(xmm1, xmm2); /* xmm2 = A.. - H. = R2 */ \ + \ + paddsw_m2r(*Eight, xmm2); /* Adjust R2 and R1 before shifting */ \ + paddsw_r2r(xmm1, xmm1); /* xmm1 = H. + H. */ \ + \ + paddsw_r2r(xmm2, xmm1); /* xmm1 = A.. + H. = R1 */ \ + psraw_i2r(4, xmm2); /* xmm2 = op2 */ \ + \ + psubsw_r2r(xmm7, xmm4); /* xmm4 = E - G = E. */ \ + psraw_i2r(4, xmm1); /* xmm1 = op1 */ \ + \ + movdqu_m2r(*I(2), xmm3); /* Load D. from I(2) */ \ + paddsw_r2r(xmm7, xmm7); /* xmm7 = G + G */ \ + \ + movdqu_r2m(xmm2, *O(2)); /* Write out op2 */ \ + paddsw_r2r(xmm4, xmm7); /* xmm7 = E + G = G. */ \ + \ + movdqu_r2m(xmm1, *O(1)); /* Write out op1 */ \ + psubsw_r2r(xmm3, xmm4); /* xmm4 = E. - D. = R4 */ \ + \ + paddsw_m2r(*Eight, xmm4); /* Adjust R4 and R3 before shifting */ \ + paddsw_r2r(xmm3, xmm3); /* xmm3 = D. + D. */ \ + \ + paddsw_r2r(xmm4, xmm3); /* xmm3 = E. + D. = R3 */ \ + psraw_i2r(4, xmm4); /* xmm4 = op4 */ \ + \ + psubsw_r2r(xmm5, xmm6); /* xmm6 = F. - B..= R6 */ \ + psraw_i2r(4, xmm3); /* xmm3 = op3 */ \ + \ + paddsw_m2r(*Eight, xmm6); /* Adjust R6 and R5 before shifting */ \ + paddsw_r2r(xmm5, xmm5); /* xmm5 = B.. + B.. */ \ + \ + paddsw_r2r(xmm6, xmm5); /* xmm5 = F. + B.. = R5 */ \ + psraw_i2r(4, xmm6); /* xmm6 = op6 */ \ + \ + movdqu_r2m(xmm4, *O(4)); /* Write out op4 */ \ + psraw_i2r(4, xmm5); /* xmm5 = op5 */ \ + \ + movdqu_r2m(xmm3, *O(3)); /* Write out op3 */ \ + psubsw_r2r(xmm0, xmm7); /* xmm7 = G. - C. = R7 */ \ + \ + paddsw_m2r(*Eight, xmm7); /* Adjust R7 and R0 before shifting */ \ + paddsw_r2r(xmm0, xmm0); /* xmm0 = C. + C. */ \ + \ + paddsw_r2r(xmm7, xmm0); /* xmm0 = G. + C. */ \ + psraw_i2r(4, xmm7); /* xmm7 = op7 */ \ + \ + movdqu_r2m(xmm6, *O(6)); /* Write out op6 */ \ + psraw_i2r(4, xmm0); /* xmm0 = op0 */ \ + \ + movdqu_r2m(xmm5, *O(5)); /* Write out op5 */ \ + movdqu_r2m(xmm7, *O(7)); /* Write out op7 */ \ + \ + movdqu_r2m(xmm0, *O(0)); /* Write out op0 */ \ + \ +} /* End of SSE2_Column_IDCT macro */ + + +#define SSE2_Row_IDCT() { \ + \ + movdqu_m2r(*I(3), xmm2); /* xmm2 = i3 */ \ + movdqu_m2r(*C(3), xmm6); /* xmm6 = c3 */ \ + \ + movdqu_r2r(xmm2, xmm4); /* xmm4 = i3 */ \ + movdqu_m2r(*I(5), xmm7); /* xmm7 = i5 */ \ + \ + pmulhw_r2r(xmm6, xmm4); /* xmm4 = c3 * i3 - i3 */ \ + movdqu_m2r(*C(5), xmm1); /* xmm1 = c5 */ \ + \ + pmulhw_r2r(xmm7, xmm6); /* xmm6 = c3 * i5 - i5 */ \ + movdqu_r2r(xmm1, xmm5); /* xmm5 = c5 */ \ + \ + pmulhw_r2r(xmm2, xmm1); /* xmm1 = c5 * i3 - i3 */ \ + movdqu_m2r(*I(1), xmm3); /* xmm3 = i1 */ \ + \ + pmulhw_r2r(xmm7, xmm5); /* xmm5 = c5 * i5 - i5 */ \ + movdqu_m2r(*C(1), xmm0); /* xmm0 = c1 */ \ + \ + /* all registers are in use */ \ + \ + paddw_r2r(xmm2, xmm4); /* xmm4 = c3 * i3 */ \ + paddw_r2r(xmm7, xmm6); /* xmm6 = c3 * i5 */ \ + \ + paddw_r2r(xmm1, xmm2); /* xmm2 = c5 * i3 */ \ + movdqu_m2r(*I(7), xmm1); /* xmm1 = i7 */ \ + \ + paddw_r2r(xmm5, xmm7); /* xmm7 = c5 * i5 */ \ + movdqu_r2r(xmm0, xmm5); /* xmm5 = c1 */ \ + \ + pmulhw_r2r(xmm3, xmm0); /* xmm0 = c1 * i1 - i1 */ \ + paddsw_r2r(xmm7, xmm4); /* xmm4 = c3 * i3 + c5 * i5 = C */ \ + \ + pmulhw_r2r(xmm1, xmm5); /* xmm5 = c1 * i7 - i7 */ \ + movdqu_m2r(*C(7), xmm7); /* xmm7 = c7 */ \ + \ + psubsw_r2r(xmm2, xmm6); /* xmm6 = c3 * i5 - c5 * i3 = D */ \ + paddw_r2r(xmm3, xmm0); /* xmm0 = c1 * i1 */ \ + \ + pmulhw_r2r(xmm7, xmm3); /* xmm3 = c7 * i1 */ \ + movdqu_m2r(*I(2), xmm2); /* xmm2 = i2 */ \ + \ + pmulhw_r2r(xmm1, xmm7); /* xmm7 = c7 * i7 */ \ + paddw_r2r(xmm1, xmm5); /* xmm5 = c1 * i7 */ \ + \ + movdqu_r2r(xmm2, xmm1); /* xmm1 = i2 */ \ + pmulhw_m2r(*C(2), xmm2); /* xmm2 = i2 * c2 -i2 */ \ + \ + psubsw_r2r(xmm5, xmm3); /* xmm3 = c7 * i1 - c1 * i7 = B */ \ + movdqu_m2r(*I(6), xmm5); /* xmm5 = i6 */ \ + \ + paddsw_r2r(xmm7, xmm0); /* xmm0 = c1 * i1 + c7 * i7 = A */ \ + movdqu_r2r(xmm5, xmm7); /* xmm7 = i6 */ \ + \ + psubsw_r2r(xmm4, xmm0); /* xmm0 = A - C */ \ + pmulhw_m2r(*C(2), xmm5); /* xmm5 = c2 * i6 - i6 */ \ + \ + paddw_r2r(xmm1, xmm2); /* xmm2 = i2 * c2 */ \ + pmulhw_m2r(*C(6), xmm1); /* xmm1 = c6 * i2 */ \ + \ + paddsw_r2r(xmm4, xmm4); /* xmm4 = C + C */ \ + paddsw_r2r(xmm0, xmm4); /* xmm4 = A + C = C. */ \ + \ + psubsw_r2r(xmm6, xmm3); /* xmm3 = B - D */ \ + paddw_r2r(xmm7, xmm5); /* xmm5 = c2 * i6 */ \ + \ + paddsw_r2r(xmm6, xmm6); /* xmm6 = D + D */ \ + pmulhw_m2r(*C(6), xmm7); /* xmm7 = c6 * i6 */ \ + \ + paddsw_r2r(xmm3, xmm6); /* xmm6 = B + D = D. */ \ + movdqu_r2m(xmm4, *I(1)); /* Save C. at I(1) */ \ + \ + psubsw_r2r(xmm5, xmm1); /* xmm1 = c6 * i2 - c2 * i6 = H */ \ + movdqu_m2r(*C(4), xmm4); /* xmm4 = c4 */ \ + \ + movdqu_r2r(xmm3, xmm5); /* xmm5 = B - D */ \ + pmulhw_r2r(xmm4, xmm3); /* xmm3 = ( c4 -1 ) * ( B - D ) */ \ + \ + paddsw_r2r(xmm2, xmm7); /* xmm7 = c2 * i2 + c6 * i6 = G */ \ + movdqu_r2m(xmm6, *I(2)); /* Save D. at I(2) */ \ + \ + movdqu_r2r(xmm0, xmm2); /* xmm2 = A - C */ \ + movdqu_m2r(*I(0), xmm6); /* xmm6 = i0 */ \ + \ + pmulhw_r2r(xmm4, xmm0); /* xmm0 = ( c4 - 1 ) * ( A - C ) = A. */ \ + paddw_r2r(xmm3, xmm5); /* xmm5 = c4 * ( B - D ) = B. */ \ + \ + movdqu_m2r(*I(4), xmm3); /* xmm3 = i4 */ \ + psubsw_r2r(xmm1, xmm5); /* xmm5 = B. - H = B.. */ \ + \ + paddw_r2r(xmm0, xmm2); /* xmm2 = c4 * ( A - C) = A. */ \ + psubsw_r2r(xmm3, xmm6); /* xmm6 = i0 - i4 */ \ + \ + movdqu_r2r(xmm6, xmm0); /* xmm0 = i0 - i4 */ \ + pmulhw_r2r(xmm4, xmm6); /* xmm6 = ( c4 - 1 ) * ( i0 - i4 ) = F */ \ + \ + paddsw_r2r(xmm3, xmm3); /* xmm3 = i4 + i4 */ \ + paddsw_r2r(xmm1, xmm1); /* xmm1 = H + H */ \ + \ + paddsw_r2r(xmm0, xmm3); /* xmm3 = i0 + i4 */ \ + paddsw_r2r(xmm5, xmm1); /* xmm1 = B. + H = H. */ \ + \ + pmulhw_r2r(xmm3, xmm4); /* xmm4 = ( c4 - 1 ) * ( i0 + i4 ) */ \ + paddw_r2r(xmm0, xmm6); /* xmm6 = c4 * ( i0 - i4 ) */ \ + \ + psubsw_r2r(xmm2, xmm6); /* xmm6 = F - A. = F. */ \ + paddsw_r2r(xmm2, xmm2); /* xmm2 = A. + A. */ \ + \ + movdqu_m2r(*I(1), xmm0); /* Load C. from I(1) */ \ + paddsw_r2r(xmm6, xmm2); /* xmm2 = F + A. = A.. */ \ + \ + paddw_r2r(xmm3, xmm4); /* xmm4 = c4 * ( i0 + i4 ) = 3 */ \ + psubsw_r2r(xmm1, xmm2); /* xmm2 = A.. - H. = R2 */ \ + \ + paddsw_r2r(xmm1, xmm1); /* xmm1 = H. + H. */ \ + paddsw_r2r(xmm2, xmm1); /* xmm1 = A.. + H. = R1 */ \ + \ + psubsw_r2r(xmm7, xmm4); /* xmm4 = E - G = E. */ \ + \ + movdqu_m2r(*I(2), xmm3); /* Load D. from I(2) */ \ + paddsw_r2r(xmm7, xmm7); /* xmm7 = G + G */ \ + \ + movdqu_r2m(xmm2, *I(2)); /* Write out op2 */ \ + paddsw_r2r(xmm4, xmm7); /* xmm7 = E + G = G. */ \ + \ + movdqu_r2m(xmm1, *I(1)); /* Write out op1 */ \ + psubsw_r2r(xmm3, xmm4); /* xmm4 = E. - D. = R4 */ \ + \ + paddsw_r2r(xmm3, xmm3); /* xmm3 = D. + D. */ \ + \ + paddsw_r2r(xmm4, xmm3); /* xmm3 = E. + D. = R3 */ \ + \ + psubsw_r2r(xmm5, xmm6); /* xmm6 = F. - B..= R6 */ \ + \ + paddsw_r2r(xmm5, xmm5); /* xmm5 = B.. + B.. */ \ + \ + paddsw_r2r(xmm6, xmm5); /* xmm5 = F. + B.. = R5 */ \ + \ + movdqu_r2m(xmm4, *I(4)); /* Write out op4 */ \ + \ + movdqu_r2m(xmm3, *I(3)); /* Write out op3 */ \ + psubsw_r2r(xmm0, xmm7); /* xmm7 = G. - C. = R7 */ \ + \ + paddsw_r2r(xmm0, xmm0); /* xmm0 = C. + C. */ \ + \ + paddsw_r2r(xmm7, xmm0); /* xmm0 = G. + C. */ \ + \ + movdqu_r2m(xmm6, *I(6)); /* Write out op6 */ \ + \ + movdqu_r2m(xmm5, *I(5)); /* Write out op5 */ \ + movdqu_r2m(xmm7, *I(7)); /* Write out op7 */ \ + \ + movdqu_r2m(xmm0, *I(0)); /* Write out op0 */ \ + \ +} /* End of SSE2_Row_IDCT macro */ + + +#define SSE2_Transpose() { \ + \ + movdqu_m2r(*I(4), xmm4); /* xmm4=e7e6e5e4e3e2e1e0 */ \ + movdqu_m2r(*I(5), xmm0); /* xmm4=f7f6f5f4f3f2f1f0 */ \ + \ + movdqu_r2r(xmm4, xmm5); /* make a copy */ \ + punpcklwd_r2r(xmm0, xmm4); /* xmm4=f3e3f2e2f1e1f0e0 */ \ + \ + punpckhwd_r2r(xmm0, xmm5); /* xmm5=f7e7f6e6f5e5f4e4 */ \ + movdqu_m2r(*I(6), xmm6); /* xmm6=g7g6g5g4g3g2g1g0 */ \ + \ + movdqu_m2r(*I(7), xmm0); /* xmm0=h7h6h5h4h3h2h1h0 */ \ + movdqu_r2r(xmm6, xmm7); /* make a copy */ \ + \ + punpcklwd_r2r(xmm0, xmm6); /* xmm6=h3g3h3g2h1g1h0g0 */ \ + punpckhwd_r2r(xmm0, xmm7); /* xmm7=h7g7h6g6h5g5h4g4 */ \ + \ + movdqu_r2r(xmm4, xmm3); /* make a copy */ \ + punpckldq_r2r(xmm6, xmm4); /* xmm4=h1g1f1e1h0g0f0e0 */ \ + \ + punpckhdq_r2r(xmm6, xmm3); /* xmm3=h3g3g3e3h2g2f2e2 */ \ + movdqu_r2m(xmm3, *I(6)); /* save h3g3g3e3h2g2f2e2 */ \ + /* Free xmm6 */ \ + movdqu_r2r(xmm5, xmm6); /* make a copy */ \ + punpckldq_r2r(xmm7, xmm5); /* xmm5=h5g5f5e5h4g4f4e4 */ \ + \ + punpckhdq_r2r(xmm7, xmm6); /* xmm6=h7g7f7e7h6g6f6e6 */ \ + movdqu_m2r(*I(0), xmm0); /* xmm0=a7a6a5a4a3a2a1a0 */ \ + /* Free xmm7 */ \ + movdqu_m2r(*I(1), xmm1); /* xmm1=b7b6b5b4b3b2b1b0 */ \ + movdqu_r2r(xmm0, xmm7); /* make a copy */ \ + \ + punpcklwd_r2r(xmm1, xmm0); /* xmm0=b3a3b2a2b1a1b0a0 */ \ + punpckhwd_r2r(xmm1, xmm7); /* xmm7=b7a7b6a6b5a5b4a4 */ \ + /* Free xmm1 */ \ + movdqu_m2r(*I(2), xmm2); /* xmm2=c7c6c5c4c3c2c1c0 */ \ + movdqu_m2r(*I(3), xmm3); /* xmm3=d7d6d5d4d3d2d1d0 */ \ + \ + movdqu_r2r(xmm2, xmm1); /* make a copy */ \ + punpcklwd_r2r(xmm3, xmm2); /* xmm2=d3c3d2c2d1c1d0c0 */ \ + \ + punpckhwd_r2r(xmm3, xmm1); /* xmm1=d7c7d6c6d5c5d4c4 */ \ + movdqu_r2r(xmm0, xmm3); /* make a copy */ \ + \ + punpckldq_r2r(xmm2, xmm0); /* xmm0=d1c1b1a1d0c0b0a0 */ \ + punpckhdq_r2r(xmm2, xmm3); /* xmm3=d3c3b3a3d2c2b2a2 */ \ + /* Free xmm2 */ \ + movdqu_r2r(xmm7, xmm2); /* make a copy */ \ + punpckldq_r2r(xmm1, xmm2); /* xmm2=d5c5b5a5d4c4b4a4 */ \ + \ + punpckhdq_r2r(xmm1, xmm7); /* xmm7=d7c7b7a7d6c6b6a6 */ \ + movdqu_r2r(xmm0, xmm1); /* make a copy */ \ + \ + punpcklqdq_r2r(xmm4, xmm0); /* xmm0=h0g0f0e0d0c0b0a0 */ \ + punpckhqdq_r2r(xmm4, xmm1); /* xmm1=h1g1g1e1d1c1b1a1 */ \ + \ + movdqu_r2m(xmm0, *I(0)); /* save I(0) */ \ + movdqu_r2m(xmm1, *I(1)); /* save I(1) */ \ + \ + movdqu_m2r(*I(6), xmm0); /* load h3g3g3e3h2g2f2e2 */ \ + movdqu_r2r(xmm3, xmm1); /* make a copy */ \ + \ + punpcklqdq_r2r(xmm0, xmm1); /* xmm1=h2g2f2e2d2c2b2a2 */ \ + punpckhqdq_r2r(xmm0, xmm3); /* xmm3=h3g3f3e3d3c3b3a3 */ \ + \ + movdqu_r2r(xmm2, xmm4); /* make a copy */ \ + punpcklqdq_r2r(xmm5, xmm4); /* xmm4=h4g4f4e4d4c4b4a4 */ \ + \ + punpckhqdq_r2r(xmm5, xmm2); /* xmm2=h5g5f5e5d5c5b5a5 */ \ + movdqu_r2m(xmm1, *I(2)); /* save I(2) */ \ + \ + movdqu_r2m(xmm3, *I(3)); /* save I(3) */ \ + movdqu_r2m(xmm4, *I(4)); /* save I(4) */ \ + \ + movdqu_r2m(xmm2, *I(5)); /* save I(5) */ \ + movdqu_r2r(xmm7, xmm5); /* make a copy */ \ + \ + punpcklqdq_r2r(xmm6, xmm5); /* xmm5=h6g6f6e6d6c6b6a6 */ \ + punpckhqdq_r2r(xmm6, xmm7); /* xmm7=h7g7f7e7d7c7b7a7 */ \ + \ + movdqu_r2m(xmm5, *I(6)); /* save I(6) */ \ + movdqu_r2m(xmm7, *I(7)); /* save I(7) */ \ + \ +} /* End of Transpose Macro */ + + +#define SSE2_Dequantize() { \ + movdqu_m2r(*(eax), xmm0); \ + \ + pmullw_m2r(*(ebx), xmm0); /* xmm0 = 07 06 05 04 03 02 01 00 */ \ + movdqu_m2r(*(eax + 16), xmm1); \ + \ + pmullw_m2r(*(ebx + 16), xmm1); /* xmm1 = 17 16 15 14 13 12 11 10 */ \ + pshuflw_r2r(xmm0, xmm3, 0x078); /* xmm3 = 07 06 05 04 01 03 02 00 */ \ + \ + movdqu_r2r(xmm1, xmm2); /* xmm2 = 17 16 15 14 13 12 11 10 */ \ + movdqu_m2r(*(ecx), xmm7); /* xmm7 = -- -- -- -- -- FF FF -- */ \ + \ + movdqu_m2r(*(eax + 32), xmm4); \ + movdqu_m2r(*(eax + 64), xmm5); \ + \ + pmullw_m2r(*(ebx + 32), xmm4); /* xmm4 = 27 26 25 24 23 22 21 20 */ \ + pmullw_m2r(*(ebx + 64), xmm5); /* xmm5 = 47 46 45 44 43 42 41 40 */ \ + \ + movdqu_m2r(*(ecx + 16), xmm6); /* xmm6 = -- -- FF FF -- -- -- -- */ \ + pand_r2r(xmm2, xmm7); /* xmm7 = -- -- -- -- -- 12 11 -- */ \ + \ + pand_r2r(xmm4, xmm6); /* xmm6 = -- -- 25 24 -- -- -- -- */ \ + pxor_r2r(xmm7, xmm2); /* xmm2 = 17 16 15 14 13 -- -- 10 */ \ + \ + pxor_r2r(xmm6, xmm4); /* xmm4 = 27 26 -- -- 23 22 21 20 */ \ + pslldq_i2r(4, xmm7); /* xmm7 = -- -- -- 12 11 -- -- -- */ \ + \ + pslldq_i2r(2, xmm6); /* xmm6 = -- 25 24 -- -- -- -- -- */ \ + por_r2r(xmm6, xmm7); /* xmm7 = -- 25 24 12 11 -- -- -- */ \ + \ + movdqu_m2r(*(ecx + 32), xmm0); /* xmm0 = -- -- -- -- -- FF FF FF */ \ + movdqu_m2r(*(ecx + 48), xmm6); /* xmm6 = -- -- -- -- FF -- -- -- */ \ + \ + pand_r2r(xmm3, xmm0); /* xmm0 = -- -- -- -- -- 03 02 00 */ \ + pand_r2r(xmm5, xmm6); /* xmm6 = -- -- -- -- 43 -- -- -- */ \ + \ + pxor_r2r(xmm0, xmm3); /* xmm3 = 07 06 05 04 01 -- -- -- */ \ + pxor_r2r(xmm6, xmm5); /* xmm5 = 47 46 45 44 -- 42 41 40 */ \ + \ + por_r2r(xmm7, xmm0); /* xmm0 = -- 25 24 12 11 03 02 00 */ \ + pslldq_i2r(8, xmm6); /* xmm6 = 43 -- -- -- -- -- -- -- */ \ + \ + por_r2r(xmm6, xmm0); /* xmm0 = 43 25 24 12 11 03 02 00 */ \ + /* 02345 in use */ \ + \ + movdqu_m2r(*(ecx + 64 ), xmm1); /* xmm1 = -- -- -- FF FF -- -- -- */ \ + pshuflw_r2r(xmm5, xmm5, 0x0B4); /* xmm5 = 47 46 45 44 42 -- 41 40 */ \ + \ + movdqu_r2r(xmm1, xmm7); /* xmm7 = -- -- -- FF FF -- -- -- */ \ + movdqu_r2r(xmm1, xmm6); /* xmm6 = -- -- -- FF FF -- -- -- */ \ + \ + movdqu_r2m(xmm0, *(eax)); /* write 43 25 24 12 11 03 02 00 */ \ + pshufhw_r2r(xmm4, xmm4, 0x0C2); /* xmm4 = 27 -- -- 26 23 22 21 20 */ \ + \ + pand_r2r(xmm4, xmm7); /* xmm7 = -- -- -- 26 23 -- -- -- */ \ + pand_r2r(xmm5, xmm1); /* xmm1 = -- -- -- 44 42 -- -- -- */ \ + \ + pxor_r2r(xmm7, xmm4); /* xmm4 = 27 -- -- -- -- 22 21 20 */ \ + pxor_r2r(xmm1, xmm5); /* xmm5 = 47 46 45 -- -- -- 41 40 */ \ + \ + pshuflw_r2r(xmm2, xmm2, 0x0C6); /* xmm2 = 17 16 15 14 13 10 -- -- */ \ + movdqu_r2r(xmm6, xmm0); /* xmm0 = -- -- -- FF FF -- -- -- */ \ + \ + pslldq_i2r(2, xmm7); /* xmm7 = -- -- 26 23 -- -- -- -- */ \ + pslldq_i2r(6, xmm1); /* xmm1 = 44 42 -- -- -- -- -- -- */ \ + \ + psrldq_i2r(2, xmm0); /* xmm0 = -- -- -- -- FF FF -- -- */ \ + pand_r2r(xmm3, xmm6); /* xmm6 = -- -- -- 04 01 -- -- -- */ \ + \ + pand_r2r(xmm2, xmm0); /* xmm0 = -- -- -- -- 13 10 -- -- */ \ + pxor_r2r(xmm6, xmm3); /* xmm3 = 07 06 05 -- -- -- -- -- */ \ + \ + pxor_r2r(xmm0, xmm2); /* xmm2 = 17 16 15 14 -- -- -- -- */ \ + psrldq_i2r(6, xmm6); /* xmm0 = -- -- -- -- -- -- 04 01 */ \ + \ + por_r2r(xmm7, xmm1); /* xmm1 = 44 42 26 23 -- -- -- -- */ \ + por_r2r(xmm6, xmm0); /* xmm1 = -- -- -- -- 13 10 04 01 */ \ + /* 12345 in use */ \ + por_r2r(xmm0, xmm1); /* xmm1 = 44 42 26 23 13 10 04 01 */ \ + pshuflw_r2r(xmm4, xmm4, 0x093); /* xmm4 = 27 -- -- -- 22 21 20 -- */ \ + \ + pshufhw_r2r(xmm4, xmm4, 0x093); /* xmm4 = -- -- -- 27 22 21 20 -- */ \ + movdqu_r2m(xmm1, *(eax + 16)); /* write 44 42 26 23 13 10 04 01 */ \ + \ + pshufhw_r2r(xmm3, xmm3, 0x0D2); /* xmm3 = 07 05 -- 06 -- -- -- -- */ \ + movdqu_m2r(*(ecx + 64), xmm0); /* xmm0 = -- -- -- FF FF -- -- -- */ \ + \ + pand_r2r(xmm3, xmm0); /* xmm0 = -- -- -- 06 -- -- -- -- */ \ + psrldq_i2r(12, xmm3); /* xmm3 = -- -- -- -- -- -- 07 05 */ \ + \ + psrldq_i2r(8, xmm0); /* xmm0 = -- -- -- -- -- -- -- 06 */ \ + \ + movdqu_m2r(*(ecx + 64), xmm6); /* xmm6 = -- -- -- FF FF -- -- -- */ \ + movdqu_m2r(*(ecx + 96), xmm7); /* xmm7 = -- -- -- -- FF FF -- -- */ \ + \ + pand_r2r(xmm4, xmm6); /* xmm6 = -- -- -- 27 22 -- -- -- */ \ + pxor_r2r(xmm6, xmm4); /* xmm4 = -- -- -- -- -- 21 20 -- */ \ + \ + por_r2r(xmm6, xmm3); /* xmm3 = -- -- -- 27 22 -- 07 05 */ \ + pand_r2r(xmm4, xmm7); /* xmm7 = -- -- -- -- -- 21 -- -- */ \ + \ + por_r2r(xmm7, xmm0); /* xmm0 = -- -- -- -- -- 21 -- 06 */ \ + pxor_r2r(xmm7, xmm4); /* xmm4 = -- -- -- -- -- -- 20 -- */ \ + \ + movdqu_m2r(*(ecx + 16 ), xmm6); /* xmm6 = -- -- FF FF -- -- -- -- */ \ + movdqu_m2r(*(ecx + 64 ), xmm1); /* xmm1 = -- -- -- FF FF -- -- -- */ \ + \ + pand_r2r(xmm2, xmm6); /* xmm6 = -- -- 15 14 -- -- -- -- */ \ + pand_r2r(xmm6, xmm1); /* xmm1 = -- -- -- 14 -- -- -- -- */ \ + \ + pxor_r2r(xmm6, xmm2); /* xmm2 = 17 16 -- -- -- -- -- -- */ \ + pxor_r2r(xmm1, xmm6); /* xmm6 = -- -- 15 -- -- -- -- -- */ \ + \ + psrldq_i2r(4, xmm1); /* xmm1 = -- -- -- -- -- 14 -- -- */ \ + \ + psrldq_i2r(8, xmm6); /* xmm6 = -- -- -- -- -- -- 15 -- */ \ + por_r2r(xmm1, xmm3); /* xmm3 = -- -- -- 27 22 14 07 05 */ \ + \ + por_r2r(xmm6, xmm0); /* xmm0 = -- -- -- -- -- 21 15 06 */ \ + pshufhw_r2r(xmm5, xmm5, 0x0E1); /* xmm5 = 47 46 -- 45 -- -- 41 40 */ \ + \ + movdqu_m2r(*(ecx + 64), xmm1); /* xmm1 = -- -- -- FF FF -- -- -- */ \ + pshuflw_r2r(xmm5, xmm5, 0x072); /* xmm5 = 47 46 -- 45 41 -- 40 -- */ \ + \ + movdqu_r2r(xmm1, xmm6); /* xmm6 = -- -- -- FF FF -- -- -- */ \ + pand_r2r(xmm5, xmm1); /* xmm1 = -- -- -- 45 41 -- -- -- */ \ + \ + pxor_r2r(xmm1, xmm5); /* xmm5 = 47 46 -- -- -- -- 40 -- */ \ + pslldq_i2r(4, xmm1); /* xmm1 = -- 45 41 -- -- -- -- -- */ \ + \ + pshufd_r2r(xmm5, xmm5, 0x09C); /* xmm5 = -- -- -- -- 47 46 40 -- */ \ + por_r2r(xmm1, xmm3); /* xmm3 = -- 45 41 27 22 14 07 05 */ \ + \ + movdqu_m2r(*(eax + 96), xmm1); /* xmm1 = 67 66 65 64 63 62 61 60 */ \ + pmullw_m2r(*(ebx + 96), xmm1); \ + \ + movdqu_m2r(*(ecx), xmm7); /* xmm7 = -- -- -- -- -- FF FF -- */ \ + \ + psrldq_i2r(8, xmm6); /* xmm6 = -- -- -- -- -- -- -- FF */ \ + pand_r2r(xmm5, xmm7); /* xmm7 = -- -- -- -- -- 46 40 -- */ \ + \ + pand_r2r(xmm1, xmm6); /* xmm6 = -- -- -- -- -- -- -- 60 */ \ + pxor_r2r(xmm7, xmm5); /* xmm5 = -- -- -- -- 47 -- -- -- */ \ + \ + pxor_r2r(xmm6, xmm1); /* xmm1 = 67 66 65 64 63 62 61 -- */ \ + pslldq_i2r(2, xmm5); /* xmm5 = -- -- -- 47 -- -- -- -- */ \ + \ + pslldq_i2r(14, xmm6); /* xmm6 = 60 -- -- -- -- -- -- -- */ \ + por_r2r(xmm5, xmm4); /* xmm4 = -- -- -- 47 -- -- 20 -- */ \ + \ + por_r2r(xmm6, xmm3); /* xmm3 = 60 45 41 27 22 14 07 05 */ \ + pslldq_i2r(6, xmm7); /* xmm7 = -- -- 46 40 -- -- -- -- */ \ + \ + movdqu_r2m(xmm3, *(eax+32)); /* write 60 45 41 27 22 14 07 05 */ \ + por_r2r(xmm7, xmm0); /* xmm0 = -- -- 46 40 -- 21 15 06 */ \ + /* 0, 1, 2, 4 in use */ \ + movdqu_m2r(*(eax + 48), xmm3); /* xmm3 = 37 36 35 34 33 32 31 30 */ \ + movdqu_m2r(*(eax + 80), xmm5); /* xmm5 = 57 56 55 54 53 52 51 50 */ \ + \ + pmullw_m2r(*(ebx + 48), xmm3); \ + pmullw_m2r(*(ebx + 80), xmm5); \ + \ + movdqu_m2r(*(ecx + 64), xmm6); /* xmm6 = -- -- -- FF FF -- -- -- */ \ + movdqu_m2r(*(ecx + 64), xmm7); /* xmm7 = -- -- -- FF FF -- -- -- */ \ + \ + psrldq_i2r(8, xmm6); /* xmm6 = -- -- -- -- -- -- -- FF */ \ + pslldq_i2r(8, xmm7); /* xmm7 = FF -- -- -- -- -- -- -- */ \ + \ + pand_r2r(xmm3, xmm6); /* xmm6 = -- -- -- -- -- -- -- 30 */ \ + pand_r2r(xmm5, xmm7); /* xmm7 = 57 -- -- -- -- -- -- -- */ \ + \ + pxor_r2r(xmm6, xmm3); /* xmm3 = 37 36 35 34 33 32 31 -- */ \ + pxor_r2r(xmm7, xmm5); /* xmm5 = __ 56 55 54 53 52 51 50 */ \ + \ + pslldq_i2r(6, xmm6); /* xmm6 = -- -- -- -- 30 -- -- -- */ \ + psrldq_i2r(2, xmm7); /* xmm7 = -- 57 -- -- -- -- -- -- */ \ + \ + por_r2r(xmm7, xmm6); /* xmm6 = -- 57 -- -- 30 -- -- -- */ \ + movdqu_m2r(*(ecx), xmm7); /* xmm7 = -- -- -- -- -- FF FF -- */ \ + \ + por_r2r(xmm6, xmm0); /* xmm0 = -- 57 46 40 30 21 15 06 */ \ + psrldq_i2r(2, xmm7); /* xmm7 = -- -- -- -- -- -- FF FF */ \ + \ + movdqu_r2r(xmm2, xmm6); /* xmm6 = 17 16 -- -- -- -- -- -- */ \ + pand_r2r(xmm1, xmm7); /* xmm7 = -- -- -- -- -- -- 61 -- */ \ + \ + pslldq_i2r(2, xmm6); /* xmm6 = 16 -- -- -- -- -- -- -- */ \ + psrldq_i2r(14, xmm2); /* xmm2 = -- -- -- -- -- -- -- 17 */ \ + \ + pxor_r2r(xmm7, xmm1); /* xmm1 = 67 66 65 64 63 62 -- -- */ \ + pslldq_i2r(12, xmm7); /* xmm7 = 61 -- -- -- -- -- -- -- */ \ + \ + psrldq_i2r(14, xmm6); /* xmm6 = -- -- -- -- -- -- -- 16 */ \ + por_r2r(xmm6, xmm4); /* xmm4 = -- -- -- 47 -- -- 20 16 */ \ + \ + por_r2r(xmm7, xmm0); /* xmm0 = 61 57 46 40 30 21 15 06 */ \ + movdqu_m2r(*(ecx), xmm6); /* xmm6 = -- -- -- -- -- FF FF -- */ \ + \ + psrldq_i2r(2, xmm6); /* xmm6 = -- -- -- -- -- -- FF FF */ \ + movdqu_r2m(xmm0, *(eax+48)); /* write 61 57 46 40 30 21 15 06 */ \ + /* 1, 2, 3, 4, 5 in use */\ + movdqu_m2r(*(ecx), xmm0); /* xmm0 = -- -- -- -- -- FF FF -- */ \ + pand_r2r(xmm3, xmm6); /* xmm6 = -- -- -- -- -- -- 31 -- */ \ + \ + movdqu_r2r(xmm3, xmm7); /* xmm7 = 37 36 35 34 33 32 31 -- */ \ + pxor_r2r(xmm6, xmm3); /* xmm3 = 37 36 35 34 33 32 -- -- */ \ + \ + pslldq_i2r(2, xmm3); /* xmm3 = 36 35 34 33 32 -- -- -- */ \ + pand_r2r(xmm1, xmm0); /* xmm0 = -- -- -- -- -- 62 -- -- */ \ + \ + psrldq_i2r(14, xmm7); /* xmm7 = -- -- -- -- -- -- -- 37 */ \ + pxor_r2r(xmm0, xmm1); /* xmm1 = 67 66 65 64 63 -- -- -- */ \ + \ + por_r2r(xmm7, xmm6); /* xmm6 = -- -- -- -- -- -- 31 37 */ \ + movdqu_m2r(*(ecx + 64), xmm7); /* xmm7 = -- -- -- FF FF -- -- -- */ \ + \ + pshuflw_r2r(xmm6, xmm6, 0x01E); /* xmm6 = -- -- -- -- 37 31 -- -- */ \ + pslldq_i2r(6, xmm7); /* xmm7 = FF FF -- -- -- -- -- -- */ \ + \ + por_r2r(xmm6, xmm4); /* xmm4 = -- -- -- 47 37 31 20 16 */ \ + pand_r2r(xmm5, xmm7); /* xmm7 = -- 56 -- -- -- -- -- -- */ \ + \ + pslldq_i2r(8, xmm0); /* xmm0 = -- 62 -- -- -- -- -- -- */ \ + pxor_r2r(xmm7, xmm5); /* xmm5 = -- -- 55 54 53 52 51 50 */ \ + \ + psrldq_i2r(2, xmm7); /* xmm7 = -- -- 56 -- -- -- -- -- */ \ + \ + pshufhw_r2r(xmm3, xmm3, 0x087); /* xmm3 = 35 33 34 36 32 -- -- -- */ \ + por_r2r(xmm7, xmm0); /* xmm0 = -- 62 56 -- -- -- -- -- */ \ + \ + movdqu_m2r(*(eax + 112), xmm7); /* xmm7 = 77 76 75 74 73 72 71 70 */ \ + pmullw_m2r(*(ebx + 112), xmm7); \ + \ + movdqu_m2r(*(ecx + 64), xmm6); /* xmm6 = -- -- -- FF FF -- -- -- */ \ + por_r2r(xmm0, xmm4); /* xmm4 = -- 62 56 47 37 31 20 16 */ \ + \ + pshuflw_r2r(xmm7, xmm7, 0x0E1); /* xmm7 = 77 76 75 74 73 72 70 71 */ \ + psrldq_i2r(8, xmm6); /* xmm6 = -- -- -- -- -- -- -- FF */ \ + \ + movdqu_m2r(*(ecx + 64), xmm0); /* xmm0 = -- -- -- FF FF -- -- -- */ \ + pand_r2r(xmm7, xmm6); /* xmm6 = -- -- -- -- -- -- -- 71 */ \ + \ + pand_r2r(xmm3, xmm0); /* xmm0 = -- -- -- 36 32 -- -- -- */ \ + pxor_r2r(xmm6, xmm7); /* xmm7 = 77 76 75 74 73 72 70 -- */ \ + \ + pxor_r2r(xmm0, xmm3); /* xmm3 = 35 33 34 -- -- -- -- -- */ \ + pslldq_i2r(14, xmm6); /* xmm6 = 71 -- -- -- -- -- -- -- */ \ + \ + psrldq_i2r(4, xmm0); /* xmm0 = -- -- -- -- -- 36 32 -- */ \ + por_r2r(xmm6, xmm4); /* xmm4 = 71 62 56 47 37 31 20 16 */ \ + \ + por_r2r(xmm0, xmm2); /* xmm2 = -- -- -- -- -- 36 32 17 */ \ + movdqu_r2m(xmm4, *(eax + 64)); /* write 71 62 56 47 37 31 20 16 */ \ + /* 1, 2, 3, 5, 7 in use */ \ + movdqu_m2r(*(ecx + 80), xmm6); /* xmm6 = -- -- FF -- -- -- -- FF */ \ + pshufhw_r2r(xmm7, xmm7, 0x0D2); /* xmm7 = 77 75 74 76 73 72 70 __ */ \ + \ + movdqu_m2r(*(ecx), xmm4); /* xmm4 = -- -- -- -- -- FF FF -- */ \ + movdqu_m2r(*(ecx+48), xmm0); /* xmm0 = -- -- -- -- FF -- -- -- */ \ + \ + pand_r2r(xmm5, xmm6); /* xmm6 = -- -- 55 -- -- -- -- 50 */ \ + pand_r2r(xmm7, xmm4); /* xmm4 = -- -- -- -- -- 72 70 -- */ \ + \ + pand_r2r(xmm1, xmm0); /* xmm0 = -- -- -- -- 63 -- -- -- */ \ + pxor_r2r(xmm6, xmm5); /* xmm5 = -- -- -- 54 53 52 51 -- */ \ + \ + pxor_r2r(xmm4, xmm7); /* xmm7 = 77 75 74 76 73 -- -- -- */ \ + pxor_r2r(xmm0, xmm1); /* xmm1 = 67 66 65 64 -- -- -- -- */ \ + \ + pshuflw_r2r(xmm6, xmm6, 0x02B); /* xmm6 = -- -- 55 -- 50 -- -- -- */ \ + pslldq_i2r(10, xmm4); /* xmm4 = 72 20 -- -- -- -- -- -- */ \ + \ + pshufhw_r2r(xmm6, xmm6, 0x0B1); /* xmm6 = -- -- -- 55 50 -- -- -- */ \ + pslldq_i2r(4, xmm0); /* xmm0 = -- -- 63 -- -- -- -- -- */ \ + \ + por_r2r(xmm4, xmm6); /* xmm6 = 72 70 -- 55 50 -- -- -- */ \ + por_r2r(xmm0, xmm2); /* xmm2 = -- -- 63 -- -- 36 32 17 */ \ + \ + por_r2r(xmm6, xmm2); /* xmm2 = 72 70 64 55 50 36 32 17 */ \ + pshufhw_r2r(xmm1, xmm1, 0x0C9); /* xmm1 = 67 64 66 65 -- -- -- -- */ \ + \ + movdqu_r2r(xmm3, xmm6); /* xmm6 = 35 33 34 -- -- -- -- -- */ \ + movdqu_r2m(xmm2, *(eax+80)); /* write 72 70 64 55 50 36 32 17 */ \ + \ + psrldq_i2r(12, xmm6); /* xmm6 = -- -- -- -- -- -- 35 33 */ \ + pslldq_i2r(4, xmm3); /* xmm3 = 34 -- -- -- -- -- -- -- */ \ + \ + pshuflw_r2r(xmm5, xmm5, 0x04E); /* xmm5 = -- -- -- 54 51 -- 53 52 */ \ + movdqu_r2r(xmm7, xmm4); /* xmm4 = 77 75 74 76 73 -- -- -- */ \ + \ + movdqu_r2r(xmm5, xmm2); /* xmm2 = -- -- -- 54 51 -- 53 52 */ \ + psrldq_i2r(10, xmm7); /* xmm7 = -- -- -- -- -- 77 75 74 */ \ + \ + pslldq_i2r(6, xmm4); /* xmm4 = 76 73 -- -- -- -- -- -- */ \ + pslldq_i2r(12, xmm2); /* xmm2 = 53 52 -- -- -- -- -- -- */ \ + \ + movdqu_r2r(xmm1, xmm0); /* xmm0 = 67 64 66 65 -- -- -- -- */ \ + psrldq_i2r(12, xmm1); /* xmm1 = -- -- -- -- -- -- 67 64 */ \ + \ + psrldq_i2r(6, xmm5); /* xmm5 = -- -- -- -- -- -- 54 51 */ \ + psrldq_i2r(14, xmm3); /* xmm3 = -- -- -- -- -- -- -- 34 */ \ + \ + pslldq_i2r(10, xmm7); /* xmm7 = 77 75 74 -- -- -- -- -- */ \ + por_r2r(xmm6, xmm4); /* xmm4 = 76 73 -- -- -- -- 35 33 */ \ + \ + psrldq_i2r(10, xmm2); /* xmm2 = -- -- -- -- -- 53 52 -- */ \ + pslldq_i2r(4, xmm0); /* xmm0 = 66 65 -- -- -- -- -- -- */ \ + \ + pslldq_i2r(8, xmm1); /* xmm1 = -- -- 67 64 -- -- -- -- */ \ + por_r2r(xmm7, xmm3); /* xmm3 = 77 75 74 -- -- -- -- 34 */ \ + \ + psrldq_i2r(6, xmm0); /* xmm0 = -- -- -- 66 65 -- -- -- */ \ + pslldq_i2r(4, xmm5); /* xmm5 = -- -- -- -- 54 51 -- -- */ \ + \ + por_r2r(xmm1, xmm4); /* xmm4 = 76 73 67 64 -- -- 35 33 */ \ + por_r2r(xmm2, xmm3); /* xmm3 = 77 75 74 -- -- 53 52 34 */ \ + \ + por_r2r(xmm5, xmm4); /* xmm4 = 76 73 67 64 54 51 35 33 */ \ + por_r2r(xmm0, xmm3); /* xmm3 = 77 75 74 66 65 53 52 34 */ \ + \ + movdqu_r2m(xmm4, *(eax+96)); /* write 76 73 67 64 54 51 35 33 */ \ + movdqu_r2m(xmm3, *(eax+112)); /* write 77 75 74 66 65 53 52 34 */ \ + \ +} /* end of SSE2_Dequantize Macro */ + + +void ff_vp3_idct_sse2(int16_t *input_data) +{ + unsigned char *input_bytes = (unsigned char *)input_data; + unsigned char *output_data_bytes = (unsigned char *)input_data; + unsigned char *idct_data_bytes = (unsigned char *)SSE2_idct_data; + unsigned char *Eight = (unsigned char *)eight_data; + +#define eax input_bytes +//#define ebx dequant_matrix_bytes +#define ecx dequant_const_bytes +#define edx idct_data_bytes + +#define I(i) (eax + 16 * i) +#define O(i) (ebx + 16 * i) +#define C(i) (edx + 16 * (i-1)) + + // SSE2_Dequantize(); + +#undef ebx +#define ebx output_data_bytes + + SSE2_Row_IDCT(); + + SSE2_Transpose(); + + SSE2_Column_IDCT(); +} diff --git a/mpeg4/src/libavcodec/idcinvideo.c b/mpeg4/src/libavcodec/idcinvideo.c new file mode 100644 index 00000000..7e7e6aab --- /dev/null +++ b/mpeg4/src/libavcodec/idcinvideo.c @@ -0,0 +1,270 @@ +/* + * Id Quake II CIN Video Decoder + * Copyright (C) 2003 the ffmpeg project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file idcinvideo.c + * Id Quake II Cin Video Decoder by Dr. Tim Ferguson + * For more information about the Id CIN format, visit: + * http://www.csse.monash.edu.au/~timf/ + * + * This video decoder outputs PAL8 colorspace data. Interacting with this + * decoder is a little involved. During initialization, the demuxer must + * transmit the 65536-byte Huffman table(s) to the decoder via extradata. + * Then, whenever a palette change is encountered while demuxing the file, + * the demuxer must use the same extradata space to transmit an + * AVPaletteControl structure. + * + * Id CIN video is purely Huffman-coded, intraframe-only codec. It achieves + * a little more compression by exploiting the fact that adjacent pixels + * tend to be similar. + * + * Note that this decoder could use ffmpeg's optimized VLC facilities + * rather than naive, tree-based Huffman decoding. However, there are 256 + * Huffman tables. Plus, the VLC bit coding order is right -> left instead + * or left -> right, so all of the bits would have to be reversed. Further, + * the original Quake II implementation likely used a similar naive + * decoding algorithm and it worked fine on much lower spec machines. + */ + +#include +#include +#include +#include + +#include "common.h" +#include "avcodec.h" +#include "dsputil.h" + +#define HUFFMAN_TABLE_SIZE 64 * 1024 +#define HUF_TOKENS 256 +#define PALETTE_COUNT 256 + +typedef struct +{ + int count; + unsigned char used; + int children[2]; +} hnode_t; + +typedef struct IdcinContext { + + AVCodecContext *avctx; + DSPContext dsp; + AVFrame frame; + + unsigned char *buf; + int size; + + hnode_t huff_nodes[256][HUF_TOKENS*2]; + int num_huff_nodes[256]; + +} IdcinContext; + +/* + * Find the lowest probability node in a Huffman table, and mark it as + * being assigned to a higher probability. + * Returns the node index of the lowest unused node, or -1 if all nodes + * are used. + */ +static int huff_smallest_node(hnode_t *hnodes, int num_hnodes) { + int i; + int best, best_node; + + best = 99999999; + best_node = -1; + for(i = 0; i < num_hnodes; i++) { + if(hnodes[i].used) + continue; + if(!hnodes[i].count) + continue; + if(hnodes[i].count < best) { + best = hnodes[i].count; + best_node = i; + } + } + + if(best_node == -1) + return -1; + hnodes[best_node].used = 1; + return best_node; +} + +/* + * Build the Huffman tree using the generated/loaded probabilities histogram. + * + * On completion: + * huff_nodes[prev][i < HUF_TOKENS] - are the nodes at the base of the tree. + * huff_nodes[prev][i >= HUF_TOKENS] - are used to construct the tree. + * num_huff_nodes[prev] - contains the index to the root node of the tree. + * That is: huff_nodes[prev][num_huff_nodes[prev]] is the root node. + */ +static void huff_build_tree(IdcinContext *s, int prev) { + hnode_t *node, *hnodes; + int num_hnodes, i; + + num_hnodes = HUF_TOKENS; + hnodes = s->huff_nodes[prev]; + for(i = 0; i < HUF_TOKENS * 2; i++) + hnodes[i].used = 0; + + while (1) { + node = &hnodes[num_hnodes]; /* next free node */ + + /* pick two lowest counts */ + node->children[0] = huff_smallest_node(hnodes, num_hnodes); + if(node->children[0] == -1) + break; /* reached the root node */ + + node->children[1] = huff_smallest_node(hnodes, num_hnodes); + if(node->children[1] == -1) + break; /* reached the root node */ + + /* combine nodes probability for new node */ + node->count = hnodes[node->children[0]].count + + hnodes[node->children[1]].count; + num_hnodes++; + } + + s->num_huff_nodes[prev] = num_hnodes - 1; +} + +static int idcin_decode_init(AVCodecContext *avctx) +{ + IdcinContext *s = (IdcinContext *)avctx->priv_data; + int i, j, histogram_index = 0; + unsigned char *histograms; + + s->avctx = avctx; + avctx->pix_fmt = PIX_FMT_PAL8; + avctx->has_b_frames = 0; + dsputil_init(&s->dsp, avctx); + + /* make sure the Huffman tables make it */ + if (s->avctx->extradata_size != HUFFMAN_TABLE_SIZE) { + av_log(s->avctx, AV_LOG_ERROR, " Id CIN video: expected extradata size of %d\n", HUFFMAN_TABLE_SIZE); + return -1; + } + + /* build the 256 Huffman decode trees */ + histograms = (unsigned char *)s->avctx->extradata; + for (i = 0; i < 256; i++) { + for(j = 0; j < HUF_TOKENS; j++) + s->huff_nodes[i][j].count = histograms[histogram_index++]; + huff_build_tree(s, i); + } + + s->frame.data[0] = NULL; + + return 0; +} + +static void idcin_decode_vlcs(IdcinContext *s) +{ + hnode_t *hnodes; + long x, y; + int prev; + unsigned char v = 0; + int bit_pos, node_num, dat_pos; + + prev = bit_pos = dat_pos = 0; + for (y = 0; y < (s->frame.linesize[0] * s->avctx->height); + y += s->frame.linesize[0]) { + for (x = y; x < y + s->avctx->width; x++) { + node_num = s->num_huff_nodes[prev]; + hnodes = s->huff_nodes[prev]; + + while(node_num >= HUF_TOKENS) { + if(!bit_pos) { + if(dat_pos >= s->size) { + av_log(s->avctx, AV_LOG_ERROR, "Huffman decode error.\n"); + return; + } + bit_pos = 8; + v = s->buf[dat_pos++]; + } + + node_num = hnodes[node_num].children[v & 0x01]; + v = v >> 1; + bit_pos--; + } + + s->frame.data[0][x] = node_num; + prev = node_num; + } + } +} + +static int idcin_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + IdcinContext *s = (IdcinContext *)avctx->priv_data; + AVPaletteControl *palette_control = avctx->palctrl; + + s->buf = buf; + s->size = buf_size; + + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + if (avctx->get_buffer(avctx, &s->frame)) { + av_log(avctx, AV_LOG_ERROR, " Id CIN Video: get_buffer() failed\n"); + return -1; + } + + idcin_decode_vlcs(s); + + /* make the palette available on the way out */ + memcpy(s->frame.data[1], palette_control->palette, PALETTE_COUNT * 4); + /* If palette changed inform application*/ + if (palette_control->palette_changed) { + palette_control->palette_changed = 0; + s->frame.palette_has_changed = 1; + } + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = s->frame; + + /* report that the buffer was completely consumed */ + return buf_size; +} + +static int idcin_decode_end(AVCodecContext *avctx) +{ + IdcinContext *s = (IdcinContext *)avctx->priv_data; + + if (s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + return 0; +} + +AVCodec idcin_decoder = { + "idcinvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_IDCIN, + sizeof(IdcinContext), + idcin_decode_init, + NULL, + idcin_decode_end, + idcin_decode_frame, + CODEC_CAP_DR1, +}; + diff --git a/mpeg4/src/libavcodec/imgconvert.c b/mpeg4/src/libavcodec/imgconvert.c new file mode 100644 index 00000000..cf0c297e --- /dev/null +++ b/mpeg4/src/libavcodec/imgconvert.c @@ -0,0 +1,2592 @@ +/* + * Misc image convertion routines + * Copyright (c) 2001, 2002, 2003 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file imgconvert.c + * Misc image convertion routines. + */ + +/* TODO: + * - write 'ffimg' program to test all the image related stuff + * - move all api to slice based system + * - integrate deinterlacing, postprocessing and scaling in the conversion process + */ + +#include "avcodec.h" +#include "dsputil.h" + +#ifdef USE_FASTMEMCPY +#include "fastmemcpy.h" +#endif + +#ifdef HAVE_MMX +#include "i386/mmx.h" +#endif + +#define xglue(x, y) x ## y +#define glue(x, y) xglue(x, y) + +#define FF_COLOR_RGB 0 /* RGB color space */ +#define FF_COLOR_GRAY 1 /* gray color space */ +#define FF_COLOR_YUV 2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ +#define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ + +#define FF_PIXEL_PLANAR 0 /* each channel has one component in AVPicture */ +#define FF_PIXEL_PACKED 1 /* only one components containing all the channels */ +#define FF_PIXEL_PALETTE 2 /* one components containing indexes for a palette */ + +typedef struct PixFmtInfo { + const char *name; + uint8_t nb_channels; /* number of channels (including alpha) */ + uint8_t color_type; /* color type (see FF_COLOR_xxx constants) */ + uint8_t pixel_type; /* pixel storage type (see FF_PIXEL_xxx constants) */ + uint8_t is_alpha : 1; /* true if alpha can be specified */ + uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */ + uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */ + uint8_t depth; /* bit depth of the color components */ +} PixFmtInfo; + +/* this table gives more information about formats */ +static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = { + /* YUV formats */ + [PIX_FMT_YUV420P] = { + .name = "yuv420p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, + [PIX_FMT_YUV422P] = { + .name = "yuv422p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 1, .y_chroma_shift = 0, + }, + [PIX_FMT_YUV444P] = { + .name = "yuv444p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_YUV422] = { + .name = "yuv422", + .nb_channels = 1, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PACKED, + .depth = 8, + .x_chroma_shift = 1, .y_chroma_shift = 0, + }, + [PIX_FMT_UYVY422] = { + .name = "uyvy422", + .nb_channels = 1, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PACKED, + .depth = 8, + .x_chroma_shift = 1, .y_chroma_shift = 0, + }, + [PIX_FMT_YUV410P] = { + .name = "yuv410p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 2, .y_chroma_shift = 2, + }, + [PIX_FMT_YUV411P] = { + .name = "yuv411p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 2, .y_chroma_shift = 0, + }, + + /* JPEG YUV */ + [PIX_FMT_YUVJ420P] = { + .name = "yuvj420p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV_JPEG, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 1, .y_chroma_shift = 1, + }, + [PIX_FMT_YUVJ422P] = { + .name = "yuvj422p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV_JPEG, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 1, .y_chroma_shift = 0, + }, + [PIX_FMT_YUVJ444P] = { + .name = "yuvj444p", + .nb_channels = 3, + .color_type = FF_COLOR_YUV_JPEG, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + + /* RGB formats */ + [PIX_FMT_RGB24] = { + .name = "rgb24", + .nb_channels = 3, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 8, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_BGR24] = { + .name = "bgr24", + .nb_channels = 3, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 8, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_RGBA32] = { + .name = "rgba32", + .nb_channels = 4, .is_alpha = 1, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 8, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_RGB565] = { + .name = "rgb565", + .nb_channels = 3, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 5, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + [PIX_FMT_RGB555] = { + .name = "rgb555", + .nb_channels = 4, .is_alpha = 1, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PACKED, + .depth = 5, + .x_chroma_shift = 0, .y_chroma_shift = 0, + }, + + /* gray / mono formats */ + [PIX_FMT_GRAY8] = { + .name = "gray", + .nb_channels = 1, + .color_type = FF_COLOR_GRAY, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 8, + }, + [PIX_FMT_MONOWHITE] = { + .name = "monow", + .nb_channels = 1, + .color_type = FF_COLOR_GRAY, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 1, + }, + [PIX_FMT_MONOBLACK] = { + .name = "monob", + .nb_channels = 1, + .color_type = FF_COLOR_GRAY, + .pixel_type = FF_PIXEL_PLANAR, + .depth = 1, + }, + + /* paletted formats */ + [PIX_FMT_PAL8] = { + .name = "pal8", + .nb_channels = 4, .is_alpha = 1, + .color_type = FF_COLOR_RGB, + .pixel_type = FF_PIXEL_PALETTE, + .depth = 8, + }, + [PIX_FMT_XVMC_MPEG2_MC] = { + .name = "xvmcmc", + }, + [PIX_FMT_XVMC_MPEG2_IDCT] = { + .name = "xvmcidct", + }, + [PIX_FMT_UYVY411] = { + .name = "uyvy411", + .nb_channels = 1, + .color_type = FF_COLOR_YUV, + .pixel_type = FF_PIXEL_PACKED, + .depth = 8, + .x_chroma_shift = 2, .y_chroma_shift = 0, + }, +}; + +void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift) +{ + *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift; + *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift; +} + +const char *avcodec_get_pix_fmt_name(int pix_fmt) +{ + if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB) + return "???"; + else + return pix_fmt_info[pix_fmt].name; +} + +enum PixelFormat avcodec_get_pix_fmt(const char* name) +{ + int i; + + for (i=0; i < PIX_FMT_NB; i++) + if (!strcmp(pix_fmt_info[i].name, name)) + break; + return i; +} + +/* Picture field are filled with 'ptr' addresses. Also return size */ +int avpicture_fill(AVPicture *picture, uint8_t *ptr, + int pix_fmt, int width, int height) +{ + int size, w2, h2, size2; + PixFmtInfo *pinfo; + + if(avcodec_check_dimensions(NULL, width, height)) + goto fail; + + pinfo = &pix_fmt_info[pix_fmt]; + size = width * height; + switch(pix_fmt) { + case PIX_FMT_YUV420P: + case PIX_FMT_YUV422P: + case PIX_FMT_YUV444P: + case PIX_FMT_YUV410P: + case PIX_FMT_YUV411P: + case PIX_FMT_YUVJ420P: + case PIX_FMT_YUVJ422P: + case PIX_FMT_YUVJ444P: + w2 = (width + (1 << pinfo->x_chroma_shift) - 1) >> pinfo->x_chroma_shift; + h2 = (height + (1 << pinfo->y_chroma_shift) - 1) >> pinfo->y_chroma_shift; + size2 = w2 * h2; + picture->data[0] = ptr; + picture->data[1] = picture->data[0] + size; + picture->data[2] = picture->data[1] + size2; + picture->linesize[0] = width; + picture->linesize[1] = w2; + picture->linesize[2] = w2; + return size + 2 * size2; + case PIX_FMT_RGB24: + case PIX_FMT_BGR24: + picture->data[0] = ptr; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->linesize[0] = width * 3; + return size * 3; + case PIX_FMT_RGBA32: + picture->data[0] = ptr; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->linesize[0] = width * 4; + return size * 4; + case PIX_FMT_RGB555: + case PIX_FMT_RGB565: + case PIX_FMT_YUV422: + picture->data[0] = ptr; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->linesize[0] = width * 2; + return size * 2; + case PIX_FMT_UYVY422: + picture->data[0] = ptr; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->linesize[0] = width * 2; + return size * 2; + case PIX_FMT_UYVY411: + picture->data[0] = ptr; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->linesize[0] = width + width/2; + return size + size/2; + case PIX_FMT_GRAY8: + picture->data[0] = ptr; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->linesize[0] = width; + return size; + case PIX_FMT_MONOWHITE: + case PIX_FMT_MONOBLACK: + picture->data[0] = ptr; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->linesize[0] = (width + 7) >> 3; + return picture->linesize[0] * height; + case PIX_FMT_PAL8: + size2 = (size + 3) & ~3; + picture->data[0] = ptr; + picture->data[1] = ptr + size2; /* palette is stored here as 256 32 bit words */ + picture->data[2] = NULL; + picture->linesize[0] = width; + picture->linesize[1] = 4; + return size2 + 256 * 4; + default: +fail: + picture->data[0] = NULL; + picture->data[1] = NULL; + picture->data[2] = NULL; + picture->data[3] = NULL; + return -1; + } +} + +int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, + unsigned char *dest, int dest_size) +{ + PixFmtInfo* pf = &pix_fmt_info[pix_fmt]; + int i, j, w, h, data_planes; + const unsigned char* s; + int size = avpicture_get_size(pix_fmt, width, height); + + if (size > dest_size || size < 0) + return -1; + + if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) { + if (pix_fmt == PIX_FMT_YUV422 || + pix_fmt == PIX_FMT_UYVY422 || + pix_fmt == PIX_FMT_RGB565 || + pix_fmt == PIX_FMT_RGB555) + w = width * 2; + else if (pix_fmt == PIX_FMT_UYVY411) + w = width + width/2; + else if (pix_fmt == PIX_FMT_PAL8) + w = width; + else + w = width * (pf->depth * pf->nb_channels / 8); + + data_planes = 1; + h = height; + } else { + data_planes = pf->nb_channels; + w = (width*pf->depth + 7)/8; + h = height; + } + + for (i=0; i> pf->x_chroma_shift; + h = height >> pf->y_chroma_shift; + } + s = src->data[i]; + for(j=0; jlinesize[i]; + } + } + + if (pf->pixel_type == FF_PIXEL_PALETTE) + memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4); + + return size; +} + +int avpicture_get_size(int pix_fmt, int width, int height) +{ + AVPicture dummy_pict; + return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height); +} + +/** + * compute the loss when converting from a pixel format to another + */ +int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, + int has_alpha) +{ + const PixFmtInfo *pf, *ps; + int loss; + + ps = &pix_fmt_info[src_pix_fmt]; + pf = &pix_fmt_info[dst_pix_fmt]; + + /* compute loss */ + loss = 0; + pf = &pix_fmt_info[dst_pix_fmt]; + if (pf->depth < ps->depth || + (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565)) + loss |= FF_LOSS_DEPTH; + if (pf->x_chroma_shift > ps->x_chroma_shift || + pf->y_chroma_shift > ps->y_chroma_shift) + loss |= FF_LOSS_RESOLUTION; + switch(pf->color_type) { + case FF_COLOR_RGB: + if (ps->color_type != FF_COLOR_RGB && + ps->color_type != FF_COLOR_GRAY) + loss |= FF_LOSS_COLORSPACE; + break; + case FF_COLOR_GRAY: + if (ps->color_type != FF_COLOR_GRAY) + loss |= FF_LOSS_COLORSPACE; + break; + case FF_COLOR_YUV: + if (ps->color_type != FF_COLOR_YUV) + loss |= FF_LOSS_COLORSPACE; + break; + case FF_COLOR_YUV_JPEG: + if (ps->color_type != FF_COLOR_YUV_JPEG && + ps->color_type != FF_COLOR_YUV && + ps->color_type != FF_COLOR_GRAY) + loss |= FF_LOSS_COLORSPACE; + break; + default: + /* fail safe test */ + if (ps->color_type != pf->color_type) + loss |= FF_LOSS_COLORSPACE; + break; + } + if (pf->color_type == FF_COLOR_GRAY && + ps->color_type != FF_COLOR_GRAY) + loss |= FF_LOSS_CHROMA; + if (!pf->is_alpha && (ps->is_alpha && has_alpha)) + loss |= FF_LOSS_ALPHA; + if (pf->pixel_type == FF_PIXEL_PALETTE && + (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY)) + loss |= FF_LOSS_COLORQUANT; + return loss; +} + +static int avg_bits_per_pixel(int pix_fmt) +{ + int bits; + const PixFmtInfo *pf; + + pf = &pix_fmt_info[pix_fmt]; + switch(pf->pixel_type) { + case FF_PIXEL_PACKED: + switch(pix_fmt) { + case PIX_FMT_YUV422: + case PIX_FMT_UYVY422: + case PIX_FMT_RGB565: + case PIX_FMT_RGB555: + bits = 16; + break; + case PIX_FMT_UYVY411: + bits = 12; + break; + default: + bits = pf->depth * pf->nb_channels; + break; + } + break; + case FF_PIXEL_PLANAR: + if (pf->x_chroma_shift == 0 && pf->y_chroma_shift == 0) { + bits = pf->depth * pf->nb_channels; + } else { + bits = pf->depth + ((2 * pf->depth) >> + (pf->x_chroma_shift + pf->y_chroma_shift)); + } + break; + case FF_PIXEL_PALETTE: + bits = 8; + break; + default: + bits = -1; + break; + } + return bits; +} + +static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, + int src_pix_fmt, + int has_alpha, + int loss_mask) +{ + int dist, i, loss, min_dist, dst_pix_fmt; + + /* find exact color match with smallest size */ + dst_pix_fmt = -1; + min_dist = 0x7fffffff; + for(i = 0;i < PIX_FMT_NB; i++) { + if (pix_fmt_mask & (1 << i)) { + loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask; + if (loss == 0) { + dist = avg_bits_per_pixel(i); + if (dist < min_dist) { + min_dist = dist; + dst_pix_fmt = i; + } + } + } + } + return dst_pix_fmt; +} + +/** + * find best pixel format to convert to. Return -1 if none found + */ +int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, + int has_alpha, int *loss_ptr) +{ + int dst_pix_fmt, loss_mask, i; + static const int loss_mask_order[] = { + ~0, /* no loss first */ + ~FF_LOSS_ALPHA, + ~FF_LOSS_RESOLUTION, + ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION), + ~FF_LOSS_COLORQUANT, + ~FF_LOSS_DEPTH, + 0, + }; + + /* try with successive loss */ + i = 0; + for(;;) { + loss_mask = loss_mask_order[i++]; + dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, + has_alpha, loss_mask); + if (dst_pix_fmt >= 0) + goto found; + if (loss_mask == 0) + break; + } + return -1; + found: + if (loss_ptr) + *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha); + return dst_pix_fmt; +} + +void ff_img_copy_plane(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + if((!dst) || (!src)) + return; + for(;height > 0; height--) { + memcpy(dst, src, width); + dst += dst_wrap; + src += src_wrap; + } +} + +/** + * Copy image 'src' to 'dst'. + */ +void img_copy(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height) +{ + int bwidth, bits, i; + PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; + + pf = &pix_fmt_info[pix_fmt]; + switch(pf->pixel_type) { + case FF_PIXEL_PACKED: + switch(pix_fmt) { + case PIX_FMT_YUV422: + case PIX_FMT_UYVY422: + case PIX_FMT_RGB565: + case PIX_FMT_RGB555: + bits = 16; + break; + case PIX_FMT_UYVY411: + bits = 12; + break; + default: + bits = pf->depth * pf->nb_channels; + break; + } + bwidth = (width * bits + 7) >> 3; + ff_img_copy_plane(dst->data[0], dst->linesize[0], + src->data[0], src->linesize[0], + bwidth, height); + break; + case FF_PIXEL_PLANAR: + for(i = 0; i < pf->nb_channels; i++) { + int w, h; + w = width; + h = height; + if (i == 1 || i == 2) { + w >>= pf->x_chroma_shift; + h >>= pf->y_chroma_shift; + } + bwidth = (w * pf->depth + 7) >> 3; + ff_img_copy_plane(dst->data[i], dst->linesize[i], + src->data[i], src->linesize[i], + bwidth, h); + } + break; + case FF_PIXEL_PALETTE: + ff_img_copy_plane(dst->data[0], dst->linesize[0], + src->data[0], src->linesize[0], + width, height); + /* copy the palette */ + ff_img_copy_plane(dst->data[1], dst->linesize[1], + src->data[1], src->linesize[1], + 4, 256); + break; + } +} + +/* XXX: totally non optimized */ + +static void yuv422_to_yuv420p(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *p, *p1; + uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = src->data[0]; + lum1 = dst->data[0]; + cb1 = dst->data[1]; + cr1 = dst->data[2]; + + for(;height >= 1; height -= 2) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for(w = width; w >= 2; w -= 2) { + lum[0] = p[0]; + cb[0] = p[1]; + lum[1] = p[2]; + cr[0] = p[3]; + p += 4; + lum += 2; + cb++; + cr++; + } + if (w) { + lum[0] = p[0]; + cb[0] = p[1]; + cr[0] = p[3]; + cb++; + cr++; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + if (height>1) { + p = p1; + lum = lum1; + for(w = width; w >= 2; w -= 2) { + lum[0] = p[0]; + lum[1] = p[2]; + p += 4; + lum += 2; + } + if (w) { + lum[0] = p[0]; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + } + cb1 += dst->linesize[1]; + cr1 += dst->linesize[2]; + } +} + +static void uyvy422_to_yuv420p(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *p, *p1; + uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = src->data[0]; + + lum1 = dst->data[0]; + cb1 = dst->data[1]; + cr1 = dst->data[2]; + + for(;height >= 1; height -= 2) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for(w = width; w >= 2; w -= 2) { + lum[0] = p[1]; + cb[0] = p[0]; + lum[1] = p[3]; + cr[0] = p[2]; + p += 4; + lum += 2; + cb++; + cr++; + } + if (w) { + lum[0] = p[1]; + cb[0] = p[0]; + cr[0] = p[2]; + cb++; + cr++; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + if (height>1) { + p = p1; + lum = lum1; + for(w = width; w >= 2; w -= 2) { + lum[0] = p[1]; + lum[1] = p[3]; + p += 4; + lum += 2; + } + if (w) { + lum[0] = p[1]; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + } + cb1 += dst->linesize[1]; + cr1 += dst->linesize[2]; + } +} + + +static void uyvy422_to_yuv422p(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *p, *p1; + uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = src->data[0]; + lum1 = dst->data[0]; + cb1 = dst->data[1]; + cr1 = dst->data[2]; + for(;height > 0; height--) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for(w = width; w >= 2; w -= 2) { + lum[0] = p[1]; + cb[0] = p[0]; + lum[1] = p[3]; + cr[0] = p[2]; + p += 4; + lum += 2; + cb++; + cr++; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + cb1 += dst->linesize[1]; + cr1 += dst->linesize[2]; + } +} + + +static void yuv422_to_yuv422p(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *p, *p1; + uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = src->data[0]; + lum1 = dst->data[0]; + cb1 = dst->data[1]; + cr1 = dst->data[2]; + for(;height > 0; height--) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for(w = width; w >= 2; w -= 2) { + lum[0] = p[0]; + cb[0] = p[1]; + lum[1] = p[2]; + cr[0] = p[3]; + p += 4; + lum += 2; + cb++; + cr++; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + cb1 += dst->linesize[1]; + cr1 += dst->linesize[2]; + } +} + +static void yuv422p_to_yuv422(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + uint8_t *p, *p1; + const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = dst->data[0]; + lum1 = src->data[0]; + cb1 = src->data[1]; + cr1 = src->data[2]; + for(;height > 0; height--) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for(w = width; w >= 2; w -= 2) { + p[0] = lum[0]; + p[1] = cb[0]; + p[2] = lum[1]; + p[3] = cr[0]; + p += 4; + lum += 2; + cb++; + cr++; + } + p1 += dst->linesize[0]; + lum1 += src->linesize[0]; + cb1 += src->linesize[1]; + cr1 += src->linesize[2]; + } +} + +static void yuv422p_to_uyvy422(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + uint8_t *p, *p1; + const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = dst->data[0]; + lum1 = src->data[0]; + cb1 = src->data[1]; + cr1 = src->data[2]; + for(;height > 0; height--) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for(w = width; w >= 2; w -= 2) { + p[1] = lum[0]; + p[0] = cb[0]; + p[3] = lum[1]; + p[2] = cr[0]; + p += 4; + lum += 2; + cb++; + cr++; + } + p1 += dst->linesize[0]; + lum1 += src->linesize[0]; + cb1 += src->linesize[1]; + cr1 += src->linesize[2]; + } +} + +static void uyvy411_to_yuv411p(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *p, *p1; + uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1; + int w; + + p1 = src->data[0]; + lum1 = dst->data[0]; + cb1 = dst->data[1]; + cr1 = dst->data[2]; + for(;height > 0; height--) { + p = p1; + lum = lum1; + cb = cb1; + cr = cr1; + for(w = width; w >= 4; w -= 4) { + cb[0] = p[0]; + lum[0] = p[1]; + lum[1] = p[2]; + cr[0] = p[3]; + lum[2] = p[4]; + lum[3] = p[5]; + p += 6; + lum += 4; + cb++; + cr++; + } + p1 += src->linesize[0]; + lum1 += dst->linesize[0]; + cb1 += dst->linesize[1]; + cr1 += dst->linesize[2]; + } +} + + +static void yuv420p_to_yuv422(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + int w, h; + uint8_t *line1, *line2, *linesrc = dst->data[0]; + uint8_t *lum1, *lum2, *lumsrc = src->data[0]; + uint8_t *cb1, *cb2 = src->data[1]; + uint8_t *cr1, *cr2 = src->data[2]; + + for(h = height / 2; h--;) { + line1 = linesrc; + line2 = linesrc + dst->linesize[0]; + + lum1 = lumsrc; + lum2 = lumsrc + src->linesize[0]; + + cb1 = cb2; + cr1 = cr2; + + for(w = width / 2; w--;) { + *line1++ = *lum1++; *line2++ = *lum2++; + *line1++ = *line2++ = *cb1++; + *line1++ = *lum1++; *line2++ = *lum2++; + *line1++ = *line2++ = *cr1++; + } + + linesrc += dst->linesize[0] * 2; + lumsrc += src->linesize[0] * 2; + cb2 += src->linesize[1]; + cr2 += src->linesize[2]; + } +} + +static void yuv420p_to_uyvy422(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + int w, h; + uint8_t *line1, *line2, *linesrc = dst->data[0]; + uint8_t *lum1, *lum2, *lumsrc = src->data[0]; + uint8_t *cb1, *cb2 = src->data[1]; + uint8_t *cr1, *cr2 = src->data[2]; + + for(h = height / 2; h--;) { + line1 = linesrc; + line2 = linesrc + dst->linesize[0]; + + lum1 = lumsrc; + lum2 = lumsrc + src->linesize[0]; + + cb1 = cb2; + cr1 = cr2; + + for(w = width / 2; w--;) { + *line1++ = *line2++ = *cb1++; + *line1++ = *lum1++; *line2++ = *lum2++; + *line1++ = *line2++ = *cr1++; + *line1++ = *lum1++; *line2++ = *lum2++; + } + + linesrc += dst->linesize[0] * 2; + lumsrc += src->linesize[0] * 2; + cb2 += src->linesize[1]; + cr2 += src->linesize[2]; + } +} + +#define SCALEBITS 10 +#define ONE_HALF (1 << (SCALEBITS - 1)) +#define FIX(x) ((int) ((x) * (1<> SCALEBITS];\ + g = cm[(y + g_add) >> SCALEBITS];\ + b = cm[(y + b_add) >> SCALEBITS];\ +} + +#define YUV_TO_RGB1(cb1, cr1)\ +{\ + cb = (cb1) - 128;\ + cr = (cr1) - 128;\ + r_add = FIX(1.40200) * cr + ONE_HALF;\ + g_add = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF;\ + b_add = FIX(1.77200) * cb + ONE_HALF;\ +} + +#define YUV_TO_RGB2(r, g, b, y1)\ +{\ + y = (y1) << SCALEBITS;\ + r = cm[(y + r_add) >> SCALEBITS];\ + g = cm[(y + g_add) >> SCALEBITS];\ + b = cm[(y + b_add) >> SCALEBITS];\ +} + +#define Y_CCIR_TO_JPEG(y)\ + cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS] + +#define Y_JPEG_TO_CCIR(y)\ + (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) + +#define C_CCIR_TO_JPEG(y)\ + cm[(((y) - 128) * FIX(127.0/112.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS] + +/* NOTE: the clamp is really necessary! */ +static inline int C_JPEG_TO_CCIR(int y) { + y = (((y - 128) * FIX(112.0/127.0) + (ONE_HALF + (128 << SCALEBITS))) >> SCALEBITS); + if (y < 16) + y = 16; + return y; +} + + +#define RGB_TO_Y(r, g, b) \ +((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \ + FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS) + +#define RGB_TO_U(r1, g1, b1, shift)\ +(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 + \ + FIX(0.50000) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V(r1, g1, b1, shift)\ +(((FIX(0.50000) * r1 - FIX(0.41869) * g1 - \ + FIX(0.08131) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_Y_CCIR(r, g, b) \ +((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \ + FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS) + +#define RGB_TO_U_CCIR(r1, g1, b1, shift)\ +(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \ + FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +#define RGB_TO_V_CCIR(r1, g1, b1, shift)\ +(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \ + FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128) + +static uint8_t y_ccir_to_jpeg[256]; +static uint8_t y_jpeg_to_ccir[256]; +static uint8_t c_ccir_to_jpeg[256]; +static uint8_t c_jpeg_to_ccir[256]; + +/* init various conversion tables */ +static void img_convert_init(void) +{ + int i; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + + for(i = 0;i < 256; i++) { + y_ccir_to_jpeg[i] = Y_CCIR_TO_JPEG(i); + y_jpeg_to_ccir[i] = Y_JPEG_TO_CCIR(i); + c_ccir_to_jpeg[i] = C_CCIR_TO_JPEG(i); + c_jpeg_to_ccir[i] = C_JPEG_TO_CCIR(i); + } +} + +/* apply to each pixel the given table */ +static void img_apply_table(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height, const uint8_t *table1) +{ + int n; + const uint8_t *s; + uint8_t *d; + const uint8_t *table; + + table = table1; + for(;height > 0; height--) { + s = src; + d = dst; + n = width; + while (n >= 4) { + d[0] = table[s[0]]; + d[1] = table[s[1]]; + d[2] = table[s[2]]; + d[3] = table[s[3]]; + d += 4; + s += 4; + n -= 4; + } + while (n > 0) { + d[0] = table[s[0]]; + d++; + s++; + n--; + } + dst += dst_wrap; + src += src_wrap; + } +} + +/* XXX: use generic filter ? */ +/* XXX: in most cases, the sampling position is incorrect */ + +/* 4x1 -> 1x1 */ +static void shrink41(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w; + const uint8_t *s; + uint8_t *d; + + for(;height > 0; height--) { + s = src; + d = dst; + for(w = width;w > 0; w--) { + d[0] = (s[0] + s[1] + s[2] + s[3] + 2) >> 2; + s += 4; + d++; + } + src += src_wrap; + dst += dst_wrap; + } +} + +/* 2x1 -> 1x1 */ +static void shrink21(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w; + const uint8_t *s; + uint8_t *d; + + for(;height > 0; height--) { + s = src; + d = dst; + for(w = width;w > 0; w--) { + d[0] = (s[0] + s[1]) >> 1; + s += 2; + d++; + } + src += src_wrap; + dst += dst_wrap; + } +} + +/* 1x2 -> 1x1 */ +static void shrink12(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w; + uint8_t *d; + const uint8_t *s1, *s2; + + for(;height > 0; height--) { + s1 = src; + s2 = s1 + src_wrap; + d = dst; + for(w = width;w >= 4; w-=4) { + d[0] = (s1[0] + s2[0]) >> 1; + d[1] = (s1[1] + s2[1]) >> 1; + d[2] = (s1[2] + s2[2]) >> 1; + d[3] = (s1[3] + s2[3]) >> 1; + s1 += 4; + s2 += 4; + d += 4; + } + for(;w > 0; w--) { + d[0] = (s1[0] + s2[0]) >> 1; + s1++; + s2++; + d++; + } + src += 2 * src_wrap; + dst += dst_wrap; + } +} + +/* 2x2 -> 1x1 */ +void ff_shrink22(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w; + const uint8_t *s1, *s2; + uint8_t *d; + + for(;height > 0; height--) { + s1 = src; + s2 = s1 + src_wrap; + d = dst; + for(w = width;w >= 4; w-=4) { + d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; + d[1] = (s1[2] + s1[3] + s2[2] + s2[3] + 2) >> 2; + d[2] = (s1[4] + s1[5] + s2[4] + s2[5] + 2) >> 2; + d[3] = (s1[6] + s1[7] + s2[6] + s2[7] + 2) >> 2; + s1 += 8; + s2 += 8; + d += 4; + } + for(;w > 0; w--) { + d[0] = (s1[0] + s1[1] + s2[0] + s2[1] + 2) >> 2; + s1 += 2; + s2 += 2; + d++; + } + src += 2 * src_wrap; + dst += dst_wrap; + } +} + +/* 4x4 -> 1x1 */ +void ff_shrink44(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w; + const uint8_t *s1, *s2, *s3, *s4; + uint8_t *d; + + for(;height > 0; height--) { + s1 = src; + s2 = s1 + src_wrap; + s3 = s2 + src_wrap; + s4 = s3 + src_wrap; + d = dst; + for(w = width;w > 0; w--) { + d[0] = (s1[0] + s1[1] + s1[2] + s1[3] + + s2[0] + s2[1] + s2[2] + s2[3] + + s3[0] + s3[1] + s3[2] + s3[3] + + s4[0] + s4[1] + s4[2] + s4[3] + 8) >> 4; + s1 += 4; + s2 += 4; + s3 += 4; + s4 += 4; + d++; + } + src += 4 * src_wrap; + dst += dst_wrap; + } +} + +/* 8x8 -> 1x1 */ +void ff_shrink88(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w, i; + + for(;height > 0; height--) { + for(w = width;w > 0; w--) { + int tmp=0; + for(i=0; i<8; i++){ + tmp += src[0] + src[1] + src[2] + src[3] + src[4] + src[5] + src[6] + src[7]; + src += src_wrap; + } + *(dst++) = (tmp + 32)>>6; + src += 8 - 8*src_wrap; + } + src += 8*src_wrap - 8*width; + dst += dst_wrap - width; + } +} + +static void grow21_line(uint8_t *dst, const uint8_t *src, + int width) +{ + int w; + const uint8_t *s1; + uint8_t *d; + + s1 = src; + d = dst; + for(w = width;w >= 4; w-=4) { + d[1] = d[0] = s1[0]; + d[3] = d[2] = s1[1]; + s1 += 2; + d += 4; + } + for(;w >= 2; w -= 2) { + d[1] = d[0] = s1[0]; + s1 ++; + d += 2; + } + /* only needed if width is not a multiple of two */ + /* XXX: veryfy that */ + if (w) { + d[0] = s1[0]; + } +} + +static void grow41_line(uint8_t *dst, const uint8_t *src, + int width) +{ + int w, v; + const uint8_t *s1; + uint8_t *d; + + s1 = src; + d = dst; + for(w = width;w >= 4; w-=4) { + v = s1[0]; + d[0] = v; + d[1] = v; + d[2] = v; + d[3] = v; + s1 ++; + d += 4; + } +} + +/* 1x1 -> 2x1 */ +static void grow21(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + for(;height > 0; height--) { + grow21_line(dst, src, width); + src += src_wrap; + dst += dst_wrap; + } +} + +/* 1x1 -> 2x2 */ +static void grow22(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + for(;height > 0; height--) { + grow21_line(dst, src, width); + if (height%2) + src += src_wrap; + dst += dst_wrap; + } +} + +/* 1x1 -> 4x1 */ +static void grow41(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + for(;height > 0; height--) { + grow41_line(dst, src, width); + src += src_wrap; + dst += dst_wrap; + } +} + +/* 1x1 -> 4x4 */ +static void grow44(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + for(;height > 0; height--) { + grow41_line(dst, src, width); + if ((height & 3) == 1) + src += src_wrap; + dst += dst_wrap; + } +} + +/* 1x2 -> 2x1 */ +static void conv411(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height) +{ + int w, c; + const uint8_t *s1, *s2; + uint8_t *d; + + width>>=1; + + for(;height > 0; height--) { + s1 = src; + s2 = src + src_wrap; + d = dst; + for(w = width;w > 0; w--) { + c = (s1[0] + s2[0]) >> 1; + d[0] = c; + d[1] = c; + s1++; + s2++; + d += 2; + } + src += src_wrap * 2; + dst += dst_wrap; + } +} + +/* XXX: add jpeg quantize code */ + +#define TRANSP_INDEX (6*6*6) + +/* this is maybe slow, but allows for extensions */ +static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b) +{ + return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6)); +} + +static void build_rgb_palette(uint8_t *palette, int has_alpha) +{ + uint32_t *pal; + static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff }; + int i, r, g, b; + + pal = (uint32_t *)palette; + i = 0; + for(r = 0; r < 6; r++) { + for(g = 0; g < 6; g++) { + for(b = 0; b < 6; b++) { + pal[i++] = (0xff << 24) | (pal_value[r] << 16) | + (pal_value[g] << 8) | pal_value[b]; + } + } + } + if (has_alpha) + pal[i++] = 0; + while (i < 256) + pal[i++] = 0xff000000; +} + +/* copy bit n to bits 0 ... n - 1 */ +static inline unsigned int bitcopy_n(unsigned int a, int n) +{ + int mask; + mask = (1 << n) - 1; + return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask); +} + +/* rgb555 handling */ + +#define RGB_NAME rgb555 + +#define RGB_IN(r, g, b, s)\ +{\ + unsigned int v = ((const uint16_t *)(s))[0];\ + r = bitcopy_n(v >> (10 - 3), 3);\ + g = bitcopy_n(v >> (5 - 3), 3);\ + b = bitcopy_n(v << 3, 3);\ +} + +#define RGBA_IN(r, g, b, a, s)\ +{\ + unsigned int v = ((const uint16_t *)(s))[0];\ + r = bitcopy_n(v >> (10 - 3), 3);\ + g = bitcopy_n(v >> (5 - 3), 3);\ + b = bitcopy_n(v << 3, 3);\ + a = (-(v >> 15)) & 0xff;\ +} + +#define RGBA_OUT(d, r, g, b, a)\ +{\ + ((uint16_t *)(d))[0] = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3) | \ + ((a << 8) & 0x8000);\ +} + +#define BPP 2 + +#include "imgconvert_template.h" + +/* rgb565 handling */ + +#define RGB_NAME rgb565 + +#define RGB_IN(r, g, b, s)\ +{\ + unsigned int v = ((const uint16_t *)(s))[0];\ + r = bitcopy_n(v >> (11 - 3), 3);\ + g = bitcopy_n(v >> (5 - 2), 2);\ + b = bitcopy_n(v << 3, 3);\ +} + +#define RGB_OUT(d, r, g, b)\ +{\ + ((uint16_t *)(d))[0] = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);\ +} + +#define BPP 2 + +#include "imgconvert_template.h" + +/* bgr24 handling */ + +#define RGB_NAME bgr24 + +#define RGB_IN(r, g, b, s)\ +{\ + b = (s)[0];\ + g = (s)[1];\ + r = (s)[2];\ +} + +#define RGB_OUT(d, r, g, b)\ +{\ + (d)[0] = b;\ + (d)[1] = g;\ + (d)[2] = r;\ +} + +#define BPP 3 + +#include "imgconvert_template.h" + +#undef RGB_IN +#undef RGB_OUT +#undef BPP + +/* rgb24 handling */ + +#define RGB_NAME rgb24 +#define FMT_RGB24 + +#define RGB_IN(r, g, b, s)\ +{\ + r = (s)[0];\ + g = (s)[1];\ + b = (s)[2];\ +} + +#define RGB_OUT(d, r, g, b)\ +{\ + (d)[0] = r;\ + (d)[1] = g;\ + (d)[2] = b;\ +} + +#define BPP 3 + +#include "imgconvert_template.h" + +/* rgba32 handling */ + +#define RGB_NAME rgba32 +#define FMT_RGBA32 + +#define RGB_IN(r, g, b, s)\ +{\ + unsigned int v = ((const uint32_t *)(s))[0];\ + r = (v >> 16) & 0xff;\ + g = (v >> 8) & 0xff;\ + b = v & 0xff;\ +} + +#define RGBA_IN(r, g, b, a, s)\ +{\ + unsigned int v = ((const uint32_t *)(s))[0];\ + a = (v >> 24) & 0xff;\ + r = (v >> 16) & 0xff;\ + g = (v >> 8) & 0xff;\ + b = v & 0xff;\ +} + +#define RGBA_OUT(d, r, g, b, a)\ +{\ + ((uint32_t *)(d))[0] = (a << 24) | (r << 16) | (g << 8) | b;\ +} + +#define BPP 4 + +#include "imgconvert_template.h" + +static void mono_to_gray(AVPicture *dst, const AVPicture *src, + int width, int height, int xor_mask) +{ + const unsigned char *p; + unsigned char *q; + int v, dst_wrap, src_wrap; + int y, w; + + p = src->data[0]; + src_wrap = src->linesize[0] - ((width + 7) >> 3); + + q = dst->data[0]; + dst_wrap = dst->linesize[0] - width; + for(y=0;y= 8) { + v = *p++ ^ xor_mask; + q[0] = -(v >> 7); + q[1] = -((v >> 6) & 1); + q[2] = -((v >> 5) & 1); + q[3] = -((v >> 4) & 1); + q[4] = -((v >> 3) & 1); + q[5] = -((v >> 2) & 1); + q[6] = -((v >> 1) & 1); + q[7] = -((v >> 0) & 1); + w -= 8; + q += 8; + } + if (w > 0) { + v = *p++ ^ xor_mask; + do { + q[0] = -((v >> 7) & 1); + q++; + v <<= 1; + } while (--w); + } + p += src_wrap; + q += dst_wrap; + } +} + +static void monowhite_to_gray(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + mono_to_gray(dst, src, width, height, 0xff); +} + +static void monoblack_to_gray(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + mono_to_gray(dst, src, width, height, 0x00); +} + +static void gray_to_mono(AVPicture *dst, const AVPicture *src, + int width, int height, int xor_mask) +{ + int n; + const uint8_t *s; + uint8_t *d; + int j, b, v, n1, src_wrap, dst_wrap, y; + + s = src->data[0]; + src_wrap = src->linesize[0] - width; + + d = dst->data[0]; + dst_wrap = dst->linesize[0] - ((width + 7) >> 3); + + for(y=0;y= 8) { + v = 0; + for(j=0;j<8;j++) { + b = s[0]; + s++; + v = (v << 1) | (b >> 7); + } + d[0] = v ^ xor_mask; + d++; + n -= 8; + } + if (n > 0) { + n1 = n; + v = 0; + while (n > 0) { + b = s[0]; + s++; + v = (v << 1) | (b >> 7); + n--; + } + d[0] = (v << (8 - (n1 & 7))) ^ xor_mask; + d++; + } + s += src_wrap; + d += dst_wrap; + } +} + +static void gray_to_monowhite(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + gray_to_mono(dst, src, width, height, 0xff); +} + +static void gray_to_monoblack(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + gray_to_mono(dst, src, width, height, 0x00); +} + +typedef struct ConvertEntry { + void (*convert)(AVPicture *dst, + const AVPicture *src, int width, int height); +} ConvertEntry; + +/* Add each new convertion function in this table. In order to be able + to convert from any format to any format, the following constraints + must be satisfied: + + - all FF_COLOR_RGB formats must convert to and from PIX_FMT_RGB24 + + - all FF_COLOR_GRAY formats must convert to and from PIX_FMT_GRAY8 + + - all FF_COLOR_RGB formats with alpha must convert to and from PIX_FMT_RGBA32 + + - PIX_FMT_YUV444P and PIX_FMT_YUVJ444P must convert to and from + PIX_FMT_RGB24. + + - PIX_FMT_422 must convert to and from PIX_FMT_422P. + + The other conversion functions are just optimisations for common cases. +*/ +static ConvertEntry convert_table[PIX_FMT_NB][PIX_FMT_NB] = { + [PIX_FMT_YUV420P] = { + [PIX_FMT_YUV422] = { + .convert = yuv420p_to_yuv422, + }, + [PIX_FMT_RGB555] = { + .convert = yuv420p_to_rgb555 + }, + [PIX_FMT_RGB565] = { + .convert = yuv420p_to_rgb565 + }, + [PIX_FMT_BGR24] = { + .convert = yuv420p_to_bgr24 + }, + [PIX_FMT_RGB24] = { + .convert = yuv420p_to_rgb24 + }, + [PIX_FMT_RGBA32] = { + .convert = yuv420p_to_rgba32 + }, + [PIX_FMT_UYVY422] = { + .convert = yuv420p_to_uyvy422, + }, + }, + [PIX_FMT_YUV422P] = { + [PIX_FMT_YUV422] = { + .convert = yuv422p_to_yuv422, + }, + [PIX_FMT_UYVY422] = { + .convert = yuv422p_to_uyvy422, + }, + }, + [PIX_FMT_YUV444P] = { + [PIX_FMT_RGB24] = { + .convert = yuv444p_to_rgb24 + }, + }, + [PIX_FMT_YUVJ420P] = { + [PIX_FMT_RGB555] = { + .convert = yuvj420p_to_rgb555 + }, + [PIX_FMT_RGB565] = { + .convert = yuvj420p_to_rgb565 + }, + [PIX_FMT_BGR24] = { + .convert = yuvj420p_to_bgr24 + }, + [PIX_FMT_RGB24] = { + .convert = yuvj420p_to_rgb24 + }, + [PIX_FMT_RGBA32] = { + .convert = yuvj420p_to_rgba32 + }, + }, + [PIX_FMT_YUVJ444P] = { + [PIX_FMT_RGB24] = { + .convert = yuvj444p_to_rgb24 + }, + }, + [PIX_FMT_YUV422] = { + [PIX_FMT_YUV420P] = { + .convert = yuv422_to_yuv420p, + }, + [PIX_FMT_YUV422P] = { + .convert = yuv422_to_yuv422p, + }, + }, + [PIX_FMT_UYVY422] = { + [PIX_FMT_YUV420P] = { + .convert = uyvy422_to_yuv420p, + }, + [PIX_FMT_YUV422P] = { + .convert = uyvy422_to_yuv422p, + }, + }, + [PIX_FMT_RGB24] = { + [PIX_FMT_YUV420P] = { + .convert = rgb24_to_yuv420p + }, + [PIX_FMT_RGB565] = { + .convert = rgb24_to_rgb565 + }, + [PIX_FMT_RGB555] = { + .convert = rgb24_to_rgb555 + }, + [PIX_FMT_RGBA32] = { + .convert = rgb24_to_rgba32 + }, + [PIX_FMT_BGR24] = { + .convert = rgb24_to_bgr24 + }, + [PIX_FMT_GRAY8] = { + .convert = rgb24_to_gray + }, + [PIX_FMT_PAL8] = { + .convert = rgb24_to_pal8 + }, + [PIX_FMT_YUV444P] = { + .convert = rgb24_to_yuv444p + }, + [PIX_FMT_YUVJ420P] = { + .convert = rgb24_to_yuvj420p + }, + [PIX_FMT_YUVJ444P] = { + .convert = rgb24_to_yuvj444p + }, + }, + [PIX_FMT_RGBA32] = { + [PIX_FMT_RGB24] = { + .convert = rgba32_to_rgb24 + }, + [PIX_FMT_RGB555] = { + .convert = rgba32_to_rgb555 + }, + [PIX_FMT_PAL8] = { + .convert = rgba32_to_pal8 + }, + [PIX_FMT_YUV420P] = { + .convert = rgba32_to_yuv420p + }, + [PIX_FMT_GRAY8] = { + .convert = rgba32_to_gray + }, + }, + [PIX_FMT_BGR24] = { + [PIX_FMT_RGB24] = { + .convert = bgr24_to_rgb24 + }, + [PIX_FMT_YUV420P] = { + .convert = bgr24_to_yuv420p + }, + [PIX_FMT_GRAY8] = { + .convert = bgr24_to_gray + }, + }, + [PIX_FMT_RGB555] = { + [PIX_FMT_RGB24] = { + .convert = rgb555_to_rgb24 + }, + [PIX_FMT_RGBA32] = { + .convert = rgb555_to_rgba32 + }, + [PIX_FMT_YUV420P] = { + .convert = rgb555_to_yuv420p + }, + [PIX_FMT_GRAY8] = { + .convert = rgb555_to_gray + }, + }, + [PIX_FMT_RGB565] = { + [PIX_FMT_RGB24] = { + .convert = rgb565_to_rgb24 + }, + [PIX_FMT_YUV420P] = { + .convert = rgb565_to_yuv420p + }, + [PIX_FMT_GRAY8] = { + .convert = rgb565_to_gray + }, + }, + [PIX_FMT_GRAY8] = { + [PIX_FMT_RGB555] = { + .convert = gray_to_rgb555 + }, + [PIX_FMT_RGB565] = { + .convert = gray_to_rgb565 + }, + [PIX_FMT_RGB24] = { + .convert = gray_to_rgb24 + }, + [PIX_FMT_BGR24] = { + .convert = gray_to_bgr24 + }, + [PIX_FMT_RGBA32] = { + .convert = gray_to_rgba32 + }, + [PIX_FMT_MONOWHITE] = { + .convert = gray_to_monowhite + }, + [PIX_FMT_MONOBLACK] = { + .convert = gray_to_monoblack + }, + }, + [PIX_FMT_MONOWHITE] = { + [PIX_FMT_GRAY8] = { + .convert = monowhite_to_gray + }, + }, + [PIX_FMT_MONOBLACK] = { + [PIX_FMT_GRAY8] = { + .convert = monoblack_to_gray + }, + }, + [PIX_FMT_PAL8] = { + [PIX_FMT_RGB555] = { + .convert = pal8_to_rgb555 + }, + [PIX_FMT_RGB565] = { + .convert = pal8_to_rgb565 + }, + [PIX_FMT_BGR24] = { + .convert = pal8_to_bgr24 + }, + [PIX_FMT_RGB24] = { + .convert = pal8_to_rgb24 + }, + [PIX_FMT_RGBA32] = { + .convert = pal8_to_rgba32 + }, + }, + [PIX_FMT_UYVY411] = { + [PIX_FMT_YUV411P] = { + .convert = uyvy411_to_yuv411p, + }, + }, + +}; + +int avpicture_alloc(AVPicture *picture, + int pix_fmt, int width, int height) +{ + int size; + void *ptr; + + size = avpicture_get_size(pix_fmt, width, height); + if(size<0) + goto fail; + ptr = av_malloc(size); + if (!ptr) + goto fail; + avpicture_fill(picture, ptr, pix_fmt, width, height); + return 0; + fail: + memset(picture, 0, sizeof(AVPicture)); + return -1; +} + +void avpicture_free(AVPicture *picture) +{ + av_free(picture->data[0]); +} + +/* return true if yuv planar */ +static inline int is_yuv_planar(PixFmtInfo *ps) +{ + return (ps->color_type == FF_COLOR_YUV || + ps->color_type == FF_COLOR_YUV_JPEG) && + ps->pixel_type == FF_PIXEL_PLANAR; +} + +/** + * Crop image top and left side + */ +int img_crop(AVPicture *dst, const AVPicture *src, + int pix_fmt, int top_band, int left_band) +{ + int y_shift; + int x_shift; + + if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt])) + return -1; + + y_shift = pix_fmt_info[pix_fmt].y_chroma_shift; + x_shift = pix_fmt_info[pix_fmt].x_chroma_shift; + + dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band; + dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift); + dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift); + + dst->linesize[0] = src->linesize[0]; + dst->linesize[1] = src->linesize[1]; + dst->linesize[2] = src->linesize[2]; + return 0; +} + +/** + * Pad image + */ +int img_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, + int padtop, int padbottom, int padleft, int padright, int *color) +{ + uint8_t *optr, *iptr; + int y_shift; + int x_shift; + int yheight; + int i, y; + + if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt])) + return -1; + + for (i = 0; i < 3; i++) { + x_shift = i ? pix_fmt_info[pix_fmt].x_chroma_shift : 0; + y_shift = i ? pix_fmt_info[pix_fmt].y_chroma_shift : 0; + + if (padtop || padleft) { + memset(dst->data[i], color[i], dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift)); + } + + if (padleft || padright || src) { + if (src) { /* first line */ + iptr = src->data[i]; + optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (padleft >> x_shift); + memcpy(optr, iptr, src->linesize[i]); + iptr += src->linesize[i]; + } + optr = dst->data[i] + dst->linesize[i] * (padtop >> y_shift) + (dst->linesize[i] - (padright >> x_shift)); + yheight = (height - 1 - (padtop + padbottom)) >> y_shift; + for (y = 0; y < yheight; y++) { + memset(optr, color[i], (padleft + padright) >> x_shift); + if (src) { + memcpy(optr + ((padleft + padright) >> x_shift), iptr, src->linesize[i]); + iptr += src->linesize[i]; + } + optr += dst->linesize[i]; + } + } + + if (padbottom || padright) { + optr = dst->data[i] + dst->linesize[i] * ((height - padbottom) >> y_shift) - (padright >> x_shift); + memset(optr, color[i], dst->linesize[i] * (padbottom >> y_shift) + (padright >> x_shift)); + } + } + return 0; +} + +/* XXX: always use linesize. Return -1 if not supported */ +int img_convert(AVPicture *dst, int dst_pix_fmt, + const AVPicture *src, int src_pix_fmt, + int src_width, int src_height) +{ + static int inited; + int i, ret, dst_width, dst_height, int_pix_fmt; + PixFmtInfo *src_pix, *dst_pix; + ConvertEntry *ce; + AVPicture tmp1, *tmp = &tmp1; + + if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB || + dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB) + return -1; + if (src_width <= 0 || src_height <= 0) + return 0; + + if (!inited) { + inited = 1; + img_convert_init(); + } + + dst_width = src_width; + dst_height = src_height; + + dst_pix = &pix_fmt_info[dst_pix_fmt]; + src_pix = &pix_fmt_info[src_pix_fmt]; + if (src_pix_fmt == dst_pix_fmt) { + /* no conversion needed: just copy */ + img_copy(dst, src, dst_pix_fmt, dst_width, dst_height); + return 0; + } + + ce = &convert_table[src_pix_fmt][dst_pix_fmt]; + if (ce->convert) { + /* specific conversion routine */ + ce->convert(dst, src, dst_width, dst_height); + return 0; + } + + /* gray to YUV */ + if (is_yuv_planar(dst_pix) && + src_pix_fmt == PIX_FMT_GRAY8) { + int w, h, y; + uint8_t *d; + + if (dst_pix->color_type == FF_COLOR_YUV_JPEG) { + ff_img_copy_plane(dst->data[0], dst->linesize[0], + src->data[0], src->linesize[0], + dst_width, dst_height); + } else { + img_apply_table(dst->data[0], dst->linesize[0], + src->data[0], src->linesize[0], + dst_width, dst_height, + y_jpeg_to_ccir); + } + /* fill U and V with 128 */ + w = dst_width; + h = dst_height; + w >>= dst_pix->x_chroma_shift; + h >>= dst_pix->y_chroma_shift; + for(i = 1; i <= 2; i++) { + d = dst->data[i]; + for(y = 0; y< h; y++) { + memset(d, 128, w); + d += dst->linesize[i]; + } + } + return 0; + } + + /* YUV to gray */ + if (is_yuv_planar(src_pix) && + dst_pix_fmt == PIX_FMT_GRAY8) { + if (src_pix->color_type == FF_COLOR_YUV_JPEG) { + ff_img_copy_plane(dst->data[0], dst->linesize[0], + src->data[0], src->linesize[0], + dst_width, dst_height); + } else { + img_apply_table(dst->data[0], dst->linesize[0], + src->data[0], src->linesize[0], + dst_width, dst_height, + y_ccir_to_jpeg); + } + return 0; + } + + /* YUV to YUV planar */ + if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) { + int x_shift, y_shift, w, h, xy_shift; + void (*resize_func)(uint8_t *dst, int dst_wrap, + const uint8_t *src, int src_wrap, + int width, int height); + + /* compute chroma size of the smallest dimensions */ + w = dst_width; + h = dst_height; + if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift) + w >>= dst_pix->x_chroma_shift; + else + w >>= src_pix->x_chroma_shift; + if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift) + h >>= dst_pix->y_chroma_shift; + else + h >>= src_pix->y_chroma_shift; + + x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift); + y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift); + xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf); + /* there must be filters for conversion at least from and to + YUV444 format */ + switch(xy_shift) { + case 0x00: + resize_func = ff_img_copy_plane; + break; + case 0x10: + resize_func = shrink21; + break; + case 0x20: + resize_func = shrink41; + break; + case 0x01: + resize_func = shrink12; + break; + case 0x11: + resize_func = ff_shrink22; + break; + case 0x22: + resize_func = ff_shrink44; + break; + case 0xf0: + resize_func = grow21; + break; + case 0xe0: + resize_func = grow41; + break; + case 0xff: + resize_func = grow22; + break; + case 0xee: + resize_func = grow44; + break; + case 0xf1: + resize_func = conv411; + break; + default: + /* currently not handled */ + goto no_chroma_filter; + } + + ff_img_copy_plane(dst->data[0], dst->linesize[0], + src->data[0], src->linesize[0], + dst_width, dst_height); + + for(i = 1;i <= 2; i++) + resize_func(dst->data[i], dst->linesize[i], + src->data[i], src->linesize[i], + dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift); + /* if yuv color space conversion is needed, we do it here on + the destination image */ + if (dst_pix->color_type != src_pix->color_type) { + const uint8_t *y_table, *c_table; + if (dst_pix->color_type == FF_COLOR_YUV) { + y_table = y_jpeg_to_ccir; + c_table = c_jpeg_to_ccir; + } else { + y_table = y_ccir_to_jpeg; + c_table = c_ccir_to_jpeg; + } + img_apply_table(dst->data[0], dst->linesize[0], + dst->data[0], dst->linesize[0], + dst_width, dst_height, + y_table); + + for(i = 1;i <= 2; i++) + img_apply_table(dst->data[i], dst->linesize[i], + dst->data[i], dst->linesize[i], + dst_width>>dst_pix->x_chroma_shift, + dst_height>>dst_pix->y_chroma_shift, + c_table); + } + return 0; + } + no_chroma_filter: + + /* try to use an intermediate format */ + if (src_pix_fmt == PIX_FMT_YUV422 || + dst_pix_fmt == PIX_FMT_YUV422) { + /* specific case: convert to YUV422P first */ + int_pix_fmt = PIX_FMT_YUV422P; + } else if (src_pix_fmt == PIX_FMT_UYVY422 || + dst_pix_fmt == PIX_FMT_UYVY422) { + /* specific case: convert to YUV422P first */ + int_pix_fmt = PIX_FMT_YUV422P; + } else if (src_pix_fmt == PIX_FMT_UYVY411 || + dst_pix_fmt == PIX_FMT_UYVY411) { + /* specific case: convert to YUV411P first */ + int_pix_fmt = PIX_FMT_YUV411P; + } else if ((src_pix->color_type == FF_COLOR_GRAY && + src_pix_fmt != PIX_FMT_GRAY8) || + (dst_pix->color_type == FF_COLOR_GRAY && + dst_pix_fmt != PIX_FMT_GRAY8)) { + /* gray8 is the normalized format */ + int_pix_fmt = PIX_FMT_GRAY8; + } else if ((is_yuv_planar(src_pix) && + src_pix_fmt != PIX_FMT_YUV444P && + src_pix_fmt != PIX_FMT_YUVJ444P)) { + /* yuv444 is the normalized format */ + if (src_pix->color_type == FF_COLOR_YUV_JPEG) + int_pix_fmt = PIX_FMT_YUVJ444P; + else + int_pix_fmt = PIX_FMT_YUV444P; + } else if ((is_yuv_planar(dst_pix) && + dst_pix_fmt != PIX_FMT_YUV444P && + dst_pix_fmt != PIX_FMT_YUVJ444P)) { + /* yuv444 is the normalized format */ + if (dst_pix->color_type == FF_COLOR_YUV_JPEG) + int_pix_fmt = PIX_FMT_YUVJ444P; + else + int_pix_fmt = PIX_FMT_YUV444P; + } else { + /* the two formats are rgb or gray8 or yuv[j]444p */ + if (src_pix->is_alpha && dst_pix->is_alpha) + int_pix_fmt = PIX_FMT_RGBA32; + else + int_pix_fmt = PIX_FMT_RGB24; + } + if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0) + return -1; + ret = -1; + if (img_convert(tmp, int_pix_fmt, + src, src_pix_fmt, src_width, src_height) < 0) + goto fail1; + if (img_convert(dst, dst_pix_fmt, + tmp, int_pix_fmt, dst_width, dst_height) < 0) + goto fail1; + ret = 0; + fail1: + avpicture_free(tmp); + return ret; +} + +/* NOTE: we scan all the pixels to have an exact information */ +static int get_alpha_info_pal8(const AVPicture *src, int width, int height) +{ + const unsigned char *p; + int src_wrap, ret, x, y; + unsigned int a; + uint32_t *palette = (uint32_t *)src->data[1]; + + p = src->data[0]; + src_wrap = src->linesize[0] - width; + ret = 0; + for(y=0;y> 24; + if (a == 0x00) { + ret |= FF_ALPHA_TRANSP; + } else if (a != 0xff) { + ret |= FF_ALPHA_SEMI_TRANSP; + } + p++; + } + p += src_wrap; + } + return ret; +} + +/** + * Tell if an image really has transparent alpha values. + * @return ored mask of FF_ALPHA_xxx constants + */ +int img_get_alpha_info(const AVPicture *src, + int pix_fmt, int width, int height) +{ + PixFmtInfo *pf = &pix_fmt_info[pix_fmt]; + int ret; + + pf = &pix_fmt_info[pix_fmt]; + /* no alpha can be represented in format */ + if (!pf->is_alpha) + return 0; + switch(pix_fmt) { + case PIX_FMT_RGBA32: + ret = get_alpha_info_rgba32(src, width, height); + break; + case PIX_FMT_RGB555: + ret = get_alpha_info_rgb555(src, width, height); + break; + case PIX_FMT_PAL8: + ret = get_alpha_info_pal8(src, width, height); + break; + default: + /* we do not know, so everything is indicated */ + ret = FF_ALPHA_TRANSP | FF_ALPHA_SEMI_TRANSP; + break; + } + return ret; +} + +#ifdef HAVE_MMX +#define DEINT_INPLACE_LINE_LUM \ + movd_m2r(lum_m4[0],mm0);\ + movd_m2r(lum_m3[0],mm1);\ + movd_m2r(lum_m2[0],mm2);\ + movd_m2r(lum_m1[0],mm3);\ + movd_m2r(lum[0],mm4);\ + punpcklbw_r2r(mm7,mm0);\ + movd_r2m(mm2,lum_m4[0]);\ + punpcklbw_r2r(mm7,mm1);\ + punpcklbw_r2r(mm7,mm2);\ + punpcklbw_r2r(mm7,mm3);\ + punpcklbw_r2r(mm7,mm4);\ + paddw_r2r(mm3,mm1);\ + psllw_i2r(1,mm2);\ + paddw_r2r(mm4,mm0);\ + psllw_i2r(2,mm1);\ + paddw_r2r(mm6,mm2);\ + paddw_r2r(mm2,mm1);\ + psubusw_r2r(mm0,mm1);\ + psrlw_i2r(3,mm1);\ + packuswb_r2r(mm7,mm1);\ + movd_r2m(mm1,lum_m2[0]); + +#define DEINT_LINE_LUM \ + movd_m2r(lum_m4[0],mm0);\ + movd_m2r(lum_m3[0],mm1);\ + movd_m2r(lum_m2[0],mm2);\ + movd_m2r(lum_m1[0],mm3);\ + movd_m2r(lum[0],mm4);\ + punpcklbw_r2r(mm7,mm0);\ + punpcklbw_r2r(mm7,mm1);\ + punpcklbw_r2r(mm7,mm2);\ + punpcklbw_r2r(mm7,mm3);\ + punpcklbw_r2r(mm7,mm4);\ + paddw_r2r(mm3,mm1);\ + psllw_i2r(1,mm2);\ + paddw_r2r(mm4,mm0);\ + psllw_i2r(2,mm1);\ + paddw_r2r(mm6,mm2);\ + paddw_r2r(mm2,mm1);\ + psubusw_r2r(mm0,mm1);\ + psrlw_i2r(3,mm1);\ + packuswb_r2r(mm7,mm1);\ + movd_r2m(mm1,dst[0]); +#endif + +/* filter parameters: [-1 4 2 4 -1] // 8 */ +static void deinterlace_line(uint8_t *dst, + const uint8_t *lum_m4, const uint8_t *lum_m3, + const uint8_t *lum_m2, const uint8_t *lum_m1, + const uint8_t *lum, + int size) +{ +#ifndef HAVE_MMX + uint8_t *cm = cropTbl + MAX_NEG_CROP; + int sum; + + for(;size > 0;size--) { + sum = -lum_m4[0]; + sum += lum_m3[0] << 2; + sum += lum_m2[0] << 1; + sum += lum_m1[0] << 2; + sum += -lum[0]; + dst[0] = cm[(sum + 4) >> 3]; + lum_m4++; + lum_m3++; + lum_m2++; + lum_m1++; + lum++; + dst++; + } +#else + + { + mmx_t rounder; + rounder.uw[0]=4; + rounder.uw[1]=4; + rounder.uw[2]=4; + rounder.uw[3]=4; + pxor_r2r(mm7,mm7); + movq_m2r(rounder,mm6); + } + for (;size > 3; size-=4) { + DEINT_LINE_LUM + lum_m4+=4; + lum_m3+=4; + lum_m2+=4; + lum_m1+=4; + lum+=4; + dst+=4; + } +#endif +} +static void deinterlace_line_inplace(uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, + int size) +{ +#ifndef HAVE_MMX + uint8_t *cm = cropTbl + MAX_NEG_CROP; + int sum; + + for(;size > 0;size--) { + sum = -lum_m4[0]; + sum += lum_m3[0] << 2; + sum += lum_m2[0] << 1; + lum_m4[0]=lum_m2[0]; + sum += lum_m1[0] << 2; + sum += -lum[0]; + lum_m2[0] = cm[(sum + 4) >> 3]; + lum_m4++; + lum_m3++; + lum_m2++; + lum_m1++; + lum++; + } +#else + + { + mmx_t rounder; + rounder.uw[0]=4; + rounder.uw[1]=4; + rounder.uw[2]=4; + rounder.uw[3]=4; + pxor_r2r(mm7,mm7); + movq_m2r(rounder,mm6); + } + for (;size > 3; size-=4) { + DEINT_INPLACE_LINE_LUM + lum_m4+=4; + lum_m3+=4; + lum_m2+=4; + lum_m1+=4; + lum+=4; + } +#endif +} + +/* deinterlacing : 2 temporal taps, 3 spatial taps linear filter. The + top field is copied as is, but the bottom field is deinterlaced + against the top field. */ +static void deinterlace_bottom_field(uint8_t *dst, int dst_wrap, + const uint8_t *src1, int src_wrap, + int width, int height) +{ + const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2; + int y; + + src_m2 = src1; + src_m1 = src1; + src_0=&src_m1[src_wrap]; + src_p1=&src_0[src_wrap]; + src_p2=&src_p1[src_wrap]; + for(y=0;y<(height-2);y+=2) { + memcpy(dst,src_m1,width); + dst += dst_wrap; + deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width); + src_m2 = src_0; + src_m1 = src_p1; + src_0 = src_p2; + src_p1 += 2*src_wrap; + src_p2 += 2*src_wrap; + dst += dst_wrap; + } + memcpy(dst,src_m1,width); + dst += dst_wrap; + /* do last line */ + deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width); +} + +static void deinterlace_bottom_field_inplace(uint8_t *src1, int src_wrap, + int width, int height) +{ + uint8_t *src_m1, *src_0, *src_p1, *src_p2; + int y; + uint8_t *buf; + buf = (uint8_t*)av_malloc(width); + + src_m1 = src1; + memcpy(buf,src_m1,width); + src_0=&src_m1[src_wrap]; + src_p1=&src_0[src_wrap]; + src_p2=&src_p1[src_wrap]; + for(y=0;y<(height-2);y+=2) { + deinterlace_line_inplace(buf,src_m1,src_0,src_p1,src_p2,width); + src_m1 = src_p1; + src_0 = src_p2; + src_p1 += 2*src_wrap; + src_p2 += 2*src_wrap; + } + /* do last line */ + deinterlace_line_inplace(buf,src_m1,src_0,src_0,src_0,width); + av_free(buf); +} + + +/* deinterlace - if not supported return -1 */ +int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, + int pix_fmt, int width, int height) +{ + int i; + + if (pix_fmt != PIX_FMT_YUV420P && + pix_fmt != PIX_FMT_YUV422P && + pix_fmt != PIX_FMT_YUV444P && + pix_fmt != PIX_FMT_YUV411P) + return -1; + if ((width & 3) != 0 || (height & 3) != 0) + return -1; + + for(i=0;i<3;i++) { + if (i == 1) { + switch(pix_fmt) { + case PIX_FMT_YUV420P: + width >>= 1; + height >>= 1; + break; + case PIX_FMT_YUV422P: + width >>= 1; + break; + case PIX_FMT_YUV411P: + width >>= 2; + break; + default: + break; + } + } + if (src == dst) { + deinterlace_bottom_field_inplace(dst->data[i], dst->linesize[i], + width, height); + } else { + deinterlace_bottom_field(dst->data[i],dst->linesize[i], + src->data[i], src->linesize[i], + width, height); + } + } +#ifdef HAVE_MMX + emms(); +#endif + return 0; +} + +#undef FIX diff --git a/mpeg4/src/libavcodec/imgconvert_template.h b/mpeg4/src/libavcodec/imgconvert_template.h new file mode 100644 index 00000000..e58b0cae --- /dev/null +++ b/mpeg4/src/libavcodec/imgconvert_template.h @@ -0,0 +1,857 @@ +/* + * Templates for image convertion routines + * Copyright (c) 2001, 2002, 2003 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RGB_OUT +#define RGB_OUT(d, r, g, b) RGBA_OUT(d, r, g, b, 0xff) +#endif + +static void glue(yuv420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr; + uint8_t *d, *d1, *d2; + int w, y, cb, cr, r_add, g_add, b_add, width2; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + unsigned int r, g, b; + + d = dst->data[0]; + y1_ptr = src->data[0]; + cb_ptr = src->data[1]; + cr_ptr = src->data[2]; + width2 = (width + 1) >> 1; + for(;height >= 2; height -= 2) { + d1 = d; + d2 = d + dst->linesize[0]; + y2_ptr = y1_ptr + src->linesize[0]; + for(w = width; w >= 2; w -= 2) { + YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); + /* output 4 pixels */ + YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + + YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]); + RGB_OUT(d1 + BPP, r, g, b); + + YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]); + RGB_OUT(d2, r, g, b); + + YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[1]); + RGB_OUT(d2 + BPP, r, g, b); + + d1 += 2 * BPP; + d2 += 2 * BPP; + + y1_ptr += 2; + y2_ptr += 2; + cb_ptr++; + cr_ptr++; + } + /* handle odd width */ + if (w) { + YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); + YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + + YUV_TO_RGB2_CCIR(r, g, b, y2_ptr[0]); + RGB_OUT(d2, r, g, b); + d1 += BPP; + d2 += BPP; + y1_ptr++; + y2_ptr++; + cb_ptr++; + cr_ptr++; + } + d += 2 * dst->linesize[0]; + y1_ptr += 2 * src->linesize[0] - width; + cb_ptr += src->linesize[1] - width2; + cr_ptr += src->linesize[2] - width2; + } + /* handle odd height */ + if (height) { + d1 = d; + for(w = width; w >= 2; w -= 2) { + YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); + /* output 2 pixels */ + YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + + YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[1]); + RGB_OUT(d1 + BPP, r, g, b); + + d1 += 2 * BPP; + + y1_ptr += 2; + cb_ptr++; + cr_ptr++; + } + /* handle width */ + if (w) { + YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); + /* output 2 pixels */ + YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + d1 += BPP; + + y1_ptr++; + cb_ptr++; + cr_ptr++; + } + } +} + +static void glue(yuvj420p_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *y1_ptr, *y2_ptr, *cb_ptr, *cr_ptr; + uint8_t *d, *d1, *d2; + int w, y, cb, cr, r_add, g_add, b_add, width2; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + unsigned int r, g, b; + + d = dst->data[0]; + y1_ptr = src->data[0]; + cb_ptr = src->data[1]; + cr_ptr = src->data[2]; + width2 = (width + 1) >> 1; + for(;height >= 2; height -= 2) { + d1 = d; + d2 = d + dst->linesize[0]; + y2_ptr = y1_ptr + src->linesize[0]; + for(w = width; w >= 2; w -= 2) { + YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]); + /* output 4 pixels */ + YUV_TO_RGB2(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + + YUV_TO_RGB2(r, g, b, y1_ptr[1]); + RGB_OUT(d1 + BPP, r, g, b); + + YUV_TO_RGB2(r, g, b, y2_ptr[0]); + RGB_OUT(d2, r, g, b); + + YUV_TO_RGB2(r, g, b, y2_ptr[1]); + RGB_OUT(d2 + BPP, r, g, b); + + d1 += 2 * BPP; + d2 += 2 * BPP; + + y1_ptr += 2; + y2_ptr += 2; + cb_ptr++; + cr_ptr++; + } + /* handle odd width */ + if (w) { + YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]); + YUV_TO_RGB2(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + + YUV_TO_RGB2(r, g, b, y2_ptr[0]); + RGB_OUT(d2, r, g, b); + d1 += BPP; + d2 += BPP; + y1_ptr++; + y2_ptr++; + cb_ptr++; + cr_ptr++; + } + d += 2 * dst->linesize[0]; + y1_ptr += 2 * src->linesize[0] - width; + cb_ptr += src->linesize[1] - width2; + cr_ptr += src->linesize[2] - width2; + } + /* handle odd height */ + if (height) { + d1 = d; + for(w = width; w >= 2; w -= 2) { + YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]); + /* output 2 pixels */ + YUV_TO_RGB2(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + + YUV_TO_RGB2(r, g, b, y1_ptr[1]); + RGB_OUT(d1 + BPP, r, g, b); + + d1 += 2 * BPP; + + y1_ptr += 2; + cb_ptr++; + cr_ptr++; + } + /* handle width */ + if (w) { + YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]); + /* output 2 pixels */ + YUV_TO_RGB2(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + d1 += BPP; + + y1_ptr++; + cb_ptr++; + cr_ptr++; + } + } +} + +static void glue(RGB_NAME, _to_yuv420p)(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + int wrap, wrap3, width2; + int r, g, b, r1, g1, b1, w; + uint8_t *lum, *cb, *cr; + const uint8_t *p; + + lum = dst->data[0]; + cb = dst->data[1]; + cr = dst->data[2]; + + width2 = (width + 1) >> 1; + wrap = dst->linesize[0]; + wrap3 = src->linesize[0]; + p = src->data[0]; + for(;height>=2;height -= 2) { + for(w = width; w >= 2; w -= 2) { + RGB_IN(r, g, b, p); + r1 = r; + g1 = g; + b1 = b; + lum[0] = RGB_TO_Y_CCIR(r, g, b); + + RGB_IN(r, g, b, p + BPP); + r1 += r; + g1 += g; + b1 += b; + lum[1] = RGB_TO_Y_CCIR(r, g, b); + p += wrap3; + lum += wrap; + + RGB_IN(r, g, b, p); + r1 += r; + g1 += g; + b1 += b; + lum[0] = RGB_TO_Y_CCIR(r, g, b); + + RGB_IN(r, g, b, p + BPP); + r1 += r; + g1 += g; + b1 += b; + lum[1] = RGB_TO_Y_CCIR(r, g, b); + + cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 2); + cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 2); + + cb++; + cr++; + p += -wrap3 + 2 * BPP; + lum += -wrap + 2; + } + if (w) { + RGB_IN(r, g, b, p); + r1 = r; + g1 = g; + b1 = b; + lum[0] = RGB_TO_Y_CCIR(r, g, b); + p += wrap3; + lum += wrap; + RGB_IN(r, g, b, p); + r1 += r; + g1 += g; + b1 += b; + lum[0] = RGB_TO_Y_CCIR(r, g, b); + cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1); + cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1); + cb++; + cr++; + p += -wrap3 + BPP; + lum += -wrap + 1; + } + p += wrap3 + (wrap3 - width * BPP); + lum += wrap + (wrap - width); + cb += dst->linesize[1] - width2; + cr += dst->linesize[2] - width2; + } + /* handle odd height */ + if (height) { + for(w = width; w >= 2; w -= 2) { + RGB_IN(r, g, b, p); + r1 = r; + g1 = g; + b1 = b; + lum[0] = RGB_TO_Y_CCIR(r, g, b); + + RGB_IN(r, g, b, p + BPP); + r1 += r; + g1 += g; + b1 += b; + lum[1] = RGB_TO_Y_CCIR(r, g, b); + cb[0] = RGB_TO_U_CCIR(r1, g1, b1, 1); + cr[0] = RGB_TO_V_CCIR(r1, g1, b1, 1); + cb++; + cr++; + p += 2 * BPP; + lum += 2; + } + if (w) { + RGB_IN(r, g, b, p); + lum[0] = RGB_TO_Y_CCIR(r, g, b); + cb[0] = RGB_TO_U_CCIR(r, g, b, 0); + cr[0] = RGB_TO_V_CCIR(r, g, b, 0); + } + } +} + +static void glue(RGB_NAME, _to_gray)(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const unsigned char *p; + unsigned char *q; + int r, g, b, dst_wrap, src_wrap; + int x, y; + + p = src->data[0]; + src_wrap = src->linesize[0] - BPP * width; + + q = dst->data[0]; + dst_wrap = dst->linesize[0] - width; + + for(y=0;ydata[0]; + src_wrap = src->linesize[0] - width; + + q = dst->data[0]; + dst_wrap = dst->linesize[0] - BPP * width; + + for(y=0;ydata[0]; + src_wrap = src->linesize[0] - width; + palette = (uint32_t *)src->data[1]; + + q = dst->data[0]; + dst_wrap = dst->linesize[0] - BPP * width; + + for(y=0;y> 16) & 0xff; + g = (v >> 8) & 0xff; + b = (v) & 0xff; +#ifdef RGBA_OUT + { + int a; + a = (v >> 24) & 0xff; + RGBA_OUT(q, r, g, b, a); + } +#else + RGB_OUT(q, r, g, b); +#endif + q += BPP; + p ++; + } + p += src_wrap; + q += dst_wrap; + } +} + +#if !defined(FMT_RGBA32) && defined(RGBA_OUT) +/* alpha support */ + +static void glue(rgba32_to_, RGB_NAME)(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *s; + uint8_t *d; + int src_wrap, dst_wrap, j, y; + unsigned int v, r, g, b, a; + + s = src->data[0]; + src_wrap = src->linesize[0] - width * 4; + + d = dst->data[0]; + dst_wrap = dst->linesize[0] - width * BPP; + + for(y=0;y> 24) & 0xff; + r = (v >> 16) & 0xff; + g = (v >> 8) & 0xff; + b = v & 0xff; + RGBA_OUT(d, r, g, b, a); + s += 4; + d += BPP; + } + s += src_wrap; + d += dst_wrap; + } +} + +static void glue(RGB_NAME, _to_rgba32)(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *s; + uint8_t *d; + int src_wrap, dst_wrap, j, y; + unsigned int r, g, b, a; + + s = src->data[0]; + src_wrap = src->linesize[0] - width * BPP; + + d = dst->data[0]; + dst_wrap = dst->linesize[0] - width * 4; + + for(y=0;ydata[0]; + src_wrap = src->linesize[0] - width * 3; + + d = dst->data[0]; + dst_wrap = dst->linesize[0] - width * BPP; + + for(y=0;ydata[0]; + src_wrap = src->linesize[0] - width * BPP; + + d = dst->data[0]; + dst_wrap = dst->linesize[0] - width * 3; + + for(y=0;ydata[0]; + y1_ptr = src->data[0]; + cb_ptr = src->data[1]; + cr_ptr = src->data[2]; + for(;height > 0; height --) { + d1 = d; + for(w = width; w > 0; w--) { + YUV_TO_RGB1_CCIR(cb_ptr[0], cr_ptr[0]); + + YUV_TO_RGB2_CCIR(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + d1 += BPP; + + y1_ptr++; + cb_ptr++; + cr_ptr++; + } + d += dst->linesize[0]; + y1_ptr += src->linesize[0] - width; + cb_ptr += src->linesize[1] - width; + cr_ptr += src->linesize[2] - width; + } +} + +static void yuvj444p_to_rgb24(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const uint8_t *y1_ptr, *cb_ptr, *cr_ptr; + uint8_t *d, *d1; + int w, y, cb, cr, r_add, g_add, b_add; + uint8_t *cm = cropTbl + MAX_NEG_CROP; + unsigned int r, g, b; + + d = dst->data[0]; + y1_ptr = src->data[0]; + cb_ptr = src->data[1]; + cr_ptr = src->data[2]; + for(;height > 0; height --) { + d1 = d; + for(w = width; w > 0; w--) { + YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]); + + YUV_TO_RGB2(r, g, b, y1_ptr[0]); + RGB_OUT(d1, r, g, b); + d1 += BPP; + + y1_ptr++; + cb_ptr++; + cr_ptr++; + } + d += dst->linesize[0]; + y1_ptr += src->linesize[0] - width; + cb_ptr += src->linesize[1] - width; + cr_ptr += src->linesize[2] - width; + } +} + +static void rgb24_to_yuv444p(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + int src_wrap, x, y; + int r, g, b; + uint8_t *lum, *cb, *cr; + const uint8_t *p; + + lum = dst->data[0]; + cb = dst->data[1]; + cr = dst->data[2]; + + src_wrap = src->linesize[0] - width * BPP; + p = src->data[0]; + for(y=0;ylinesize[0] - width; + cb += dst->linesize[1] - width; + cr += dst->linesize[2] - width; + } +} + +static void rgb24_to_yuvj420p(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + int wrap, wrap3, width2; + int r, g, b, r1, g1, b1, w; + uint8_t *lum, *cb, *cr; + const uint8_t *p; + + lum = dst->data[0]; + cb = dst->data[1]; + cr = dst->data[2]; + + width2 = (width + 1) >> 1; + wrap = dst->linesize[0]; + wrap3 = src->linesize[0]; + p = src->data[0]; + for(;height>=2;height -= 2) { + for(w = width; w >= 2; w -= 2) { + RGB_IN(r, g, b, p); + r1 = r; + g1 = g; + b1 = b; + lum[0] = RGB_TO_Y(r, g, b); + + RGB_IN(r, g, b, p + BPP); + r1 += r; + g1 += g; + b1 += b; + lum[1] = RGB_TO_Y(r, g, b); + p += wrap3; + lum += wrap; + + RGB_IN(r, g, b, p); + r1 += r; + g1 += g; + b1 += b; + lum[0] = RGB_TO_Y(r, g, b); + + RGB_IN(r, g, b, p + BPP); + r1 += r; + g1 += g; + b1 += b; + lum[1] = RGB_TO_Y(r, g, b); + + cb[0] = RGB_TO_U(r1, g1, b1, 2); + cr[0] = RGB_TO_V(r1, g1, b1, 2); + + cb++; + cr++; + p += -wrap3 + 2 * BPP; + lum += -wrap + 2; + } + if (w) { + RGB_IN(r, g, b, p); + r1 = r; + g1 = g; + b1 = b; + lum[0] = RGB_TO_Y(r, g, b); + p += wrap3; + lum += wrap; + RGB_IN(r, g, b, p); + r1 += r; + g1 += g; + b1 += b; + lum[0] = RGB_TO_Y(r, g, b); + cb[0] = RGB_TO_U(r1, g1, b1, 1); + cr[0] = RGB_TO_V(r1, g1, b1, 1); + cb++; + cr++; + p += -wrap3 + BPP; + lum += -wrap + 1; + } + p += wrap3 + (wrap3 - width * BPP); + lum += wrap + (wrap - width); + cb += dst->linesize[1] - width2; + cr += dst->linesize[2] - width2; + } + /* handle odd height */ + if (height) { + for(w = width; w >= 2; w -= 2) { + RGB_IN(r, g, b, p); + r1 = r; + g1 = g; + b1 = b; + lum[0] = RGB_TO_Y(r, g, b); + + RGB_IN(r, g, b, p + BPP); + r1 += r; + g1 += g; + b1 += b; + lum[1] = RGB_TO_Y(r, g, b); + cb[0] = RGB_TO_U(r1, g1, b1, 1); + cr[0] = RGB_TO_V(r1, g1, b1, 1); + cb++; + cr++; + p += 2 * BPP; + lum += 2; + } + if (w) { + RGB_IN(r, g, b, p); + lum[0] = RGB_TO_Y(r, g, b); + cb[0] = RGB_TO_U(r, g, b, 0); + cr[0] = RGB_TO_V(r, g, b, 0); + } + } +} + +static void rgb24_to_yuvj444p(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + int src_wrap, x, y; + int r, g, b; + uint8_t *lum, *cb, *cr; + const uint8_t *p; + + lum = dst->data[0]; + cb = dst->data[1]; + cr = dst->data[2]; + + src_wrap = src->linesize[0] - width * BPP; + p = src->data[0]; + for(y=0;ylinesize[0] - width; + cb += dst->linesize[1] - width; + cr += dst->linesize[2] - width; + } +} + +#endif /* FMT_RGB24 */ + +#if defined(FMT_RGB24) || defined(FMT_RGBA32) + +static void glue(RGB_NAME, _to_pal8)(AVPicture *dst, const AVPicture *src, + int width, int height) +{ + const unsigned char *p; + unsigned char *q; + int dst_wrap, src_wrap; + int x, y, has_alpha; + unsigned int r, g, b; + + p = src->data[0]; + src_wrap = src->linesize[0] - BPP * width; + + q = dst->data[0]; + dst_wrap = dst->linesize[0] - width; + has_alpha = 0; + + for(y=0;ydata[1], has_alpha); +} + +#endif /* defined(FMT_RGB24) || defined(FMT_RGBA32) */ + +#ifdef RGBA_IN + +static int glue(get_alpha_info_, RGB_NAME)(const AVPicture *src, + int width, int height) +{ + const unsigned char *p; + int src_wrap, ret, x, y; + unsigned int r, g, b, a; + + p = src->data[0]; + src_wrap = src->linesize[0] - BPP * width; + ret = 0; + for(y=0;y> (POS_FRAC_BITS - PHASE_BITS)) & ((1 << PHASE_BITS) - 1); +} + +/* This function must be optimized */ +static void h_resample_fast(uint8_t *dst, int dst_width, const uint8_t *src, + int src_width, int src_start, int src_incr, + int16_t *filters) +{ + int src_pos, phase, sum, i; + const uint8_t *s; + int16_t *filter; + + src_pos = src_start; + for(i=0;i> POS_FRAC_BITS) < 0 || + (src_pos >> POS_FRAC_BITS) > (src_width - NB_TAPS)) + av_abort(); +#endif + s = src + (src_pos >> POS_FRAC_BITS); + phase = get_phase(src_pos); + filter = filters + phase * NB_TAPS; +#if NB_TAPS == 4 + sum = s[0] * filter[0] + + s[1] * filter[1] + + s[2] * filter[2] + + s[3] * filter[3]; +#else + { + int j; + sum = 0; + for(j=0;j> FILTER_BITS; + if (sum < 0) + sum = 0; + else if (sum > 255) + sum = 255; + dst[0] = sum; + src_pos += src_incr; + dst++; + } +} + +/* This function must be optimized */ +static void v_resample(uint8_t *dst, int dst_width, const uint8_t *src, + int wrap, int16_t *filter) +{ + int sum, i; + const uint8_t *s; + + s = src; + for(i=0;i> FILTER_BITS; + if (sum < 0) + sum = 0; + else if (sum > 255) + sum = 255; + dst[0] = sum; + dst++; + s++; + } +} + +#ifdef HAVE_MMX + +#include "i386/mmx.h" + +#define FILTER4(reg) \ +{\ + s = src + (src_pos >> POS_FRAC_BITS);\ + phase = get_phase(src_pos);\ + filter = filters + phase * NB_TAPS;\ + movq_m2r(*s, reg);\ + punpcklbw_r2r(mm7, reg);\ + movq_m2r(*filter, mm6);\ + pmaddwd_r2r(reg, mm6);\ + movq_r2r(mm6, reg);\ + psrlq_i2r(32, reg);\ + paddd_r2r(mm6, reg);\ + psrad_i2r(FILTER_BITS, reg);\ + src_pos += src_incr;\ +} + +#define DUMP(reg) movq_r2m(reg, tmp); printf(#reg "=%016Lx\n", tmp.uq); + +/* XXX: do four pixels at a time */ +static void h_resample_fast4_mmx(uint8_t *dst, int dst_width, + const uint8_t *src, int src_width, + int src_start, int src_incr, int16_t *filters) +{ + int src_pos, phase; + const uint8_t *s; + int16_t *filter; + mmx_t tmp; + + src_pos = src_start; + pxor_r2r(mm7, mm7); + + while (dst_width >= 4) { + + FILTER4(mm0); + FILTER4(mm1); + FILTER4(mm2); + FILTER4(mm3); + + packuswb_r2r(mm7, mm0); + packuswb_r2r(mm7, mm1); + packuswb_r2r(mm7, mm3); + packuswb_r2r(mm7, mm2); + movq_r2m(mm0, tmp); + dst[0] = tmp.ub[0]; + movq_r2m(mm1, tmp); + dst[1] = tmp.ub[0]; + movq_r2m(mm2, tmp); + dst[2] = tmp.ub[0]; + movq_r2m(mm3, tmp); + dst[3] = tmp.ub[0]; + dst += 4; + dst_width -= 4; + } + while (dst_width > 0) { + FILTER4(mm0); + packuswb_r2r(mm7, mm0); + movq_r2m(mm0, tmp); + dst[0] = tmp.ub[0]; + dst++; + dst_width--; + } + emms(); +} + +static void v_resample4_mmx(uint8_t *dst, int dst_width, const uint8_t *src, + int wrap, int16_t *filter) +{ + int sum, i, v; + const uint8_t *s; + mmx_t tmp; + mmx_t coefs[4]; + + for(i=0;i<4;i++) { + v = filter[i]; + coefs[i].uw[0] = v; + coefs[i].uw[1] = v; + coefs[i].uw[2] = v; + coefs[i].uw[3] = v; + } + + pxor_r2r(mm7, mm7); + s = src; + while (dst_width >= 4) { + movq_m2r(s[0 * wrap], mm0); + punpcklbw_r2r(mm7, mm0); + movq_m2r(s[1 * wrap], mm1); + punpcklbw_r2r(mm7, mm1); + movq_m2r(s[2 * wrap], mm2); + punpcklbw_r2r(mm7, mm2); + movq_m2r(s[3 * wrap], mm3); + punpcklbw_r2r(mm7, mm3); + + pmullw_m2r(coefs[0], mm0); + pmullw_m2r(coefs[1], mm1); + pmullw_m2r(coefs[2], mm2); + pmullw_m2r(coefs[3], mm3); + + paddw_r2r(mm1, mm0); + paddw_r2r(mm3, mm2); + paddw_r2r(mm2, mm0); + psraw_i2r(FILTER_BITS, mm0); + + packuswb_r2r(mm7, mm0); + movq_r2m(mm0, tmp); + + *(uint32_t *)dst = tmp.ud[0]; + dst += 4; + s += 4; + dst_width -= 4; + } + while (dst_width > 0) { + sum = s[0 * wrap] * filter[0] + + s[1 * wrap] * filter[1] + + s[2 * wrap] * filter[2] + + s[3 * wrap] * filter[3]; + sum = sum >> FILTER_BITS; + if (sum < 0) + sum = 0; + else if (sum > 255) + sum = 255; + dst[0] = sum; + dst++; + s++; + dst_width--; + } + emms(); +} +#endif + +#ifdef HAVE_ALTIVEC +typedef union { + vector unsigned char v; + unsigned char c[16]; +} vec_uc_t; + +typedef union { + vector signed short v; + signed short s[8]; +} vec_ss_t; + +void v_resample16_altivec(uint8_t *dst, int dst_width, const uint8_t *src, + int wrap, int16_t *filter) +{ + int sum, i; + const uint8_t *s; + vector unsigned char *tv, tmp, dstv, zero; + vec_ss_t srchv[4], srclv[4], fv[4]; + vector signed short zeros, sumhv, sumlv; + s = src; + + for(i=0;i<4;i++) + { + /* + The vec_madds later on does an implicit >>15 on the result. + Since FILTER_BITS is 8, and we have 15 bits of magnitude in + a signed short, we have just enough bits to pre-shift our + filter constants <<7 to compensate for vec_madds. + */ + fv[i].s[0] = filter[i] << (15-FILTER_BITS); + fv[i].v = vec_splat(fv[i].v, 0); + } + + zero = vec_splat_u8(0); + zeros = vec_splat_s16(0); + + + /* + When we're resampling, we'd ideally like both our input buffers, + and output buffers to be 16-byte aligned, so we can do both aligned + reads and writes. Sadly we can't always have this at the moment, so + we opt for aligned writes, as unaligned writes have a huge overhead. + To do this, do enough scalar resamples to get dst 16-byte aligned. + */ + i = (-(int)dst) & 0xf; + while(i>0) { + sum = s[0 * wrap] * filter[0] + + s[1 * wrap] * filter[1] + + s[2 * wrap] * filter[2] + + s[3 * wrap] * filter[3]; + sum = sum >> FILTER_BITS; + if (sum<0) sum = 0; else if (sum>255) sum=255; + dst[0] = sum; + dst++; + s++; + dst_width--; + i--; + } + + /* Do our altivec resampling on 16 pixels at once. */ + while(dst_width>=16) { + /* + Read 16 (potentially unaligned) bytes from each of + 4 lines into 4 vectors, and split them into shorts. + Interleave the multipy/accumulate for the resample + filter with the loads to hide the 3 cycle latency + the vec_madds have. + */ + tv = (vector unsigned char *) &s[0 * wrap]; + tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[i * wrap])); + srchv[0].v = (vector signed short) vec_mergeh(zero, tmp); + srclv[0].v = (vector signed short) vec_mergel(zero, tmp); + sumhv = vec_madds(srchv[0].v, fv[0].v, zeros); + sumlv = vec_madds(srclv[0].v, fv[0].v, zeros); + + tv = (vector unsigned char *) &s[1 * wrap]; + tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[1 * wrap])); + srchv[1].v = (vector signed short) vec_mergeh(zero, tmp); + srclv[1].v = (vector signed short) vec_mergel(zero, tmp); + sumhv = vec_madds(srchv[1].v, fv[1].v, sumhv); + sumlv = vec_madds(srclv[1].v, fv[1].v, sumlv); + + tv = (vector unsigned char *) &s[2 * wrap]; + tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[2 * wrap])); + srchv[2].v = (vector signed short) vec_mergeh(zero, tmp); + srclv[2].v = (vector signed short) vec_mergel(zero, tmp); + sumhv = vec_madds(srchv[2].v, fv[2].v, sumhv); + sumlv = vec_madds(srclv[2].v, fv[2].v, sumlv); + + tv = (vector unsigned char *) &s[3 * wrap]; + tmp = vec_perm(tv[0], tv[1], vec_lvsl(0, &s[3 * wrap])); + srchv[3].v = (vector signed short) vec_mergeh(zero, tmp); + srclv[3].v = (vector signed short) vec_mergel(zero, tmp); + sumhv = vec_madds(srchv[3].v, fv[3].v, sumhv); + sumlv = vec_madds(srclv[3].v, fv[3].v, sumlv); + + /* + Pack the results into our destination vector, + and do an aligned write of that back to memory. + */ + dstv = vec_packsu(sumhv, sumlv) ; + vec_st(dstv, 0, (vector unsigned char *) dst); + + dst+=16; + s+=16; + dst_width-=16; + } + + /* + If there are any leftover pixels, resample them + with the slow scalar method. + */ + while(dst_width>0) { + sum = s[0 * wrap] * filter[0] + + s[1 * wrap] * filter[1] + + s[2 * wrap] * filter[2] + + s[3 * wrap] * filter[3]; + sum = sum >> FILTER_BITS; + if (sum<0) sum = 0; else if (sum>255) sum=255; + dst[0] = sum; + dst++; + s++; + dst_width--; + } +} +#endif + +/* slow version to handle limit cases. Does not need optimisation */ +static void h_resample_slow(uint8_t *dst, int dst_width, + const uint8_t *src, int src_width, + int src_start, int src_incr, int16_t *filters) +{ + int src_pos, phase, sum, j, v, i; + const uint8_t *s, *src_end; + int16_t *filter; + + src_end = src + src_width; + src_pos = src_start; + for(i=0;i> POS_FRAC_BITS); + phase = get_phase(src_pos); + filter = filters + phase * NB_TAPS; + sum = 0; + for(j=0;j= src_end) + v = src_end[-1]; + else + v = s[0]; + sum += v * filter[j]; + s++; + } + sum = sum >> FILTER_BITS; + if (sum < 0) + sum = 0; + else if (sum > 255) + sum = 255; + dst[0] = sum; + src_pos += src_incr; + dst++; + } +} + +static void h_resample(uint8_t *dst, int dst_width, const uint8_t *src, + int src_width, int src_start, int src_incr, + int16_t *filters) +{ + int n, src_end; + + if (src_start < 0) { + n = (0 - src_start + src_incr - 1) / src_incr; + h_resample_slow(dst, n, src, src_width, src_start, src_incr, filters); + dst += n; + dst_width -= n; + src_start += n * src_incr; + } + src_end = src_start + dst_width * src_incr; + if (src_end > ((src_width - NB_TAPS) << POS_FRAC_BITS)) { + n = (((src_width - NB_TAPS + 1) << POS_FRAC_BITS) - 1 - src_start) / + src_incr; + } else { + n = dst_width; + } +#ifdef HAVE_MMX + if ((mm_flags & MM_MMX) && NB_TAPS == 4) + h_resample_fast4_mmx(dst, n, + src, src_width, src_start, src_incr, filters); + else +#endif + h_resample_fast(dst, n, + src, src_width, src_start, src_incr, filters); + if (n < dst_width) { + dst += n; + dst_width -= n; + src_start += n * src_incr; + h_resample_slow(dst, dst_width, + src, src_width, src_start, src_incr, filters); + } +} + +static void component_resample(ImgReSampleContext *s, + uint8_t *output, int owrap, int owidth, int oheight, + uint8_t *input, int iwrap, int iwidth, int iheight) +{ + int src_y, src_y1, last_src_y, ring_y, phase_y, y1, y; + uint8_t *new_line, *src_line; + + last_src_y = - FCENTER - 1; + /* position of the bottom of the filter in the source image */ + src_y = (last_src_y + NB_TAPS) * POS_FRAC; + ring_y = NB_TAPS; /* position in ring buffer */ + for(y=0;y> POS_FRAC_BITS; + while (last_src_y < src_y1) { + if (++ring_y >= LINE_BUF_HEIGHT + NB_TAPS) + ring_y = NB_TAPS; + last_src_y++; + /* handle limit conditions : replicate line (slightly + inefficient because we filter multiple times) */ + y1 = last_src_y; + if (y1 < 0) { + y1 = 0; + } else if (y1 >= iheight) { + y1 = iheight - 1; + } + src_line = input + y1 * iwrap; + new_line = s->line_buf + ring_y * owidth; + /* apply filter and handle limit cases correctly */ + h_resample(new_line, owidth, + src_line, iwidth, - FCENTER * POS_FRAC, s->h_incr, + &s->h_filters[0][0]); + /* handle ring buffer wraping */ + if (ring_y >= LINE_BUF_HEIGHT) { + memcpy(s->line_buf + (ring_y - LINE_BUF_HEIGHT) * owidth, + new_line, owidth); + } + } + /* apply vertical filter */ + phase_y = get_phase(src_y); +#ifdef HAVE_MMX + /* desactivated MMX because loss of precision */ + if ((mm_flags & MM_MMX) && NB_TAPS == 4 && 0) + v_resample4_mmx(output, owidth, + s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth, + &s->v_filters[phase_y][0]); + else +#endif +#ifdef HAVE_ALTIVEC + if ((mm_flags & MM_ALTIVEC) && NB_TAPS == 4 && FILTER_BITS <= 6) + v_resample16_altivec(output, owidth, + s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth, + &s->v_filters[phase_y][0]); + else +#endif + v_resample(output, owidth, + s->line_buf + (ring_y - NB_TAPS + 1) * owidth, owidth, + &s->v_filters[phase_y][0]); + + src_y += s->v_incr; + + output += owrap; + } +} + +ImgReSampleContext *img_resample_init(int owidth, int oheight, + int iwidth, int iheight) +{ + return img_resample_full_init(owidth, oheight, iwidth, iheight, + 0, 0, 0, 0, 0, 0, 0, 0); +} + +ImgReSampleContext *img_resample_full_init(int owidth, int oheight, + int iwidth, int iheight, + int topBand, int bottomBand, + int leftBand, int rightBand, + int padtop, int padbottom, + int padleft, int padright) +{ + ImgReSampleContext *s; + + if (!owidth || !oheight || !iwidth || !iheight) + return NULL; + + s = av_mallocz(sizeof(ImgReSampleContext)); + if (!s) + return NULL; + if((unsigned)owidth >= UINT_MAX / (LINE_BUF_HEIGHT + NB_TAPS)) + return NULL; + s->line_buf = av_mallocz(owidth * (LINE_BUF_HEIGHT + NB_TAPS)); + if (!s->line_buf) + goto fail; + + s->owidth = owidth; + s->oheight = oheight; + s->iwidth = iwidth; + s->iheight = iheight; + + s->topBand = topBand; + s->bottomBand = bottomBand; + s->leftBand = leftBand; + s->rightBand = rightBand; + + s->padtop = padtop; + s->padbottom = padbottom; + s->padleft = padleft; + s->padright = padright; + + s->pad_owidth = owidth - (padleft + padright); + s->pad_oheight = oheight - (padtop + padbottom); + + s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / s->pad_owidth; + s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / s->pad_oheight; + + av_build_filter(&s->h_filters[0][0], (float) s->pad_owidth / + (float) (iwidth - leftBand - rightBand), NB_TAPS, NB_PHASES, 1<v_filters[0][0], (float) s->pad_oheight / + (float) (iheight - topBand - bottomBand), NB_TAPS, NB_PHASES, 1<data[i] + (((output->linesize[i] * + s->padtop) + s->padleft) >> shift); + + component_resample(s, optr, output->linesize[i], + s->pad_owidth >> shift, s->pad_oheight >> shift, + input->data[i] + (input->linesize[i] * + (s->topBand >> shift)) + (s->leftBand >> shift), + input->linesize[i], ((s->iwidth - s->leftBand - + s->rightBand) >> shift), + (s->iheight - s->topBand - s->bottomBand) >> shift); + } +} + +void img_resample_close(ImgReSampleContext *s) +{ + av_free(s->line_buf); + av_free(s); +} + +struct SwsContext *sws_getContext(int srcW, int srcH, int srcFormat, + int dstW, int dstH, int dstFormat, + int flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, double *param) +{ + struct SwsContext *ctx; + + ctx = av_malloc(sizeof(struct SwsContext)); + if (ctx == NULL) { + av_log(NULL, AV_LOG_ERROR, "Cannot allocate a resampling context!\n"); + + return NULL; + } + + if ((srcH != dstH) || (srcW != dstW)) { + if ((srcFormat != PIX_FMT_YUV420P) || (dstFormat != PIX_FMT_YUV420P)) { + av_log(NULL, AV_LOG_INFO, "PIX_FMT_YUV420P will be used as an intermediate format for rescaling\n"); + } + ctx->resampling_ctx = img_resample_init(dstW, dstH, srcW, srcH); + } else { + ctx->resampling_ctx = av_malloc(sizeof(ImgReSampleContext)); + ctx->resampling_ctx->iheight = srcH; + ctx->resampling_ctx->iwidth = srcW; + ctx->resampling_ctx->oheight = dstH; + ctx->resampling_ctx->owidth = dstW; + } + ctx->src_pix_fmt = srcFormat; + ctx->dst_pix_fmt = dstFormat; + + return ctx; +} + +void sws_freeContext(struct SwsContext *ctx) +{ + if ((ctx->resampling_ctx->iwidth != ctx->resampling_ctx->owidth) || + (ctx->resampling_ctx->iheight != ctx->resampling_ctx->oheight)) { + img_resample_close(ctx->resampling_ctx); + } else { + av_free(ctx->resampling_ctx); + } + av_free(ctx); +} + +int sws_scale(struct SwsContext *ctx, uint8_t* src[], int srcStride[], + int srcSliceY, int srcSliceH, uint8_t* dst[], int dstStride[]) +{ + AVPicture src_pict, dst_pict; + int i, res = 0; + AVPicture picture_format_temp; + AVPicture picture_resample_temp, *formatted_picture, *resampled_picture; + uint8_t *buf1 = NULL, *buf2 = NULL; + enum PixelFormat current_pix_fmt; + + for (i = 0; i < 3; i++) { + src_pict.data[i] = src[i]; + src_pict.linesize[i] = srcStride[i]; + dst_pict.data[i] = dst[i]; + dst_pict.linesize[i] = dstStride[i]; + } + if ((ctx->resampling_ctx->iwidth != ctx->resampling_ctx->owidth) || + (ctx->resampling_ctx->iheight != ctx->resampling_ctx->oheight)) { + /* We have to rescale the picture, but only YUV420P rescaling is supported... */ + + if (ctx->src_pix_fmt != PIX_FMT_YUV420P) { + int size; + + /* create temporary picture for rescaling input*/ + size = avpicture_get_size(PIX_FMT_YUV420P, ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight); + buf1 = av_malloc(size); + if (!buf1) { + res = -1; + goto the_end; + } + formatted_picture = &picture_format_temp; + avpicture_fill((AVPicture*)formatted_picture, buf1, + PIX_FMT_YUV420P, ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight); + + if (img_convert((AVPicture*)formatted_picture, PIX_FMT_YUV420P, + &src_pict, ctx->src_pix_fmt, + ctx->resampling_ctx->iwidth, ctx->resampling_ctx->iheight) < 0) { + + av_log(NULL, AV_LOG_ERROR, "pixel format conversion not handled\n"); + res = -1; + goto the_end; + } + } else { + formatted_picture = &src_pict; + } + + if (ctx->dst_pix_fmt != PIX_FMT_YUV420P) { + int size; + + /* create temporary picture for rescaling output*/ + size = avpicture_get_size(PIX_FMT_YUV420P, ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight); + buf2 = av_malloc(size); + if (!buf2) { + res = -1; + goto the_end; + } + resampled_picture = &picture_resample_temp; + avpicture_fill((AVPicture*)resampled_picture, buf2, + PIX_FMT_YUV420P, ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight); + + } else { + resampled_picture = &dst_pict; + } + + /* ...and finally rescale!!! */ + img_resample(ctx->resampling_ctx, resampled_picture, formatted_picture); + current_pix_fmt = PIX_FMT_YUV420P; + } else { + resampled_picture = &src_pict; + current_pix_fmt = ctx->src_pix_fmt; + } + + if (current_pix_fmt != ctx->dst_pix_fmt) { + if (img_convert(&dst_pict, ctx->dst_pix_fmt, + resampled_picture, current_pix_fmt, + ctx->resampling_ctx->owidth, ctx->resampling_ctx->oheight) < 0) { + + av_log(NULL, AV_LOG_ERROR, "pixel format conversion not handled\n"); + + res = -1; + goto the_end; + } + } + +the_end: + av_free(buf1); + av_free(buf2); + return res; +} + + +#ifdef TEST +#include + +/* input */ +#define XSIZE 256 +#define YSIZE 256 +uint8_t img[XSIZE * YSIZE]; + +/* output */ +#define XSIZE1 512 +#define YSIZE1 512 +uint8_t img1[XSIZE1 * YSIZE1]; +uint8_t img2[XSIZE1 * YSIZE1]; + +void save_pgm(const char *filename, uint8_t *img, int xsize, int ysize) +{ +#undef fprintf + FILE *f; + f=fopen(filename,"w"); + fprintf(f,"P5\n%d %d\n%d\n", xsize, ysize, 255); + fwrite(img,1, xsize * ysize,f); + fclose(f); +#define fprintf please_use_av_log +} + +static void dump_filter(int16_t *filter) +{ + int i, ph; + + for(ph=0;phh_filters[0][0]); + component_resample(s, img1, xsize, xsize, ysize, + img + 50 * XSIZE, XSIZE, XSIZE, YSIZE - 100); + img_resample_close(s); + + snprintf(buf, sizeof(buf), "/tmp/out%d.pgm", i); + save_pgm(buf, img1, xsize, ysize); + } + + /* mmx test */ +#ifdef HAVE_MMX + av_log(NULL, AV_LOG_INFO, "MMX test\n"); + fact = 0.72; + xsize = (int)(XSIZE * fact); + ysize = (int)(YSIZE * fact); + mm_flags = MM_MMX; + s = img_resample_init(xsize, ysize, XSIZE, YSIZE); + component_resample(s, img1, xsize, xsize, ysize, + img, XSIZE, XSIZE, YSIZE); + + mm_flags = 0; + s = img_resample_init(xsize, ysize, XSIZE, YSIZE); + component_resample(s, img2, xsize, xsize, ysize, + img, XSIZE, XSIZE, YSIZE); + if (memcmp(img1, img2, xsize * ysize) != 0) { + av_log(NULL, AV_LOG_ERROR, "mmx error\n"); + exit(1); + } + av_log(NULL, AV_LOG_INFO, "MMX OK\n"); +#endif + return 0; +} + +#endif diff --git a/mpeg4/src/libavcodec/indeo2.c b/mpeg4/src/libavcodec/indeo2.c new file mode 100644 index 00000000..3814e525 --- /dev/null +++ b/mpeg4/src/libavcodec/indeo2.c @@ -0,0 +1,219 @@ +/* + * Indel Indeo 2 codec + * Copyright (c) 2005 Konstantin Shishkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file indeo2.c + * Intel Indeo 2 decoder. + */ +#define ALT_BITSTREAM_READER_LE +#include "avcodec.h" +#include "bitstream.h" +#include "indeo2data.h" + +typedef struct Ir2Context{ + AVCodecContext *avctx; + AVFrame picture; + GetBitContext gb; + int decode_delta; +} Ir2Context; + +#define CODE_VLC_BITS 14 +static VLC ir2_vlc; + +/* Indeo 2 codes are in range 0x01..0x7F and 0x81..0x90 */ +static inline int ir2_get_code(GetBitContext *gb) +{ + return get_vlc2(gb, ir2_vlc.table, CODE_VLC_BITS, 1) + 1; +} + +static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride, + const uint8_t *table) +{ + int i; + int j; + int out = 0; + int c; + int t; + + if(width&1) + return -1; + + /* first line contain absolute values, other lines contain deltas */ + while (out < width){ + c = ir2_get_code(&ctx->gb); + if(c >= 0x80) { /* we have a run */ + c -= 0x7F; + if(out + c*2 > width) + return -1; + for (i = 0; i < c * 2; i++) + dst[out++] = 0x80; + } else { /* copy two values from table */ + dst[out++] = table[c * 2]; + dst[out++] = table[(c * 2) + 1]; + } + } + dst += stride; + + for (j = 1; j < height; j++){ + out = 0; + while (out < width){ + c = ir2_get_code(&ctx->gb); + if(c >= 0x80) { /* we have a skip */ + c -= 0x7F; + if(out + c*2 > width) + return -1; + for (i = 0; i < c * 2; i++) { + dst[out] = dst[out - stride]; + out++; + } + } else { /* add two deltas from table */ + t = dst[out - stride] + (table[c * 2] - 128); + t= clip_uint8(t); + dst[out] = t; + out++; + t = dst[out - stride] + (table[(c * 2) + 1] - 128); + t= clip_uint8(t); + dst[out] = t; + out++; + } + } + dst += stride; + } + return 0; +} + +static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst, int stride, + const uint8_t *table) +{ + int j; + int out = 0; + int c; + int t; + + if(width&1) + return -1; + + for (j = 0; j < height; j++){ + out = 0; + while (out < width){ + c = ir2_get_code(&ctx->gb); + if(c >= 0x80) { /* we have a skip */ + c -= 0x7F; + out += c * 2; + } else { /* add two deltas from table */ + t = dst[out] + (((table[c * 2] - 128)*3) >> 2); + t= clip_uint8(t); + dst[out] = t; + out++; + t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2); + t= clip_uint8(t); + dst[out] = t; + out++; + } + } + dst += stride; + } + return 0; +} + +static int ir2_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + Ir2Context * const s = avctx->priv_data; + AVFrame *picture = data; + AVFrame * const p= (AVFrame*)&s->picture; + int start; + + if(p->data[0]) + avctx->release_buffer(avctx, p); + + p->reference = 1; + p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, p)) { + av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); + return -1; + } + + s->decode_delta = buf[18]; + + /* decide whether frame uses deltas or not */ +#ifndef ALT_BITSTREAM_READER_LE + for (i = 0; i < buf_size; i++) + buf[i] = ff_reverse[buf[i]]; +#endif + start = 48; /* hardcoded for now */ + + init_get_bits(&s->gb, buf + start, buf_size - start); + + if (s->decode_delta) { /* intraframe */ + ir2_decode_plane(s, avctx->width, avctx->height, + s->picture.data[0], s->picture.linesize[0], ir2_luma_table); + /* swapped U and V */ + ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, + s->picture.data[2], s->picture.linesize[2], ir2_luma_table); + ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, + s->picture.data[1], s->picture.linesize[1], ir2_luma_table); + } else { /* interframe */ + ir2_decode_plane_inter(s, avctx->width, avctx->height, + s->picture.data[0], s->picture.linesize[0], ir2_luma_table); + /* swapped U and V */ + ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, + s->picture.data[2], s->picture.linesize[2], ir2_luma_table); + ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, + s->picture.data[1], s->picture.linesize[1], ir2_luma_table); + } + + *picture= *(AVFrame*)&s->picture; + *data_size = sizeof(AVPicture); + + return buf_size; +} + +static int ir2_decode_init(AVCodecContext *avctx){ + Ir2Context * const ic = avctx->priv_data; + + ic->avctx = avctx; + + avctx->pix_fmt= PIX_FMT_YUV410P; + + if (!ir2_vlc.table) + init_vlc(&ir2_vlc, CODE_VLC_BITS, IR2_CODES, + &ir2_codes[0][1], 4, 2, +#ifdef ALT_BITSTREAM_READER_LE + &ir2_codes[0][0], 4, 2, INIT_VLC_USE_STATIC | INIT_VLC_LE); +#else + &ir2_codes[0][0], 4, 2, INIT_VLC_USE_STATIC); +#endif + + return 0; +} + +AVCodec indeo2_decoder = { + "indeo2", + CODEC_TYPE_VIDEO, + CODEC_ID_INDEO2, + sizeof(Ir2Context), + ir2_decode_init, + NULL, + NULL, + ir2_decode_frame, + CODEC_CAP_DR1, +}; diff --git a/mpeg4/src/libavcodec/indeo2data.h b/mpeg4/src/libavcodec/indeo2data.h new file mode 100644 index 00000000..2430b53c --- /dev/null +++ b/mpeg4/src/libavcodec/indeo2data.h @@ -0,0 +1,113 @@ +#define IR2_CODES 143 +static const uint16_t ir2_codes[IR2_CODES][2] = { +#ifdef ALT_BITSTREAM_READER_LE +{0x0000, 3}, {0x0004, 3}, {0x0006, 3}, {0x0001, 5}, +{0x0009, 5}, {0x0019, 5}, {0x000D, 5}, {0x001D, 5}, +{0x0023, 6}, {0x0013, 6}, {0x0033, 6}, {0x000B, 6}, +{0x002B, 6}, {0x001B, 6}, {0x0007, 8}, {0x0087, 8}, +{0x0027, 8}, {0x00A7, 8}, {0x0067, 8}, {0x00E7, 8}, +{0x0097, 8}, {0x0057, 8}, {0x0037, 8}, {0x00B7, 8}, +{0x00F7, 8}, {0x000F, 9}, {0x008F, 9}, {0x018F, 9}, +{0x014F, 9}, {0x00CF, 9}, {0x002F, 9}, {0x012F, 9}, +{0x01AF, 9}, {0x006F, 9}, {0x00EF, 9}, {0x01EF, 9}, +{0x001F, 10}, {0x021F, 10}, {0x011F, 10}, {0x031F, 10}, +{0x009F, 10}, {0x029F, 10}, {0x019F, 10}, {0x039F, 10}, +{0x005F, 10}, {0x025F, 10}, {0x015F, 10}, {0x035F, 10}, +{0x00DF, 10}, {0x02DF, 10}, {0x01DF, 10}, {0x03DF, 10}, +{0x003F, 13}, {0x103F, 13}, {0x083F, 13}, {0x183F, 13}, +{0x043F, 13}, {0x143F, 13}, {0x0C3F, 13}, {0x1C3F, 13}, +{0x023F, 13}, {0x123F, 13}, {0x0A3F, 13}, {0x1A3F, 13}, +{0x063F, 13}, {0x163F, 13}, {0x0E3F, 13}, {0x1E3F, 13}, +{0x013F, 13}, {0x113F, 13}, {0x093F, 13}, {0x193F, 13}, +{0x053F, 13}, {0x153F, 13}, {0x0D3F, 13}, {0x1D3F, 13}, +{0x033F, 13}, {0x133F, 13}, {0x0B3F, 13}, {0x1B3F, 13}, +{0x073F, 13}, {0x173F, 13}, {0x0F3F, 13}, {0x1F3F, 13}, +{0x00BF, 13}, {0x10BF, 13}, {0x08BF, 13}, {0x18BF, 13}, +{0x04BF, 13}, {0x14BF, 13}, {0x0CBF, 13}, {0x1CBF, 13}, +{0x02BF, 13}, {0x12BF, 13}, {0x0ABF, 13}, {0x1ABF, 13}, +{0x06BF, 13}, {0x16BF, 13}, {0x0EBF, 13}, {0x1EBF, 13}, +{0x01BF, 13}, {0x11BF, 13}, {0x09BF, 13}, {0x19BF, 13}, +{0x05BF, 13}, {0x15BF, 13}, {0x0DBF, 13}, {0x1DBF, 13}, +{0x03BF, 13}, {0x13BF, 13}, {0x0BBF, 13}, {0x1BBF, 13}, +{0x07BF, 13}, {0x17BF, 13}, {0x0FBF, 13}, {0x1FBF, 13}, +{0x007F, 14}, {0x207F, 14}, {0x107F, 14}, {0x307F, 14}, +{0x087F, 14}, {0x287F, 14}, {0x187F, 14}, {0x387F, 14}, +{0x047F, 14}, {0x247F, 14}, {0x147F, 14}, {0x0002, 3}, +{0x0011, 5}, {0x0005, 5}, {0x0015, 5}, {0x0003, 6}, +{0x003B, 6}, {0x0047, 8}, {0x00C7, 8}, {0x0017, 8}, +{0x00D7, 8}, {0x0077, 8}, {0x010F, 9}, {0x004F, 9}, +{0x01CF, 9}, {0x00AF, 9}, {0x016F, 9}, +#else + {0x0000, 3}, {0x0001, 3}, {0x0003, 3}, {0x0010, 5}, + {0x0012, 5}, {0x0013, 5}, {0x0016, 5}, {0x0017, 5}, + {0x0031, 6}, {0x0032, 6}, {0x0033, 6}, {0x0034, 6}, + {0x0035, 6}, {0x0036, 6}, {0x00E0, 8}, {0x00E1, 8}, + {0x00E4, 8}, {0x00E5, 8}, {0x00E6, 8}, {0x00E7, 8}, + {0x00E9, 8}, {0x00EA, 8}, {0x00EC, 8}, {0x00ED, 8}, + {0x00EF, 8}, {0x01E0, 9}, {0x01E2, 9}, {0x01E3, 9}, + {0x01E5, 9}, {0x01E6, 9}, {0x01E8, 9}, {0x01E9, 9}, + {0x01EB, 9}, {0x01EC, 9}, {0x01EE, 9}, {0x01EF, 9}, + {0x03E0, 10}, {0x03E1, 10}, {0x03E2, 10}, {0x03E3, 10}, + {0x03E4, 10}, {0x03E5, 10}, {0x03E6, 10}, {0x03E7, 10}, + {0x03E8, 10}, {0x03E9, 10}, {0x03EA, 10}, {0x03EB, 10}, + {0x03EC, 10}, {0x03ED, 10}, {0x03EE, 10}, {0x03EF, 10}, + {0x1F80, 13}, {0x1F81, 13}, {0x1F82, 13}, {0x1F83, 13}, + {0x1F84, 13}, {0x1F85, 13}, {0x1F86, 13}, {0x1F87, 13}, + {0x1F88, 13}, {0x1F89, 13}, {0x1F8A, 13}, {0x1F8B, 13}, + {0x1F8C, 13}, {0x1F8D, 13}, {0x1F8E, 13}, {0x1F8F, 13}, + {0x1F90, 13}, {0x1F91, 13}, {0x1F92, 13}, {0x1F93, 13}, + {0x1F94, 13}, {0x1F95, 13}, {0x1F96, 13}, {0x1F97, 13}, + {0x1F98, 13}, {0x1F99, 13}, {0x1F9A, 13}, {0x1F9B, 13}, + {0x1F9C, 13}, {0x1F9D, 13}, {0x1F9E, 13}, {0x1F9F, 13}, + {0x1FA0, 13}, {0x1FA1, 13}, {0x1FA2, 13}, {0x1FA3, 13}, + {0x1FA4, 13}, {0x1FA5, 13}, {0x1FA6, 13}, {0x1FA7, 13}, + {0x1FA8, 13}, {0x1FA9, 13}, {0x1FAA, 13}, {0x1FAB, 13}, + {0x1FAC, 13}, {0x1FAD, 13}, {0x1FAE, 13}, {0x1FAF, 13}, + {0x1FB0, 13}, {0x1FB1, 13}, {0x1FB2, 13}, {0x1FB3, 13}, + {0x1FB4, 13}, {0x1FB5, 13}, {0x1FB6, 13}, {0x1FB7, 13}, + {0x1FB8, 13}, {0x1FB9, 13}, {0x1FBA, 13}, {0x1FBB, 13}, + {0x1FBC, 13}, {0x1FBD, 13}, {0x1FBE, 13}, {0x1FBF, 13}, + {0x3F80, 14}, {0x3F81, 14}, {0x3F82, 14}, {0x3F83, 14}, + {0x3F84, 14}, {0x3F85, 14}, {0x3F86, 14}, {0x3F87, 14}, + {0x3F88, 14}, {0x3F89, 14}, {0x3F8A, 14}, {0x0002, 3}, + {0x0011, 5}, {0x0014, 5}, {0x0015, 5}, {0x0030, 6}, + {0x0037, 6}, {0x00E2, 8}, {0x00E3, 8}, {0x00E8, 8}, + {0x00EB, 8}, {0x00EE, 8}, {0x01E1, 9}, {0x01E4, 9}, + {0x01E7, 9}, {0x01EA, 9}, {0x01ED, 9} +#endif +}; + +static const uint8_t ir2_luma_table[256] = { + 0x80, 0x80, 0x84, 0x84, 0x7C, 0x7C, 0x7F, 0x85, + 0x81, 0x7B, 0x85, 0x7F, 0x7B, 0x81, 0x8C, 0x8C, + 0x74, 0x74, 0x83, 0x8D, 0x7D, 0x73, 0x8D, 0x83, + 0x73, 0x7D, 0x77, 0x89, 0x89, 0x77, 0x89, 0x77, + 0x77, 0x89, 0x8C, 0x95, 0x74, 0x6B, 0x95, 0x8C, + 0x6B, 0x74, 0x7C, 0x90, 0x84, 0x70, 0x90, 0x7C, + 0x70, 0x84, 0x96, 0x96, 0x6A, 0x6A, 0x82, 0x98, + 0x7E, 0x68, 0x98, 0x82, 0x68, 0x7E, 0x97, 0xA2, + 0x69, 0x5E, 0xA2, 0x97, 0x5E, 0x69, 0xA2, 0xA2, + 0x5E, 0x5E, 0x8B, 0xA3, 0x75, 0x5D, 0xA3, 0x8B, + 0x5D, 0x75, 0x71, 0x95, 0x8F, 0x6B, 0x95, 0x71, + 0x6B, 0x8F, 0x78, 0x9D, 0x88, 0x63, 0x9D, 0x78, + 0x63, 0x88, 0x7F, 0xA7, 0x81, 0x59, 0xA7, 0x7F, + 0x59, 0x81, 0xA4, 0xB1, 0x5C, 0x4F, 0xB1, 0xA4, + 0x4F, 0x5C, 0x96, 0xB1, 0x6A, 0x4F, 0xB1, 0x96, + 0x4F, 0x6A, 0xB2, 0xB2, 0x4E, 0x4E, 0x65, 0x9B, + 0x9B, 0x65, 0x9B, 0x65, 0x65, 0x9B, 0x89, 0xB4, + 0x77, 0x4C, 0xB4, 0x89, 0x4C, 0x77, 0x6A, 0xA3, + 0x96, 0x5D, 0xA3, 0x6A, 0x5D, 0x96, 0x73, 0xAC, + 0x8D, 0x54, 0xAC, 0x73, 0x54, 0x8D, 0xB4, 0xC3, + 0x4C, 0x3D, 0xC3, 0xB4, 0x3D, 0x4C, 0xA4, 0xC3, + 0x5C, 0x3D, 0xC3, 0xA4, 0x3D, 0x5C, 0xC4, 0xC4, + 0x3C, 0x3C, 0x96, 0xC6, 0x6A, 0x3A, 0xC6, 0x96, + 0x3A, 0x6A, 0x7C, 0xBA, 0x84, 0x46, 0xBA, 0x7C, + 0x46, 0x84, 0x5B, 0xAB, 0xA5, 0x55, 0xAB, 0x5B, + 0x55, 0xA5, 0x63, 0xB4, 0x9D, 0x4C, 0xB4, 0x63, + 0x4C, 0x9D, 0x86, 0xCA, 0x7A, 0x36, 0xCA, 0x86, + 0x36, 0x7A, 0xB6, 0xD7, 0x4A, 0x29, 0xD7, 0xB6, + 0x29, 0x4A, 0xC8, 0xD7, 0x38, 0x29, 0xD7, 0xC8, + 0x29, 0x38, 0xA4, 0xD8, 0x5C, 0x28, 0xD8, 0xA4, + 0x28, 0x5C, 0x6C, 0xC1, 0x94, 0x3F, 0xC1, 0x6C, + 0x3F, 0x94, 0xD9, 0xD9, 0x27, 0x27, 0x80, 0x80 +}; diff --git a/mpeg4/src/libavcodec/indeo3.c b/mpeg4/src/libavcodec/indeo3.c new file mode 100644 index 00000000..90eb3715 --- /dev/null +++ b/mpeg4/src/libavcodec/indeo3.c @@ -0,0 +1,1151 @@ +/* + * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg + * written, produced, and directed by Alan Smithee + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include "common.h" +#include "avcodec.h" +#include "dsputil.h" +#include "mpegvideo.h" + +#include "indeo3data.h" + +typedef struct +{ + unsigned char *Ybuf; + unsigned char *Ubuf; + unsigned char *Vbuf; + unsigned char *the_buf; + unsigned int the_buf_size; + unsigned short y_w, y_h; + unsigned short uv_w, uv_h; +} YUVBufs; + +typedef struct Indeo3DecodeContext { + AVCodecContext *avctx; + int width, height; + AVFrame frame; + + YUVBufs iv_frame[2]; + YUVBufs *cur_frame; + YUVBufs *ref_frame; + + unsigned char *ModPred; + unsigned short *corrector_type; +} Indeo3DecodeContext; + +static int corrector_type_0[24] = { + 195, 159, 133, 115, 101, 93, 87, 77, + 195, 159, 133, 115, 101, 93, 87, 77, + 128, 79, 79, 79, 79, 79, 79, 79 +}; + +static int corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 }; + +static void build_modpred(Indeo3DecodeContext *s) +{ + int i, j; + + s->ModPred = (unsigned char *) av_malloc (8 * 128); + + for (i=0; i < 128; ++i) { + s->ModPred[i+0*128] = (i > 126) ? 254 : 2*((i + 1) - ((i + 1) % 2)); + s->ModPred[i+1*128] = (i == 7) ? 20 : ((i == 119 || i == 120) + ? 236 : 2*((i + 2) - ((i + 1) % 3))); + s->ModPred[i+2*128] = (i > 125) ? 248 : 2*((i + 2) - ((i + 2) % 4)); + s->ModPred[i+3*128] = 2*((i + 1) - ((i - 3) % 5)); + s->ModPred[i+4*128] = (i == 8) ? 20 : 2*((i + 1) - ((i - 3) % 6)); + s->ModPred[i+5*128] = 2*((i + 4) - ((i + 3) % 7)); + s->ModPred[i+6*128] = (i > 123) ? 240 : 2*((i + 4) - ((i + 4) % 8)); + s->ModPred[i+7*128] = 2*((i + 5) - ((i + 4) % 9)); + } + + s->corrector_type = (unsigned short *) av_malloc (24 * 256 * sizeof(unsigned short)); + + for (i=0; i < 24; ++i) { + for (j=0; j < 256; ++j) { + s->corrector_type[i*256+j] = (j < corrector_type_0[i]) + ? 1 : ((j < 248 || (i == 16 && j == 248)) + ? 0 : corrector_type_2[j - 248]); + } + } +} + +static void iv_Decode_Chunk(Indeo3DecodeContext *s, unsigned char *cur, + unsigned char *ref, int width, int height, unsigned char *buf1, + long fflags2, unsigned char *hdr, + unsigned char *buf2, int min_width_160); + +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +/* ---------------------------------------------------------------------- */ +static void iv_alloc_frames(Indeo3DecodeContext *s) +{ + int luma_width, luma_height, luma_pixels, chroma_width, chroma_height, + chroma_pixels, i; + unsigned int bufsize; + + luma_width = (s->width + 3) & (~3); + luma_height = (s->height + 3) & (~3); + + s->iv_frame[0].y_w = s->iv_frame[0].y_h = + s->iv_frame[0].the_buf_size = 0; + s->iv_frame[1].y_w = s->iv_frame[1].y_h = + s->iv_frame[1].the_buf_size = 0; + s->iv_frame[1].the_buf = NULL; + + chroma_width = ((luma_width >> 2) + 3) & (~3); + chroma_height = ((luma_height>> 2) + 3) & (~3); + luma_pixels = luma_width * luma_height; + chroma_pixels = chroma_width * chroma_height; + + bufsize = luma_pixels * 2 + luma_width * 3 + + (chroma_pixels + chroma_width) * 4; + + if((s->iv_frame[0].the_buf = + (s->iv_frame[0].the_buf_size == 0 ? av_malloc(bufsize) : + av_realloc(s->iv_frame[0].the_buf, bufsize))) == NULL) + return; + s->iv_frame[0].y_w = s->iv_frame[1].y_w = luma_width; + s->iv_frame[0].y_h = s->iv_frame[1].y_h = luma_height; + s->iv_frame[0].uv_w = s->iv_frame[1].uv_w = chroma_width; + s->iv_frame[0].uv_h = s->iv_frame[1].uv_h = chroma_height; + s->iv_frame[0].the_buf_size = bufsize; + + s->iv_frame[0].Ybuf = s->iv_frame[0].the_buf + luma_width; + i = luma_pixels + luma_width * 2; + s->iv_frame[1].Ybuf = s->iv_frame[0].the_buf + i; + i += (luma_pixels + luma_width); + s->iv_frame[0].Ubuf = s->iv_frame[0].the_buf + i; + i += (chroma_pixels + chroma_width); + s->iv_frame[1].Ubuf = s->iv_frame[0].the_buf + i; + i += (chroma_pixels + chroma_width); + s->iv_frame[0].Vbuf = s->iv_frame[0].the_buf + i; + i += (chroma_pixels + chroma_width); + s->iv_frame[1].Vbuf = s->iv_frame[0].the_buf + i; + + for(i = 1; i <= luma_width; i++) + s->iv_frame[0].Ybuf[-i] = s->iv_frame[1].Ybuf[-i] = + s->iv_frame[0].Ubuf[-i] = 0x80; + + for(i = 1; i <= chroma_width; i++) { + s->iv_frame[1].Ubuf[-i] = 0x80; + s->iv_frame[0].Vbuf[-i] = 0x80; + s->iv_frame[1].Vbuf[-i] = 0x80; + s->iv_frame[1].Vbuf[chroma_pixels+i-1] = 0x80; + } +} + +/* ---------------------------------------------------------------------- */ +static void iv_free_func(Indeo3DecodeContext *s) +{ + int i; + + for(i = 0 ; i < 2 ; i++) { + if(s->iv_frame[i].the_buf != NULL) + av_free(s->iv_frame[i].the_buf); + s->iv_frame[i].Ybuf = s->iv_frame[i].Ubuf = + s->iv_frame[i].Vbuf = NULL; + s->iv_frame[i].the_buf = NULL; + s->iv_frame[i].the_buf_size = 0; + s->iv_frame[i].y_w = s->iv_frame[i].y_h = 0; + s->iv_frame[i].uv_w = s->iv_frame[i].uv_h = 0; + } + + av_free(s->ModPred); + av_free(s->corrector_type); +} + +/* ---------------------------------------------------------------------- */ +static unsigned long iv_decode_frame(Indeo3DecodeContext *s, + unsigned char *buf, int buf_size) +{ + unsigned int hdr_width, hdr_height, + chroma_width, chroma_height; + unsigned long fflags1, fflags2, fflags3, offs1, offs2, offs3, offs; + unsigned char *hdr_pos, *buf_pos; + + buf_pos = buf; + buf_pos += 18; + + fflags1 = le2me_16(*(uint16_t *)buf_pos); + buf_pos += 2; + fflags3 = le2me_32(*(uint32_t *)buf_pos); + buf_pos += 4; + fflags2 = *buf_pos++; + buf_pos += 3; + hdr_height = le2me_16(*(uint16_t *)buf_pos); + buf_pos += 2; + hdr_width = le2me_16(*(uint16_t *)buf_pos); + + if(avcodec_check_dimensions(NULL, hdr_width, hdr_height)) + return -1; + + buf_pos += 2; + chroma_height = ((hdr_height >> 2) + 3) & 0x7ffc; + chroma_width = ((hdr_width >> 2) + 3) & 0x7ffc; + offs1 = le2me_32(*(uint32_t *)buf_pos); + buf_pos += 4; + offs2 = le2me_32(*(uint32_t *)buf_pos); + buf_pos += 4; + offs3 = le2me_32(*(uint32_t *)buf_pos); + buf_pos += 8; + hdr_pos = buf_pos; + if(fflags3 == 0x80) return 4; + + if(fflags1 & 0x200) { + s->cur_frame = s->iv_frame + 1; + s->ref_frame = s->iv_frame; + } else { + s->cur_frame = s->iv_frame; + s->ref_frame = s->iv_frame + 1; + } + + buf_pos = buf + 16 + offs1; + offs = le2me_32(*(uint32_t *)buf_pos); + buf_pos += 4; + + iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, hdr_width, + hdr_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, + min(hdr_width, 160)); + + if (!(s->avctx->flags & CODEC_FLAG_GRAY)) + { + + buf_pos = buf + 16 + offs2; + offs = le2me_32(*(uint32_t *)buf_pos); + buf_pos += 4; + + iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width, + chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, + min(chroma_width, 40)); + + buf_pos = buf + 16 + offs3; + offs = le2me_32(*(uint32_t *)buf_pos); + buf_pos += 4; + + iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width, + chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, + min(chroma_width, 40)); + + } + + return 8; +} + +typedef struct { + long xpos; + long ypos; + long width; + long height; + long split_flag; + long split_direction; + long usl7; +} ustr_t; + +/* ---------------------------------------------------------------------- */ + +#define LV1_CHECK(buf1,rle_v3,lv1,lp2) \ + if((lv1 & 0x80) != 0) { \ + if(rle_v3 != 0) \ + rle_v3 = 0; \ + else { \ + rle_v3 = 1; \ + buf1 -= 2; \ + } \ + } \ + lp2 = 4; + + +#define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) \ + if(rle_v3 == 0) { \ + rle_v2 = *buf1; \ + rle_v1 = 1; \ + if(rle_v2 > 32) { \ + rle_v2 -= 32; \ + rle_v1 = 0; \ + } \ + rle_v3 = 1; \ + } \ + buf1--; + + +#define LP2_CHECK(buf1,rle_v3,lp2) \ + if(lp2 == 0 && rle_v3 != 0) \ + rle_v3 = 0; \ + else { \ + buf1--; \ + rle_v3 = 1; \ + } + + +#define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \ + rle_v2--; \ + if(rle_v2 == 0) { \ + rle_v3 = 0; \ + buf1 += 2; \ + } \ + lp2 = 4; + +static void iv_Decode_Chunk(Indeo3DecodeContext *s, + unsigned char *cur, unsigned char *ref, int width, int height, + unsigned char *buf1, long fflags2, unsigned char *hdr, + unsigned char *buf2, int min_width_160) +{ + unsigned char bit_buf; + unsigned long bit_pos, lv, lv1, lv2; + long *width_tbl, width_tbl_arr[10]; + signed char *ref_vectors; + unsigned char *cur_frm_pos, *ref_frm_pos, *cp, *cp2; + uint32_t *cur_lp, *ref_lp; + const uint32_t *correction_lp[2], *correctionloworder_lp[2], *correctionhighorder_lp[2]; + unsigned short *correction_type_sp[2]; + ustr_t strip_tbl[20], *strip; + int i, j, k, lp1, lp2, flag1, cmd, blks_width, blks_height, region_160_width, + rle_v1, rle_v2, rle_v3; + unsigned short res; + + bit_buf = 0; + ref_vectors = NULL; + + width_tbl = width_tbl_arr + 1; + i = (width < 0 ? width + 3 : width)/4; + for(j = -1; j < 8; j++) + width_tbl[j] = i * j; + + strip = strip_tbl; + + for(region_160_width = 0; region_160_width < (width - min_width_160); region_160_width += min_width_160); + + strip->ypos = strip->xpos = 0; + for(strip->width = min_width_160; width > strip->width; strip->width *= 2); + strip->height = height; + strip->split_direction = 0; + strip->split_flag = 0; + strip->usl7 = 0; + + bit_pos = 0; + + rle_v1 = rle_v2 = rle_v3 = 0; + + while(strip >= strip_tbl) { + if(bit_pos <= 0) { + bit_pos = 8; + bit_buf = *buf1++; + } + + bit_pos -= 2; + cmd = (bit_buf >> bit_pos) & 0x03; + + if(cmd == 0) { + strip++; + memcpy(strip, strip-1, sizeof(ustr_t)); + strip->split_flag = 1; + strip->split_direction = 0; + strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4); + continue; + } else if(cmd == 1) { + strip++; + memcpy(strip, strip-1, sizeof(ustr_t)); + strip->split_flag = 1; + strip->split_direction = 1; + strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4); + continue; + } else if(cmd == 2) { + if(strip->usl7 == 0) { + strip->usl7 = 1; + ref_vectors = NULL; + continue; + } + } else if(cmd == 3) { + if(strip->usl7 == 0) { + strip->usl7 = 1; + ref_vectors = buf2 + (*buf1 * 2); + buf1++; + continue; + } + } + + cur_frm_pos = cur + width * strip->ypos + strip->xpos; + + if((blks_width = strip->width) < 0) + blks_width += 3; + blks_width >>= 2; + blks_height = strip->height; + + if(ref_vectors != NULL) { + ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width + + ref_vectors[1] + strip->xpos; + } else + ref_frm_pos = cur_frm_pos - width_tbl[4]; + + if(cmd == 2) { + if(bit_pos <= 0) { + bit_pos = 8; + bit_buf = *buf1++; + } + + bit_pos -= 2; + cmd = (bit_buf >> bit_pos) & 0x03; + + if(cmd == 0 || ref_vectors != NULL) { + for(lp1 = 0; lp1 < blks_width; lp1++) { + for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1]) + ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j]; + cur_frm_pos += 4; + ref_frm_pos += 4; + } + } else if(cmd != 1) + return; + } else { + k = *buf1 >> 4; + j = *buf1 & 0x0f; + buf1++; + lv = j + fflags2; + + if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) { + cp2 = s->ModPred + ((lv - 8) << 7); + cp = ref_frm_pos; + for(i = 0; i < blks_width << 2; i++) { + int v = *cp >> 1; + *(cp++) = cp2[v]; + } + } + + if(k == 1 || k == 4) { + lv = (hdr[j] & 0xf) + fflags2; + correction_type_sp[0] = s->corrector_type + (lv << 8); + correction_lp[0] = correction + (lv << 8); + lv = (hdr[j] >> 4) + fflags2; + correction_lp[1] = correction + (lv << 8); + correction_type_sp[1] = s->corrector_type + (lv << 8); + } else { + correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8); + correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8); + correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8); + correction_lp[0] = correction_lp[1] = correction + (lv << 8); + } + + switch(k) { + case 1: + case 0: /********** CASE 0 **********/ + for( ; blks_height > 0; blks_height -= 4) { + for(lp1 = 0; lp1 < blks_width; lp1++) { + for(lp2 = 0; lp2 < 4; ) { + k = *buf1++; + cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2]; + ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2]; + + switch(correction_type_sp[0][k]) { + case 0: + *cur_lp = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); + lp2++; + break; + case 1: + res = ((le2me_16(((unsigned short *)(ref_lp))[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1; + ((unsigned short *)cur_lp)[0] = le2me_16(res); + res = ((le2me_16(((unsigned short *)(ref_lp))[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1; + ((unsigned short *)cur_lp)[1] = le2me_16(res); + buf1++; + lp2++; + break; + case 2: + if(lp2 == 0) { + for(i = 0, j = 0; i < 2; i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + lp2 += 2; + } + break; + case 3: + if(lp2 < 2) { + for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + lp2 = 3; + } + break; + case 8: + if(lp2 == 0) { + RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) + + if(rle_v1 == 1 || ref_vectors != NULL) { + for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + } + + RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) + break; + } else { + rle_v1 = 1; + rle_v2 = *buf1 - 1; + } + case 5: + LP2_CHECK(buf1,rle_v3,lp2) + case 4: + for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + lp2 = 4; + break; + + case 7: + if(rle_v3 != 0) + rle_v3 = 0; + else { + buf1--; + rle_v3 = 1; + } + case 6: + if(ref_vectors != NULL) { + for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + } + lp2 = 4; + break; + + case 9: + lv1 = *buf1++; + lv = (lv1 & 0x7F) << 1; + lv += (lv << 8); + lv += (lv << 16); + for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) + cur_lp[j] = lv; + + LV1_CHECK(buf1,rle_v3,lv1,lp2) + break; + default: + return; + } + } + + cur_frm_pos += 4; + ref_frm_pos += 4; + } + + cur_frm_pos += ((width - blks_width) * 4); + ref_frm_pos += ((width - blks_width) * 4); + } + break; + + case 4: + case 3: /********** CASE 3 **********/ + if(ref_vectors != NULL) + return; + flag1 = 1; + + for( ; blks_height > 0; blks_height -= 8) { + for(lp1 = 0; lp1 < blks_width; lp1++) { + for(lp2 = 0; lp2 < 4; ) { + k = *buf1++; + + cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2]; + ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1]; + + switch(correction_type_sp[lp2 & 0x01][k]) { + case 0: + cur_lp[width_tbl[1]] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); + if(lp2 > 0 || flag1 == 0 || strip->ypos != 0) + cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; + else + cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); + lp2++; + break; + + case 1: + res = ((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1; + ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res); + res = ((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1; + ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res); + + if(lp2 > 0 || flag1 == 0 || strip->ypos != 0) + cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; + else + cur_lp[0] = cur_lp[width_tbl[1]]; + buf1++; + lp2++; + break; + + case 2: + if(lp2 == 0) { + for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) + cur_lp[j] = *ref_lp; + lp2 += 2; + } + break; + + case 3: + if(lp2 < 2) { + for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) + cur_lp[j] = *ref_lp; + lp2 = 3; + } + break; + + case 6: + lp2 = 4; + break; + + case 7: + if(rle_v3 != 0) + rle_v3 = 0; + else { + buf1--; + rle_v3 = 1; + } + lp2 = 4; + break; + + case 8: + if(lp2 == 0) { + RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) + + if(rle_v1 == 1) { + for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + } + + RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) + break; + } else { + rle_v2 = (*buf1) - 1; + rle_v1 = 1; + } + case 5: + LP2_CHECK(buf1,rle_v3,lp2) + case 4: + for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) + cur_lp[j] = *ref_lp; + lp2 = 4; + break; + + case 9: + av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n"); + lv1 = *buf1++; + lv = (lv1 & 0x7F) << 1; + lv += (lv << 8); + lv += (lv << 16); + + for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) + cur_lp[j] = lv; + + LV1_CHECK(buf1,rle_v3,lv1,lp2) + break; + + default: + return; + } + } + + cur_frm_pos += 4; + } + + cur_frm_pos += (((width * 2) - blks_width) * 4); + flag1 = 0; + } + break; + + case 10: /********** CASE 10 **********/ + if(ref_vectors == NULL) { + flag1 = 1; + + for( ; blks_height > 0; blks_height -= 8) { + for(lp1 = 0; lp1 < blks_width; lp1 += 2) { + for(lp2 = 0; lp2 < 4; ) { + k = *buf1++; + cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2]; + ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1]; + lv1 = ref_lp[0]; + lv2 = ref_lp[1]; + if(lp2 == 0 && flag1 != 0) { +#ifdef WORDS_BIGENDIAN + lv1 = lv1 & 0xFF00FF00; + lv1 = (lv1 >> 8) | lv1; + lv2 = lv2 & 0xFF00FF00; + lv2 = (lv2 >> 8) | lv2; +#else + lv1 = lv1 & 0x00FF00FF; + lv1 = (lv1 << 8) | lv1; + lv2 = lv2 & 0x00FF00FF; + lv2 = (lv2 << 8) | lv2; +#endif + } + + switch(correction_type_sp[lp2 & 0x01][k]) { + case 0: + cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1); + cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1); + if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) { + cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; + cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; + } else { + cur_lp[0] = cur_lp[width_tbl[1]]; + cur_lp[1] = cur_lp[width_tbl[1]+1]; + } + lp2++; + break; + + case 1: + cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1]) << 1); + cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1); + if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) { + cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; + cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; + } else { + cur_lp[0] = cur_lp[width_tbl[1]]; + cur_lp[1] = cur_lp[width_tbl[1]+1]; + } + buf1++; + lp2++; + break; + + case 2: + if(lp2 == 0) { + if(flag1 != 0) { + for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) { + cur_lp[j] = lv1; + cur_lp[j+1] = lv2; + } + cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; + cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; + } else { + for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) { + cur_lp[j] = lv1; + cur_lp[j+1] = lv2; + } + } + lp2 += 2; + } + break; + + case 3: + if(lp2 < 2) { + if(lp2 == 0 && flag1 != 0) { + for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) { + cur_lp[j] = lv1; + cur_lp[j+1] = lv2; + } + cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; + cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; + } else { + for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) { + cur_lp[j] = lv1; + cur_lp[j+1] = lv2; + } + } + lp2 = 3; + } + break; + + case 8: + if(lp2 == 0) { + RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) + if(rle_v1 == 1) { + if(flag1 != 0) { + for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) { + cur_lp[j] = lv1; + cur_lp[j+1] = lv2; + } + cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; + cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; + } else { + for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) { + cur_lp[j] = lv1; + cur_lp[j+1] = lv2; + } + } + } + RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) + break; + } else { + rle_v1 = 1; + rle_v2 = (*buf1) - 1; + } + case 5: + LP2_CHECK(buf1,rle_v3,lp2) + case 4: + if(lp2 == 0 && flag1 != 0) { + for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) { + cur_lp[j] = lv1; + cur_lp[j+1] = lv2; + } + cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE; + cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE; + } else { + for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) { + cur_lp[j] = lv1; + cur_lp[j+1] = lv2; + } + } + lp2 = 4; + break; + + case 6: + lp2 = 4; + break; + + case 7: + if(lp2 == 0) { + if(rle_v3 != 0) + rle_v3 = 0; + else { + buf1--; + rle_v3 = 1; + } + lp2 = 4; + } + break; + + case 9: + av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n"); + lv1 = *buf1; + lv = (lv1 & 0x7F) << 1; + lv += (lv << 8); + lv += (lv << 16); + for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) + cur_lp[j] = lv; + LV1_CHECK(buf1,rle_v3,lv1,lp2) + break; + + default: + return; + } + } + + cur_frm_pos += 8; + } + + cur_frm_pos += (((width * 2) - blks_width) * 4); + flag1 = 0; + } + } else { + for( ; blks_height > 0; blks_height -= 8) { + for(lp1 = 0; lp1 < blks_width; lp1 += 2) { + for(lp2 = 0; lp2 < 4; ) { + k = *buf1++; + cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2]; + ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2]; + + switch(correction_type_sp[lp2 & 0x01][k]) { + case 0: + lv1 = correctionloworder_lp[lp2 & 0x01][k]; + lv2 = correctionhighorder_lp[lp2 & 0x01][k]; + cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1); + cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1); + cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1); + cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1); + lp2++; + break; + + case 1: + lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++]; + lv2 = correctionloworder_lp[lp2 & 0x01][k]; + cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1); + cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1); + cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1); + cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1); + lp2++; + break; + + case 2: + if(lp2 == 0) { + for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) { + cur_lp[j] = ref_lp[j]; + cur_lp[j+1] = ref_lp[j+1]; + } + lp2 += 2; + } + break; + + case 3: + if(lp2 < 2) { + for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) { + cur_lp[j] = ref_lp[j]; + cur_lp[j+1] = ref_lp[j+1]; + } + lp2 = 3; + } + break; + + case 8: + if(lp2 == 0) { + RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) + for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) { + ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j]; + ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1]; + } + RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) + break; + } else { + rle_v1 = 1; + rle_v2 = (*buf1) - 1; + } + case 5: + case 7: + LP2_CHECK(buf1,rle_v3,lp2) + case 6: + case 4: + for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) { + cur_lp[j] = ref_lp[j]; + cur_lp[j+1] = ref_lp[j+1]; + } + lp2 = 4; + break; + + case 9: + av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n"); + lv1 = *buf1; + lv = (lv1 & 0x7F) << 1; + lv += (lv << 8); + lv += (lv << 16); + for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) + ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv; + LV1_CHECK(buf1,rle_v3,lv1,lp2) + break; + + default: + return; + } + } + + cur_frm_pos += 8; + ref_frm_pos += 8; + } + + cur_frm_pos += (((width * 2) - blks_width) * 4); + ref_frm_pos += (((width * 2) - blks_width) * 4); + } + } + break; + + case 11: /********** CASE 11 **********/ + if(ref_vectors == NULL) + return; + + for( ; blks_height > 0; blks_height -= 8) { + for(lp1 = 0; lp1 < blks_width; lp1++) { + for(lp2 = 0; lp2 < 4; ) { + k = *buf1++; + cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2]; + ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2]; + + switch(correction_type_sp[lp2 & 0x01][k]) { + case 0: + cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); + cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1); + lp2++; + break; + + case 1: + lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]); + lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]); + res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + lv1) << 1); + ((unsigned short *)cur_lp)[0] = le2me_16(res); + res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + lv2) << 1); + ((unsigned short *)cur_lp)[1] = le2me_16(res); + res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]]) >> 1) + lv1) << 1); + ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res); + res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]+1]) >> 1) + lv2) << 1); + ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res); + lp2++; + break; + + case 2: + if(lp2 == 0) { + for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + lp2 += 2; + } + break; + + case 3: + if(lp2 < 2) { + for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + lp2 = 3; + } + break; + + case 8: + if(lp2 == 0) { + RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) + + for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + + RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) + break; + } else { + rle_v1 = 1; + rle_v2 = (*buf1) - 1; + } + case 5: + case 7: + LP2_CHECK(buf1,rle_v3,lp2) + case 4: + case 6: + for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) + cur_lp[j] = ref_lp[j]; + lp2 = 4; + break; + + case 9: + av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n"); + lv1 = *buf1++; + lv = (lv1 & 0x7F) << 1; + lv += (lv << 8); + lv += (lv << 16); + for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) + cur_lp[j] = lv; + LV1_CHECK(buf1,rle_v3,lv1,lp2) + break; + + default: + return; + } + } + + cur_frm_pos += 4; + ref_frm_pos += 4; + } + + cur_frm_pos += (((width * 2) - blks_width) * 4); + ref_frm_pos += (((width * 2) - blks_width) * 4); + } + break; + + default: + return; + } + } + + if(strip < strip_tbl) + return; + + for( ; strip >= strip_tbl; strip--) { + if(strip->split_flag != 0) { + strip->split_flag = 0; + strip->usl7 = (strip-1)->usl7; + + if(strip->split_direction) { + strip->xpos += strip->width; + strip->width = (strip-1)->width - strip->width; + if(region_160_width <= strip->xpos && width < strip->width + strip->xpos) + strip->width = width - strip->xpos; + } else { + strip->ypos += strip->height; + strip->height = (strip-1)->height - strip->height; + } + break; + } + } + } +} + +static int indeo3_decode_init(AVCodecContext *avctx) +{ + Indeo3DecodeContext *s = avctx->priv_data; + + s->avctx = avctx; + s->width = avctx->width; + s->height = avctx->height; + avctx->pix_fmt = PIX_FMT_YUV410P; + avctx->has_b_frames = 0; + + build_modpred(s); + iv_alloc_frames(s); + + return 0; +} + +static int indeo3_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + unsigned char *buf, int buf_size) +{ + Indeo3DecodeContext *s=avctx->priv_data; + unsigned char *src, *dest; + int y; + + iv_decode_frame(s, buf, buf_size); + + if(s->frame.data[0]) + avctx->release_buffer(avctx, &s->frame); + + s->frame.reference = 0; + if(avctx->get_buffer(avctx, &s->frame) < 0) { + av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + src = s->cur_frame->Ybuf; + dest = s->frame.data[0]; + for (y = 0; y < s->height; y++) { + memcpy(dest, src, s->cur_frame->y_w); + src += s->cur_frame->y_w; + dest += s->frame.linesize[0]; + } + + if (!(s->avctx->flags & CODEC_FLAG_GRAY)) + { + src = s->cur_frame->Ubuf; + dest = s->frame.data[1]; + for (y = 0; y < s->height / 4; y++) { + memcpy(dest, src, s->cur_frame->uv_w); + src += s->cur_frame->uv_w; + dest += s->frame.linesize[1]; + } + + src = s->cur_frame->Vbuf; + dest = s->frame.data[2]; + for (y = 0; y < s->height / 4; y++) { + memcpy(dest, src, s->cur_frame->uv_w); + src += s->cur_frame->uv_w; + dest += s->frame.linesize[2]; + } + } + + *data_size=sizeof(AVFrame); + *(AVFrame*)data= s->frame; + + return buf_size; +} + +static int indeo3_decode_end(AVCodecContext *avctx) +{ + Indeo3DecodeContext *s = avctx->priv_data; + + iv_free_func(s); + + return 0; +} + +AVCodec indeo3_decoder = { + "indeo3", + CODEC_TYPE_VIDEO, + CODEC_ID_INDEO3, + sizeof(Indeo3DecodeContext), + indeo3_decode_init, + NULL, + indeo3_decode_end, + indeo3_decode_frame, + 0, + NULL +}; diff --git a/mpeg4/src/libavcodec/indeo3data.h b/mpeg4/src/libavcodec/indeo3data.h new file mode 100644 index 00000000..77bbc07b --- /dev/null +++ b/mpeg4/src/libavcodec/indeo3data.h @@ -0,0 +1,2315 @@ + +static const uint32_t correction[] = { + 0x00000000, 0x00000202, 0xfffffdfe, 0x000002ff, 0xfffffd01, 0xffffff03, 0x000000fd, 0x00000404, + 0xfffffbfc, 0x00000501, 0xfffffaff, 0x00000105, 0xfffffefb, 0x000003fc, 0xfffffc04, 0x000005fe, + 0xfffffa02, 0xfffffe06, 0x000001fa, 0x00000904, 0xfffff6fc, 0x00000409, 0xfffffbf7, 0x00000909, + 0xfffff6f7, 0x00000a01, 0xfffff5ff, 0x0000010a, 0xfffffef6, 0x000007fb, 0xfffff805, 0xfffffb08, + 0x000004f8, 0x00000f09, 0xfffff0f7, 0x0000090f, 0xfffff6f1, 0x00000bfd, 0xfffff403, 0xfffffd0c, + 0x000002f4, 0x00001004, 0xffffeffc, 0x00000410, 0xfffffbf0, 0x00001010, 0xffffeff0, 0x00001200, + 0xffffee00, 0x00000012, 0xffffffee, 0x00000bf4, 0xfffff40c, 0x00000ff7, 0xfffff009, 0xfffff710, + 0x000008f0, 0x00001b0b, 0xffffe4f5, 0x00000b1b, 0xfffff4e5, 0x00001c13, 0xffffe3ed, 0x0000131c, + 0xffffece4, 0x000015fa, 0xffffea06, 0xfffffa16, 0x000005ea, 0x00001d04, 0xffffe2fc, 0x0000041d, + 0xfffffbe3, 0x00001e1e, 0xffffe1e2, 0x000020fe, 0xffffdf02, 0xfffffe21, 0x000001df, 0x000016ee, + 0xffffe912, 0xffffee17, 0x000011e9, 0x00001df1, 0xffffe20f, 0xfffff11e, 0x00000ee2, 0x00002e16, + 0xffffd1ea, 0x0000162e, 0xffffe9d2, 0x00002f0d, 0xffffd0f3, 0x00000d2f, 0xfffff2d1, 0x00003123, + 0xffffcedd, 0x00002331, 0xffffdccf, 0x000028f5, 0xffffd70b, 0xfffff529, 0x00000ad7, 0x00003304, + 0xffffccfc, 0x00000433, 0xfffffbcd, 0x00003636, 0xffffc9ca, 0x000021de, 0xffffde22, 0x000029e3, + 0xffffd61d, 0xffffe32a, 0x00001cd6, 0x00003bfa, 0xffffc406, 0xfffffa3c, 0x000005c4, 0x00004c1b, + 0xffffb3e5, 0x00001b4c, 0xffffe4b4, 0x00004d2b, 0xffffb2d5, 0x00002b4d, 0xffffd4b3, 0x000036e8, + 0xffffc918, 0xffffe837, 0x000017c9, 0x00004f0e, 0xffffb0f2, 0x00000e4f, 0xfffff1b1, 0x0000533f, + 0xffffacc1, 0x00003f53, 0xffffc0ad, 0x000049ec, 0xffffb614, 0xffffec4a, 0x000013b6, 0x00005802, + 0xffffa7fe, 0x00000258, 0xfffffda8, 0x00005d5d, 0xffffa2a3, 0x00003ccc, 0xffffc334, 0xffffcc3d, + 0x000033c3, 0x00007834, 0xffff87cc, 0x00003478, 0xffffcb88, 0x00004ad3, 0xffffb52d, 0xffffd34b, + 0x00002cb5, 0x00007d4b, 0xffff82b5, 0x00004b7d, 0xffffb483, 0x00007a21, 0xffff85df, 0x0000217a, + 0xffffde86, 0x000066f3, 0xffff990d, 0xfffff367, 0x00000c99, 0x00005fd8, 0xffffa028, 0xffffd860, + 0x000027a0, 0x00007ede, 0xffff8122, 0xffffde7f, 0x00002181, 0x000058a7, 0xffffa759, 0x000068b2, + 0xffff974e, 0xffffb269, 0x00004d97, 0x00000c0c, 0xfffff3f4, 0x00001717, 0xffffe8e9, 0x00002a2a, + 0xffffd5d6, 0x00004949, 0xffffb6b7, 0x00000000, 0x02020000, 0xfdfe0000, 0x02ff0000, 0xfd010000, + 0xff030000, 0x00fd0000, 0x00000202, 0x02020202, 0xfdfe0202, 0x02ff0202, 0xfd010202, 0xff030202, + 0x00fd0202, 0xfffffdfe, 0x0201fdfe, 0xfdfdfdfe, 0x02fefdfe, 0xfd00fdfe, 0xff02fdfe, 0x00fcfdfe, + 0x000002ff, 0x020202ff, 0xfdfe02ff, 0x02ff02ff, 0xfd0102ff, 0xff0302ff, 0x00fd02ff, 0xfffffd01, + 0x0201fd01, 0xfdfdfd01, 0x02fefd01, 0xfd00fd01, 0xff02fd01, 0x00fcfd01, 0xffffff03, 0x0201ff03, + 0xfdfdff03, 0x02feff03, 0xfd00ff03, 0xff02ff03, 0x00fcff03, 0x000000fd, 0x020200fd, 0xfdfe00fd, + 0x02ff00fd, 0xfd0100fd, 0xff0300fd, 0x00fd00fd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000303, 0xfffffcfd, 0x000003ff, 0xfffffc01, 0xffffff04, 0x000000fc, 0x00000707, + 0xfffff8f9, 0x00000802, 0xfffff7fe, 0x00000208, 0xfffffdf8, 0x000008fe, 0xfffff702, 0xfffffe09, + 0x000001f7, 0x000005fa, 0xfffffa06, 0x00000d06, 0xfffff2fa, 0x0000060d, 0xfffff9f3, 0x00000d0d, + 0xfffff2f3, 0x00000e01, 0xfffff1ff, 0x0000010e, 0xfffffef2, 0x00000bf8, 0xfffff408, 0xfffff80c, + 0x000007f4, 0x0000170e, 0xffffe8f2, 0x00000e17, 0xfffff1e9, 0x000011fb, 0xffffee05, 0xfffffb12, + 0x000004ee, 0x00001806, 0xffffe7fa, 0x00000618, 0xfffff9e8, 0x00001818, 0xffffe7e8, 0x00001aff, + 0xffffe501, 0xffffff1b, 0x000000e5, 0x000010ef, 0xffffef11, 0x000016f3, 0xffffe90d, 0xfffff317, + 0x00000ce9, 0x00002810, 0xffffd7f0, 0x00001028, 0xffffefd8, 0x0000291c, 0xffffd6e4, 0x00001c29, + 0xffffe3d7, 0x000020f7, 0xffffdf09, 0xfffff721, 0x000008df, 0x00002b06, 0xffffd4fa, 0x0000062b, + 0xfffff9d5, 0x00002e2e, 0xffffd1d2, 0x000031fc, 0xffffce04, 0xfffffc32, 0x000003ce, 0x000021e5, + 0xffffde1b, 0xffffe522, 0x00001ade, 0x00002cea, 0xffffd316, 0xffffea2d, 0x000015d3, 0x00004522, + 0xffffbade, 0x00002245, 0xffffddbb, 0x00004613, 0xffffb9ed, 0x00001346, 0xffffecba, 0x00004935, + 0xffffb6cb, 0x00003549, 0xffffcab7, 0x00003def, 0xffffc211, 0xffffef3e, 0x000010c2, 0x00004d05, + 0xffffb2fb, 0x0000054d, 0xfffffab3, 0x00005252, 0xffffadae, 0x000032cd, 0xffffcd33, 0x00003fd5, + 0xffffc02b, 0xffffd540, 0x00002ac0, 0x000059f6, 0xffffa60a, 0xfffff65a, 0x000009a6, 0x00007229, + 0xffff8dd7, 0x00002972, 0xffffd68e, 0x00007440, 0xffff8bc0, 0x00004074, 0xffffbf8c, 0x000051db, + 0xffffae25, 0xffffdb52, 0x000024ae, 0x00007716, 0xffff88ea, 0x00001677, 0xffffe989, 0x00007c5f, + 0xffff83a1, 0x00005f7c, 0xffffa084, 0x00006ee2, 0xffff911e, 0xffffe26f, 0x00001d91, 0x00005bb2, + 0xffffa44e, 0xffffb25c, 0x00004da4, 0x000070bc, 0xffff8f44, 0xffffbc71, 0x0000438f, 0x00001212, + 0xffffedee, 0x00002222, 0xffffddde, 0x00003f3f, 0xffffc0c1, 0x00006d6d, 0xffff9293, 0x00000000, + 0x03030000, 0xfcfd0000, 0x03ff0000, 0xfc010000, 0xff040000, 0x00fc0000, 0x07070000, 0xf8f90000, + 0x00000303, 0x03030303, 0xfcfd0303, 0x03ff0303, 0xfc010303, 0xff040303, 0x00fc0303, 0x07070303, + 0xf8f90303, 0xfffffcfd, 0x0302fcfd, 0xfcfcfcfd, 0x03fefcfd, 0xfc00fcfd, 0xff03fcfd, 0x00fbfcfd, + 0x0706fcfd, 0xf8f8fcfd, 0x000003ff, 0x030303ff, 0xfcfd03ff, 0x03ff03ff, 0xfc0103ff, 0xff0403ff, + 0x00fc03ff, 0x070703ff, 0xf8f903ff, 0xfffffc01, 0x0302fc01, 0xfcfcfc01, 0x03fefc01, 0xfc00fc01, + 0xff03fc01, 0x00fbfc01, 0x0706fc01, 0xf8f8fc01, 0xffffff04, 0x0302ff04, 0xfcfcff04, 0x03feff04, + 0xfc00ff04, 0xff03ff04, 0x00fbff04, 0x0706ff04, 0xf8f8ff04, 0x000000fc, 0x030300fc, 0xfcfd00fc, + 0x03ff00fc, 0xfc0100fc, 0xff0400fc, 0x00fc00fc, 0x070700fc, 0xf8f900fc, 0x00000707, 0x03030707, + 0xfcfd0707, 0x03ff0707, 0xfc010707, 0xff040707, 0x00fc0707, 0x07070707, 0xf8f90707, 0xfffff8f9, + 0x0302f8f9, 0xfcfcf8f9, 0x03fef8f9, 0xfc00f8f9, 0xff03f8f9, 0x00fbf8f9, 0x0706f8f9, 0xf8f8f8f9, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000404, 0xfffffbfc, 0x000004ff, 0xfffffb01, 0xffffff05, 0x000000fb, 0x00000a03, + 0xfffff5fd, 0x0000030a, 0xfffffcf6, 0x00000909, 0xfffff6f7, 0x000006f9, 0xfffff907, 0x00000bfd, + 0xfffff403, 0xfffffd0c, 0x000002f4, 0x00001108, 0xffffeef8, 0x00000811, 0xfffff7ef, 0x00001111, + 0xffffeeef, 0x00001301, 0xffffecff, 0x00000113, 0xfffffeed, 0x00000ff5, 0xfffff00b, 0xfffff510, + 0x00000af0, 0x000016fa, 0xffffe906, 0xfffffa17, 0x000005e9, 0x00001f12, 0xffffe0ee, 0x0000121f, + 0xffffede1, 0x00002008, 0xffffdff8, 0x00000820, 0xfffff7e0, 0x00002121, 0xffffdedf, 0x000023ff, + 0xffffdc01, 0xffffff24, 0x000000dc, 0x000016e9, 0xffffe917, 0x00001eef, 0xffffe111, 0xffffef1f, + 0x000010e1, 0x00003615, 0xffffc9eb, 0x00001536, 0xffffeaca, 0x00003725, 0xffffc8db, 0x00002537, + 0xffffdac9, 0x00002bf4, 0xffffd40c, 0xfffff42c, 0x00000bd4, 0x00003908, 0xffffc6f8, 0x00000839, + 0xfffff7c7, 0x00003d3d, 0xffffc2c3, 0x000041fb, 0xffffbe05, 0xfffffb42, 0x000004be, 0x00002cdc, + 0xffffd324, 0xffffdc2d, 0x000023d3, 0x00003be3, 0xffffc41d, 0xffffe33c, 0x00001cc4, 0x00005c2d, + 0xffffa3d3, 0x00002d5c, 0xffffd2a4, 0x00005d19, 0xffffa2e7, 0x0000195d, 0xffffe6a3, 0x00006147, + 0xffff9eb9, 0x00004761, 0xffffb89f, 0x000052ea, 0xffffad16, 0xffffea53, 0x000015ad, 0x00006607, + 0xffff99f9, 0x00000766, 0xfffff89a, 0x00006d6d, 0xffff9293, 0x000043bc, 0xffffbc44, 0x000054c7, + 0xffffab39, 0xffffc755, 0x000038ab, 0x000077f3, 0xffff880d, 0xfffff378, 0x00000c88, 0x00006dcf, + 0xffff9231, 0xffffcf6e, 0x00003092, 0x00007a98, 0xffff8568, 0xffff987b, 0x00006785, 0x00001818, + 0xffffe7e8, 0x00002e2e, 0xffffd1d2, 0x00005454, 0xffffabac, 0x00000000, 0x04040000, 0xfbfc0000, + 0x04ff0000, 0xfb010000, 0xff050000, 0x00fb0000, 0x0a030000, 0xf5fd0000, 0x030a0000, 0x00000404, + 0x04040404, 0xfbfc0404, 0x04ff0404, 0xfb010404, 0xff050404, 0x00fb0404, 0x0a030404, 0xf5fd0404, + 0x030a0404, 0xfffffbfc, 0x0403fbfc, 0xfbfbfbfc, 0x04fefbfc, 0xfb00fbfc, 0xff04fbfc, 0x00fafbfc, + 0x0a02fbfc, 0xf5fcfbfc, 0x0309fbfc, 0x000004ff, 0x040404ff, 0xfbfc04ff, 0x04ff04ff, 0xfb0104ff, + 0xff0504ff, 0x00fb04ff, 0x0a0304ff, 0xf5fd04ff, 0x030a04ff, 0xfffffb01, 0x0403fb01, 0xfbfbfb01, + 0x04fefb01, 0xfb00fb01, 0xff04fb01, 0x00fafb01, 0x0a02fb01, 0xf5fcfb01, 0x0309fb01, 0xffffff05, + 0x0403ff05, 0xfbfbff05, 0x04feff05, 0xfb00ff05, 0xff04ff05, 0x00faff05, 0x0a02ff05, 0xf5fcff05, + 0x0309ff05, 0x000000fb, 0x040400fb, 0xfbfc00fb, 0x04ff00fb, 0xfb0100fb, 0xff0500fb, 0x00fb00fb, + 0x0a0300fb, 0xf5fd00fb, 0x030a00fb, 0x00000a03, 0x04040a03, 0xfbfc0a03, 0x04ff0a03, 0xfb010a03, + 0xff050a03, 0x00fb0a03, 0x0a030a03, 0xf5fd0a03, 0x030a0a03, 0xfffff5fd, 0x0403f5fd, 0xfbfbf5fd, + 0x04fef5fd, 0xfb00f5fd, 0xff04f5fd, 0x00faf5fd, 0x0a02f5fd, 0xf5fcf5fd, 0x0309f5fd, 0x0000030a, + 0x0404030a, 0xfbfc030a, 0x04ff030a, 0xfb01030a, 0xff05030a, 0x00fb030a, 0x0a03030a, 0xf5fd030a, + 0x030a030a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000505, 0xfffffafb, 0x000006fe, 0xfffff902, 0xfffffe07, 0x000001f9, 0x00000b0b, + 0xfffff4f5, 0x00000d03, 0xfffff2fd, 0x0000030d, 0xfffffcf3, 0x000008f7, 0xfffff709, 0x00000efc, + 0xfffff104, 0xfffffc0f, 0x000003f1, 0x0000160b, 0xffffe9f5, 0x00000b16, 0xfffff4ea, 0x00001515, + 0xffffeaeb, 0x00001802, 0xffffe7fe, 0x00000218, 0xfffffde8, 0x000013f2, 0xffffec0e, 0xfffff214, + 0x00000dec, 0x00002617, 0xffffd9e9, 0x00001726, 0xffffe8da, 0x00001cf8, 0xffffe308, 0xfffff81d, + 0x000007e3, 0x0000270b, 0xffffd8f5, 0x00000b27, 0xfffff4d9, 0x00002929, 0xffffd6d7, 0x00002cff, + 0xffffd301, 0xffffff2d, 0x000000d3, 0x00001ce3, 0xffffe31d, 0x000026ea, 0xffffd916, 0xffffea27, + 0x000015d9, 0x0000431b, 0xffffbce5, 0x00001b43, 0xffffe4bd, 0x0000452f, 0xffffbad1, 0x00002f45, + 0xffffd0bb, 0x000037f1, 0xffffc80f, 0xfffff138, 0x00000ec8, 0x0000470b, 0xffffb8f5, 0x00000b47, + 0xfffff4b9, 0x00004c4c, 0xffffb3b4, 0x000052fa, 0xffffad06, 0xfffffa53, 0x000005ad, 0x000038d3, + 0xffffc72d, 0xffffd339, 0x00002cc7, 0x00004adc, 0xffffb524, 0xffffdc4b, 0x000023b5, 0x00007338, + 0xffff8cc8, 0x00003873, 0xffffc78d, 0x0000751f, 0xffff8ae1, 0x00001f75, 0xffffe08b, 0x00007a58, + 0xffff85a8, 0x0000587a, 0xffffa786, 0x000067e4, 0xffff981c, 0xffffe468, 0x00001b98, 0x000054ab, + 0xffffab55, 0x000069b8, 0xffff9648, 0xffffb86a, 0x00004796, 0x00001e1e, 0xffffe1e2, 0x00003a3a, + 0xffffc5c6, 0x00006969, 0xffff9697, 0x00000000, 0x05050000, 0xfafb0000, 0x06fe0000, 0xf9020000, + 0xfe070000, 0x01f90000, 0x0b0b0000, 0xf4f50000, 0x0d030000, 0xf2fd0000, 0x00000505, 0x05050505, + 0xfafb0505, 0x06fe0505, 0xf9020505, 0xfe070505, 0x01f90505, 0x0b0b0505, 0xf4f50505, 0x0d030505, + 0xf2fd0505, 0xfffffafb, 0x0504fafb, 0xfafafafb, 0x06fdfafb, 0xf901fafb, 0xfe06fafb, 0x01f8fafb, + 0x0b0afafb, 0xf4f4fafb, 0x0d02fafb, 0xf2fcfafb, 0x000006fe, 0x050506fe, 0xfafb06fe, 0x06fe06fe, + 0xf90206fe, 0xfe0706fe, 0x01f906fe, 0x0b0b06fe, 0xf4f506fe, 0x0d0306fe, 0xf2fd06fe, 0xfffff902, + 0x0504f902, 0xfafaf902, 0x06fdf902, 0xf901f902, 0xfe06f902, 0x01f8f902, 0x0b0af902, 0xf4f4f902, + 0x0d02f902, 0xf2fcf902, 0xfffffe07, 0x0504fe07, 0xfafafe07, 0x06fdfe07, 0xf901fe07, 0xfe06fe07, + 0x01f8fe07, 0x0b0afe07, 0xf4f4fe07, 0x0d02fe07, 0xf2fcfe07, 0x000001f9, 0x050501f9, 0xfafb01f9, + 0x06fe01f9, 0xf90201f9, 0xfe0701f9, 0x01f901f9, 0x0b0b01f9, 0xf4f501f9, 0x0d0301f9, 0xf2fd01f9, + 0x00000b0b, 0x05050b0b, 0xfafb0b0b, 0x06fe0b0b, 0xf9020b0b, 0xfe070b0b, 0x01f90b0b, 0x0b0b0b0b, + 0xf4f50b0b, 0x0d030b0b, 0xf2fd0b0b, 0xfffff4f5, 0x0504f4f5, 0xfafaf4f5, 0x06fdf4f5, 0xf901f4f5, + 0xfe06f4f5, 0x01f8f4f5, 0x0b0af4f5, 0xf4f4f4f5, 0x0d02f4f5, 0xf2fcf4f5, 0x00000d03, 0x05050d03, + 0xfafb0d03, 0x06fe0d03, 0xf9020d03, 0xfe070d03, 0x01f90d03, 0x0b0b0d03, 0xf4f50d03, 0x0d030d03, + 0xf2fd0d03, 0xfffff2fd, 0x0504f2fd, 0xfafaf2fd, 0x06fdf2fd, 0xf901f2fd, 0xfe06f2fd, 0x01f8f2fd, + 0x0b0af2fd, 0xf4f4f2fd, 0x0d02f2fd, 0xf2fcf2fd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000606, 0xfffff9fa, 0x000007fe, 0xfffff802, 0xfffffe08, 0x000001f8, 0x00000d0d, + 0xfffff2f3, 0x00000f04, 0xfffff0fc, 0x0000040f, 0xfffffbf1, 0x00000af5, 0xfffff50b, 0x000011fb, + 0xffffee05, 0xfffffb12, 0x000004ee, 0x00001a0d, 0xffffe5f3, 0x00000d1a, 0xfffff2e6, 0x00001a1a, + 0xffffe5e6, 0x00001d02, 0xffffe2fe, 0x0000021d, 0xfffffde3, 0x000017f0, 0xffffe810, 0xfffff018, + 0x00000fe8, 0x00002e1c, 0xffffd1e4, 0x00001c2e, 0xffffe3d2, 0x000022f7, 0xffffdd09, 0xfffff723, + 0x000008dd, 0x00002f0d, 0xffffd0f3, 0x00000d2f, 0xfffff2d1, 0x00003131, 0xffffcecf, 0x000035ff, + 0xffffca01, 0xffffff36, 0x000000ca, 0x000022dd, 0xffffdd23, 0x00002ee6, 0xffffd11a, 0xffffe62f, + 0x000019d1, 0x00005120, 0xffffaee0, 0x00002051, 0xffffdfaf, 0x00005338, 0xffffacc8, 0x00003853, + 0xffffc7ad, 0x000042ee, 0xffffbd12, 0xffffee43, 0x000011bd, 0x0000560d, 0xffffa9f3, 0x00000d56, + 0xfffff2aa, 0x00005b5b, 0xffffa4a5, 0x000062f9, 0xffff9d07, 0xfffff963, 0x0000069d, 0x000043ca, + 0xffffbc36, 0xffffca44, 0x000035bc, 0x000059d4, 0xffffa62c, 0xffffd45a, 0x00002ba6, 0x00007bdf, + 0xffff8421, 0xffffdf7c, 0x00002084, 0x00006699, 0xffff9967, 0x00007eaa, 0xffff8156, 0xffffaa7f, + 0x00005581, 0x00002525, 0xffffdadb, 0x00004545, 0xffffbabb, 0x00000000, 0x06060000, 0xf9fa0000, + 0x07fe0000, 0xf8020000, 0xfe080000, 0x01f80000, 0x0d0d0000, 0xf2f30000, 0x0f040000, 0xf0fc0000, + 0x040f0000, 0x00000606, 0x06060606, 0xf9fa0606, 0x07fe0606, 0xf8020606, 0xfe080606, 0x01f80606, + 0x0d0d0606, 0xf2f30606, 0x0f040606, 0xf0fc0606, 0x040f0606, 0xfffff9fa, 0x0605f9fa, 0xf9f9f9fa, + 0x07fdf9fa, 0xf801f9fa, 0xfe07f9fa, 0x01f7f9fa, 0x0d0cf9fa, 0xf2f2f9fa, 0x0f03f9fa, 0xf0fbf9fa, + 0x040ef9fa, 0x000007fe, 0x060607fe, 0xf9fa07fe, 0x07fe07fe, 0xf80207fe, 0xfe0807fe, 0x01f807fe, + 0x0d0d07fe, 0xf2f307fe, 0x0f0407fe, 0xf0fc07fe, 0x040f07fe, 0xfffff802, 0x0605f802, 0xf9f9f802, + 0x07fdf802, 0xf801f802, 0xfe07f802, 0x01f7f802, 0x0d0cf802, 0xf2f2f802, 0x0f03f802, 0xf0fbf802, + 0x040ef802, 0xfffffe08, 0x0605fe08, 0xf9f9fe08, 0x07fdfe08, 0xf801fe08, 0xfe07fe08, 0x01f7fe08, + 0x0d0cfe08, 0xf2f2fe08, 0x0f03fe08, 0xf0fbfe08, 0x040efe08, 0x000001f8, 0x060601f8, 0xf9fa01f8, + 0x07fe01f8, 0xf80201f8, 0xfe0801f8, 0x01f801f8, 0x0d0d01f8, 0xf2f301f8, 0x0f0401f8, 0xf0fc01f8, + 0x040f01f8, 0x00000d0d, 0x06060d0d, 0xf9fa0d0d, 0x07fe0d0d, 0xf8020d0d, 0xfe080d0d, 0x01f80d0d, + 0x0d0d0d0d, 0xf2f30d0d, 0x0f040d0d, 0xf0fc0d0d, 0x040f0d0d, 0xfffff2f3, 0x0605f2f3, 0xf9f9f2f3, + 0x07fdf2f3, 0xf801f2f3, 0xfe07f2f3, 0x01f7f2f3, 0x0d0cf2f3, 0xf2f2f2f3, 0x0f03f2f3, 0xf0fbf2f3, + 0x040ef2f3, 0x00000f04, 0x06060f04, 0xf9fa0f04, 0x07fe0f04, 0xf8020f04, 0xfe080f04, 0x01f80f04, + 0x0d0d0f04, 0xf2f30f04, 0x0f040f04, 0xf0fc0f04, 0x040f0f04, 0xfffff0fc, 0x0605f0fc, 0xf9f9f0fc, + 0x07fdf0fc, 0xf801f0fc, 0xfe07f0fc, 0x01f7f0fc, 0x0d0cf0fc, 0xf2f2f0fc, 0x0f03f0fc, 0xf0fbf0fc, + 0x040ef0fc, 0x0000040f, 0x0606040f, 0xf9fa040f, 0x07fe040f, 0xf802040f, 0xfe08040f, 0x01f8040f, + 0x0d0d040f, 0xf2f3040f, 0x0f04040f, 0xf0fc040f, 0x040f040f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000707, 0xfffff8f9, 0x000009fd, 0xfffff603, 0xfffffd0a, 0x000002f6, 0x00001010, + 0xffffeff0, 0x00001205, 0xffffedfb, 0x00000512, 0xfffffaee, 0x00000cf3, 0xfffff30d, 0x000014fa, + 0xffffeb06, 0xfffffa15, 0x000005eb, 0x00001e0f, 0xffffe1f1, 0x00000f1e, 0xfffff0e2, 0x00001e1e, + 0xffffe1e2, 0x00002202, 0xffffddfe, 0x00000222, 0xfffffdde, 0x00001bed, 0xffffe413, 0xffffed1c, + 0x000012e4, 0x00003620, 0xffffc9e0, 0x00002036, 0xffffdfca, 0x000028f5, 0xffffd70b, 0xfffff529, + 0x00000ad7, 0x0000370f, 0xffffc8f1, 0x00000f37, 0xfffff0c9, 0x00003939, 0xffffc6c7, 0x00003eff, + 0xffffc101, 0xffffff3f, 0x000000c1, 0x000027d8, 0xffffd828, 0x000036e2, 0xffffc91e, 0xffffe237, + 0x00001dc9, 0x00005e25, 0xffffa1db, 0x0000255e, 0xffffdaa2, 0x00006041, 0xffff9fbf, 0x00004160, + 0xffffbea0, 0x00004deb, 0xffffb215, 0xffffeb4e, 0x000014b2, 0x0000640f, 0xffff9bf1, 0x00000f64, + 0xfffff09c, 0x00006a6a, 0xffff9596, 0x000073f8, 0xffff8c08, 0xfffff874, 0x0000078c, 0x00004ec1, + 0xffffb13f, 0xffffc14f, 0x00003eb1, 0x000068cd, 0xffff9733, 0xffffcd69, 0x00003297, 0x00007788, + 0xffff8878, 0x00002b2b, 0xffffd4d5, 0x00005050, 0xffffafb0, 0x00000000, 0x07070000, 0xf8f90000, + 0x09fd0000, 0xf6030000, 0xfd0a0000, 0x02f60000, 0x10100000, 0xeff00000, 0x12050000, 0xedfb0000, + 0x05120000, 0x00000707, 0x07070707, 0xf8f90707, 0x09fd0707, 0xf6030707, 0xfd0a0707, 0x02f60707, + 0x10100707, 0xeff00707, 0x12050707, 0xedfb0707, 0x05120707, 0xfffff8f9, 0x0706f8f9, 0xf8f8f8f9, + 0x09fcf8f9, 0xf602f8f9, 0xfd09f8f9, 0x02f5f8f9, 0x100ff8f9, 0xefeff8f9, 0x1204f8f9, 0xedfaf8f9, + 0x0511f8f9, 0x000009fd, 0x070709fd, 0xf8f909fd, 0x09fd09fd, 0xf60309fd, 0xfd0a09fd, 0x02f609fd, + 0x101009fd, 0xeff009fd, 0x120509fd, 0xedfb09fd, 0x051209fd, 0xfffff603, 0x0706f603, 0xf8f8f603, + 0x09fcf603, 0xf602f603, 0xfd09f603, 0x02f5f603, 0x100ff603, 0xefeff603, 0x1204f603, 0xedfaf603, + 0x0511f603, 0xfffffd0a, 0x0706fd0a, 0xf8f8fd0a, 0x09fcfd0a, 0xf602fd0a, 0xfd09fd0a, 0x02f5fd0a, + 0x100ffd0a, 0xefeffd0a, 0x1204fd0a, 0xedfafd0a, 0x0511fd0a, 0x000002f6, 0x070702f6, 0xf8f902f6, + 0x09fd02f6, 0xf60302f6, 0xfd0a02f6, 0x02f602f6, 0x101002f6, 0xeff002f6, 0x120502f6, 0xedfb02f6, + 0x051202f6, 0x00001010, 0x07071010, 0xf8f91010, 0x09fd1010, 0xf6031010, 0xfd0a1010, 0x02f61010, + 0x10101010, 0xeff01010, 0x12051010, 0xedfb1010, 0x05121010, 0xffffeff0, 0x0706eff0, 0xf8f8eff0, + 0x09fceff0, 0xf602eff0, 0xfd09eff0, 0x02f5eff0, 0x100feff0, 0xefefeff0, 0x1204eff0, 0xedfaeff0, + 0x0511eff0, 0x00001205, 0x07071205, 0xf8f91205, 0x09fd1205, 0xf6031205, 0xfd0a1205, 0x02f61205, + 0x10101205, 0xeff01205, 0x12051205, 0xedfb1205, 0x05121205, 0xffffedfb, 0x0706edfb, 0xf8f8edfb, + 0x09fcedfb, 0xf602edfb, 0xfd09edfb, 0x02f5edfb, 0x100fedfb, 0xefefedfb, 0x1204edfb, 0xedfaedfb, + 0x0511edfb, 0x00000512, 0x07070512, 0xf8f90512, 0x09fd0512, 0xf6030512, 0xfd0a0512, 0x02f60512, + 0x10100512, 0xeff00512, 0x12050512, 0xedfb0512, 0x05120512, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000808, 0xfffff7f8, 0x00000afd, 0xfffff503, 0xfffffd0b, 0x000002f5, 0x00001212, + 0xffffedee, 0x00001405, 0xffffebfb, 0x00000514, 0xfffffaec, 0x00000ef1, 0xfffff10f, 0x000017f9, + 0xffffe807, 0xfffff918, 0x000006e8, 0x00002311, 0xffffdcef, 0x00001123, 0xffffeedd, 0x00002222, + 0xffffddde, 0x00002603, 0xffffd9fd, 0x00000326, 0xfffffcda, 0x00001fea, 0xffffe016, 0xffffea20, + 0x000015e0, 0x00003d25, 0xffffc2db, 0x0000253d, 0xffffdac3, 0x00002ef3, 0xffffd10d, 0xfffff32f, + 0x00000cd1, 0x00003f11, 0xffffc0ef, 0x0000113f, 0xffffeec1, 0x00004141, 0xffffbebf, 0x000047ff, + 0xffffb801, 0xffffff48, 0x000000b8, 0x00002dd2, 0xffffd22e, 0x00003edd, 0xffffc123, 0xffffdd3f, + 0x000022c1, 0x00006b2b, 0xffff94d5, 0x00002b6b, 0xffffd495, 0x00006e4b, 0xffff91b5, 0x00004b6e, + 0xffffb492, 0x000058e8, 0xffffa718, 0xffffe859, 0x000017a7, 0x00007211, 0xffff8def, 0x00001172, + 0xffffee8e, 0x00007979, 0xffff8687, 0x00005ab8, 0xffffa548, 0xffffb85b, 0x000047a5, 0x000077c6, + 0xffff883a, 0xffffc678, 0x00003988, 0x00003131, 0xffffcecf, 0x00005c5c, 0xffffa3a4, 0x00000000, + 0x08080000, 0xf7f80000, 0x0afd0000, 0xf5030000, 0xfd0b0000, 0x02f50000, 0x12120000, 0xedee0000, + 0x14050000, 0xebfb0000, 0x05140000, 0x00000808, 0x08080808, 0xf7f80808, 0x0afd0808, 0xf5030808, + 0xfd0b0808, 0x02f50808, 0x12120808, 0xedee0808, 0x14050808, 0xebfb0808, 0x05140808, 0xfffff7f8, + 0x0807f7f8, 0xf7f7f7f8, 0x0afcf7f8, 0xf502f7f8, 0xfd0af7f8, 0x02f4f7f8, 0x1211f7f8, 0xededf7f8, + 0x1404f7f8, 0xebfaf7f8, 0x0513f7f8, 0x00000afd, 0x08080afd, 0xf7f80afd, 0x0afd0afd, 0xf5030afd, + 0xfd0b0afd, 0x02f50afd, 0x12120afd, 0xedee0afd, 0x14050afd, 0xebfb0afd, 0x05140afd, 0xfffff503, + 0x0807f503, 0xf7f7f503, 0x0afcf503, 0xf502f503, 0xfd0af503, 0x02f4f503, 0x1211f503, 0xededf503, + 0x1404f503, 0xebfaf503, 0x0513f503, 0xfffffd0b, 0x0807fd0b, 0xf7f7fd0b, 0x0afcfd0b, 0xf502fd0b, + 0xfd0afd0b, 0x02f4fd0b, 0x1211fd0b, 0xededfd0b, 0x1404fd0b, 0xebfafd0b, 0x0513fd0b, 0x000002f5, + 0x080802f5, 0xf7f802f5, 0x0afd02f5, 0xf50302f5, 0xfd0b02f5, 0x02f502f5, 0x121202f5, 0xedee02f5, + 0x140502f5, 0xebfb02f5, 0x051402f5, 0x00001212, 0x08081212, 0xf7f81212, 0x0afd1212, 0xf5031212, + 0xfd0b1212, 0x02f51212, 0x12121212, 0xedee1212, 0x14051212, 0xebfb1212, 0x05141212, 0xffffedee, + 0x0807edee, 0xf7f7edee, 0x0afcedee, 0xf502edee, 0xfd0aedee, 0x02f4edee, 0x1211edee, 0xedededee, + 0x1404edee, 0xebfaedee, 0x0513edee, 0x00001405, 0x08081405, 0xf7f81405, 0x0afd1405, 0xf5031405, + 0xfd0b1405, 0x02f51405, 0x12121405, 0xedee1405, 0x14051405, 0xebfb1405, 0x05141405, 0xffffebfb, + 0x0807ebfb, 0xf7f7ebfb, 0x0afcebfb, 0xf502ebfb, 0xfd0aebfb, 0x02f4ebfb, 0x1211ebfb, 0xededebfb, + 0x1404ebfb, 0xebfaebfb, 0x0513ebfb, 0x00000514, 0x08080514, 0xf7f80514, 0x0afd0514, 0xf5030514, + 0xfd0b0514, 0x02f50514, 0x12120514, 0xedee0514, 0x14050514, 0xebfb0514, 0x05140514, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000909, 0xfffff6f7, 0x00000bfd, 0xfffff403, 0xfffffd0c, 0x000002f4, 0x00001414, + 0xffffebec, 0x00001706, 0xffffe8fa, 0x00000617, 0xfffff9e9, 0x000010ef, 0xffffef11, 0x00001af9, + 0xffffe507, 0xfffff91b, 0x000006e5, 0x00002713, 0xffffd8ed, 0x00001327, 0xffffecd9, 0x00002727, + 0xffffd8d9, 0x00002b03, 0xffffd4fd, 0x0000032b, 0xfffffcd5, 0x000023e8, 0xffffdc18, 0xffffe824, + 0x000017dc, 0x0000452a, 0xffffbad6, 0x00002a45, 0xffffd5bb, 0x000034f2, 0xffffcb0e, 0xfffff235, + 0x00000dcb, 0x00004713, 0xffffb8ed, 0x00001347, 0xffffecb9, 0x00004949, 0xffffb6b7, 0x00004ffe, + 0xffffb002, 0xfffffe50, 0x000001b0, 0x000033cc, 0xffffcc34, 0x000045d9, 0xffffba27, 0xffffd946, + 0x000026ba, 0x00007930, 0xffff86d0, 0x00003079, 0xffffcf87, 0x00007c54, 0xffff83ac, 0x0000547c, + 0xffffab84, 0x000063e5, 0xffff9c1b, 0xffffe564, 0x00001a9c, 0x000065af, 0xffff9a51, 0xffffaf66, + 0x0000509a, 0x00003737, 0xffffc8c9, 0x00006868, 0xffff9798, 0x00000000, 0x09090000, 0xf6f70000, + 0x0bfd0000, 0xf4030000, 0xfd0c0000, 0x02f40000, 0x14140000, 0xebec0000, 0x17060000, 0xe8fa0000, + 0x06170000, 0xf9e90000, 0x00000909, 0x09090909, 0xf6f70909, 0x0bfd0909, 0xf4030909, 0xfd0c0909, + 0x02f40909, 0x14140909, 0xebec0909, 0x17060909, 0xe8fa0909, 0x06170909, 0xf9e90909, 0xfffff6f7, + 0x0908f6f7, 0xf6f6f6f7, 0x0bfcf6f7, 0xf402f6f7, 0xfd0bf6f7, 0x02f3f6f7, 0x1413f6f7, 0xebebf6f7, + 0x1705f6f7, 0xe8f9f6f7, 0x0616f6f7, 0xf9e8f6f7, 0x00000bfd, 0x09090bfd, 0xf6f70bfd, 0x0bfd0bfd, + 0xf4030bfd, 0xfd0c0bfd, 0x02f40bfd, 0x14140bfd, 0xebec0bfd, 0x17060bfd, 0xe8fa0bfd, 0x06170bfd, + 0xf9e90bfd, 0xfffff403, 0x0908f403, 0xf6f6f403, 0x0bfcf403, 0xf402f403, 0xfd0bf403, 0x02f3f403, + 0x1413f403, 0xebebf403, 0x1705f403, 0xe8f9f403, 0x0616f403, 0xf9e8f403, 0xfffffd0c, 0x0908fd0c, + 0xf6f6fd0c, 0x0bfcfd0c, 0xf402fd0c, 0xfd0bfd0c, 0x02f3fd0c, 0x1413fd0c, 0xebebfd0c, 0x1705fd0c, + 0xe8f9fd0c, 0x0616fd0c, 0xf9e8fd0c, 0x000002f4, 0x090902f4, 0xf6f702f4, 0x0bfd02f4, 0xf40302f4, + 0xfd0c02f4, 0x02f402f4, 0x141402f4, 0xebec02f4, 0x170602f4, 0xe8fa02f4, 0x061702f4, 0xf9e902f4, + 0x00001414, 0x09091414, 0xf6f71414, 0x0bfd1414, 0xf4031414, 0xfd0c1414, 0x02f41414, 0x14141414, + 0xebec1414, 0x17061414, 0xe8fa1414, 0x06171414, 0xf9e91414, 0xffffebec, 0x0908ebec, 0xf6f6ebec, + 0x0bfcebec, 0xf402ebec, 0xfd0bebec, 0x02f3ebec, 0x1413ebec, 0xebebebec, 0x1705ebec, 0xe8f9ebec, + 0x0616ebec, 0xf9e8ebec, 0x00001706, 0x09091706, 0xf6f71706, 0x0bfd1706, 0xf4031706, 0xfd0c1706, + 0x02f41706, 0x14141706, 0xebec1706, 0x17061706, 0xe8fa1706, 0x06171706, 0xf9e91706, 0xffffe8fa, + 0x0908e8fa, 0xf6f6e8fa, 0x0bfce8fa, 0xf402e8fa, 0xfd0be8fa, 0x02f3e8fa, 0x1413e8fa, 0xebebe8fa, + 0x1705e8fa, 0xe8f9e8fa, 0x0616e8fa, 0xf9e8e8fa, 0x00000617, 0x09090617, 0xf6f70617, 0x0bfd0617, + 0xf4030617, 0xfd0c0617, 0x02f40617, 0x14140617, 0xebec0617, 0x17060617, 0xe8fa0617, 0x06170617, + 0xf9e90617, 0xfffff9e9, 0x0908f9e9, 0xf6f6f9e9, 0x0bfcf9e9, 0xf402f9e9, 0xfd0bf9e9, 0x02f3f9e9, + 0x1413f9e9, 0xebebf9e9, 0x1705f9e9, 0xe8f9f9e9, 0x0616f9e9, 0xf9e8f9e9, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000202, 0xfffffdfe, 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000404, + 0xfffffbfc, 0x00000400, 0xfffffc00, 0x00000004, 0xfffffffc, 0x000003fc, 0xfffffc04, 0x000005fe, + 0xfffffa02, 0xfffffe06, 0x000001fa, 0x00000804, 0xfffff7fc, 0x00000408, 0xfffffbf8, 0x00000808, + 0xfffff7f8, 0x00000a00, 0xfffff600, 0x0000000a, 0xfffffff6, 0x000007fc, 0xfffff804, 0xfffffc08, + 0x000003f8, 0x00000e08, 0xfffff1f8, 0x0000080e, 0xfffff7f2, 0x00000bfe, 0xfffff402, 0xfffffe0c, + 0x000001f4, 0x00001004, 0xffffeffc, 0x00000410, 0xfffffbf0, 0x00001010, 0xffffeff0, 0x00001200, + 0xffffee00, 0x00000012, 0xffffffee, 0x00000bf4, 0xfffff40c, 0x00000ff8, 0xfffff008, 0xfffff810, + 0x000007f0, 0x00001a0a, 0xffffe5f6, 0x00000a1a, 0xfffff5e6, 0x00001c12, 0xffffe3ee, 0x0000121c, + 0xffffede4, 0x000015fa, 0xffffea06, 0xfffffa16, 0x000005ea, 0x00001c04, 0xffffe3fc, 0x0000041c, + 0xfffffbe4, 0x00001e1e, 0xffffe1e2, 0x00001ffe, 0xffffe002, 0xfffffe20, 0x000001e0, 0x000015ee, + 0xffffea12, 0xffffee16, 0x000011ea, 0x00001df2, 0xffffe20e, 0xfffff21e, 0x00000de2, 0x00002e16, + 0xffffd1ea, 0x0000162e, 0xffffe9d2, 0x00002e0c, 0xffffd1f4, 0x00000c2e, 0xfffff3d2, 0x00003022, + 0xffffcfde, 0x00002230, 0xffffddd0, 0x000027f6, 0xffffd80a, 0xfffff628, 0x000009d8, 0x00003204, + 0xffffcdfc, 0x00000432, 0xfffffbce, 0x00003636, 0xffffc9ca, 0x000021de, 0xffffde22, 0x000029e4, + 0xffffd61c, 0xffffe42a, 0x00001bd6, 0x00003bfa, 0xffffc406, 0xfffffa3c, 0x000005c4, 0x00004c1a, + 0xffffb3e6, 0x00001a4c, 0xffffe5b4, 0x00004c2a, 0xffffb3d6, 0x00002a4c, 0xffffd5b4, 0x000035e8, + 0xffffca18, 0xffffe836, 0x000017ca, 0x00004e0e, 0xffffb1f2, 0x00000e4e, 0xfffff1b2, 0x0000523e, + 0xffffadc2, 0x00003e52, 0xffffc1ae, 0x000049ec, 0xffffb614, 0xffffec4a, 0x000013b6, 0x00005802, + 0xffffa7fe, 0x00000258, 0xfffffda8, 0x00005c5c, 0xffffa3a4, 0x00003bcc, 0xffffc434, 0xffffcc3c, + 0x000033c4, 0x00007634, 0xffff89cc, 0x00003476, 0xffffcb8a, 0x000049d4, 0xffffb62c, 0xffffd44a, + 0x00002bb6, 0x0000764a, 0xffff89b6, 0x00004a76, 0xffffb58a, 0x00007620, 0xffff89e0, 0x00002076, + 0xffffdf8a, 0x000065f4, 0xffff9a0c, 0xfffff466, 0x00000b9a, 0x00005fd8, 0xffffa028, 0xffffd860, + 0x000027a0, 0x000075de, 0xffff8a22, 0xffffde76, 0x0000218a, 0x000057a8, 0xffffa858, 0x000067b2, + 0xffff984e, 0xffffb268, 0x00004d98, 0x00000c0c, 0xfffff3f4, 0x00001616, 0xffffe9ea, 0x00002a2a, + 0xffffd5d6, 0x00004848, 0xffffb7b8, 0x00000000, 0x02020000, 0xfdfe0000, 0x02000000, 0xfe000000, + 0x00020000, 0xfffe0000, 0x00000202, 0x02020202, 0xfdfe0202, 0x02000202, 0xfe000202, 0x00020202, + 0xfffe0202, 0xfffffdfe, 0x0201fdfe, 0xfdfdfdfe, 0x01fffdfe, 0xfdfffdfe, 0x0001fdfe, 0xfffdfdfe, + 0x00000200, 0x02020200, 0xfdfe0200, 0x02000200, 0xfe000200, 0x00020200, 0xfffe0200, 0xfffffe00, + 0x0201fe00, 0xfdfdfe00, 0x01fffe00, 0xfdfffe00, 0x0001fe00, 0xfffdfe00, 0x00000002, 0x02020002, + 0xfdfe0002, 0x02000002, 0xfe000002, 0x00020002, 0xfffe0002, 0xfffffffe, 0x0201fffe, 0xfdfdfffe, + 0x01fffffe, 0xfdfffffe, 0x0001fffe, 0xfffdfffe, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000303, 0xfffffcfd, 0x00000300, 0xfffffd00, 0x00000003, 0xfffffffd, 0x00000606, + 0xfffff9fa, 0x00000903, 0xfffff6fd, 0x00000309, 0xfffffcf7, 0x000008fd, 0xfffff703, 0xfffffd09, + 0x000002f7, 0x000005fa, 0xfffffa06, 0x00000c06, 0xfffff3fa, 0x0000060c, 0xfffff9f4, 0x00000c0c, + 0xfffff3f4, 0x00000f00, 0xfffff100, 0x0000000f, 0xfffffff1, 0x00000bf7, 0xfffff409, 0xfffff70c, + 0x000008f4, 0x0000180f, 0xffffe7f1, 0x00000f18, 0xfffff0e8, 0x000011fa, 0xffffee06, 0xfffffa12, + 0x000005ee, 0x00001806, 0xffffe7fa, 0x00000618, 0xfffff9e8, 0x00001818, 0xffffe7e8, 0x00001b00, + 0xffffe500, 0x0000001b, 0xffffffe5, 0x000011ee, 0xffffee12, 0x000017f4, 0xffffe80c, 0xfffff418, + 0x00000be8, 0x0000270f, 0xffffd8f1, 0x00000f27, 0xfffff0d9, 0x00002a1b, 0xffffd5e5, 0x00001b2a, + 0xffffe4d6, 0x000020f7, 0xffffdf09, 0xfffff721, 0x000008df, 0x00002a06, 0xffffd5fa, 0x0000062a, + 0xfffff9d6, 0x00002d2d, 0xffffd2d3, 0x000032fd, 0xffffcd03, 0xfffffd33, 0x000002cd, 0x000020e5, + 0xffffdf1b, 0xffffe521, 0x00001adf, 0x00002ceb, 0xffffd315, 0xffffeb2d, 0x000014d3, 0x00004521, + 0xffffbadf, 0x00002145, 0xffffdebb, 0x00004512, 0xffffbaee, 0x00001245, 0xffffedbb, 0x00004836, + 0xffffb7ca, 0x00003648, 0xffffc9b8, 0x00003eee, 0xffffc112, 0xffffee3f, 0x000011c1, 0x00004e06, + 0xffffb1fa, 0x0000064e, 0xfffff9b2, 0x00005151, 0xffffaeaf, 0x000032cd, 0xffffcd33, 0x00003ed6, + 0xffffc12a, 0xffffd63f, 0x000029c1, 0x000059f7, 0xffffa609, 0xfffff75a, 0x000008a6, 0x0000722a, + 0xffff8dd6, 0x00002a72, 0xffffd58e, 0x0000753f, 0xffff8ac1, 0x00003f75, 0xffffc08b, 0x000050dc, + 0xffffaf24, 0xffffdc51, 0x000023af, 0x00007815, 0xffff87eb, 0x00001578, 0xffffea88, 0x00007b60, + 0xffff84a0, 0x0000607b, 0xffff9f85, 0x00006ee2, 0xffff911e, 0xffffe26f, 0x00001d91, 0x00005cb2, + 0xffffa34e, 0xffffb25d, 0x00004da3, 0x000071bb, 0xffff8e45, 0xffffbb72, 0x0000448e, 0x00001212, + 0xffffedee, 0x00002121, 0xffffdedf, 0x00003f3f, 0xffffc0c1, 0x00006c6c, 0xffff9394, 0x00000000, + 0x03030000, 0xfcfd0000, 0x03000000, 0xfd000000, 0x00030000, 0xfffd0000, 0x06060000, 0xf9fa0000, + 0x00000303, 0x03030303, 0xfcfd0303, 0x03000303, 0xfd000303, 0x00030303, 0xfffd0303, 0x06060303, + 0xf9fa0303, 0xfffffcfd, 0x0302fcfd, 0xfcfcfcfd, 0x02fffcfd, 0xfcfffcfd, 0x0002fcfd, 0xfffcfcfd, + 0x0605fcfd, 0xf9f9fcfd, 0x00000300, 0x03030300, 0xfcfd0300, 0x03000300, 0xfd000300, 0x00030300, + 0xfffd0300, 0x06060300, 0xf9fa0300, 0xfffffd00, 0x0302fd00, 0xfcfcfd00, 0x02fffd00, 0xfcfffd00, + 0x0002fd00, 0xfffcfd00, 0x0605fd00, 0xf9f9fd00, 0x00000003, 0x03030003, 0xfcfd0003, 0x03000003, + 0xfd000003, 0x00030003, 0xfffd0003, 0x06060003, 0xf9fa0003, 0xfffffffd, 0x0302fffd, 0xfcfcfffd, + 0x02fffffd, 0xfcfffffd, 0x0002fffd, 0xfffcfffd, 0x0605fffd, 0xf9f9fffd, 0x00000606, 0x03030606, + 0xfcfd0606, 0x03000606, 0xfd000606, 0x00030606, 0xfffd0606, 0x06060606, 0xf9fa0606, 0xfffff9fa, + 0x0302f9fa, 0xfcfcf9fa, 0x02fff9fa, 0xfcfff9fa, 0x0002f9fa, 0xfffcf9fa, 0x0605f9fa, 0xf9f9f9fa, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000404, 0xfffffbfc, 0x00000400, 0xfffffc00, 0x00000004, 0xfffffffc, 0x00000804, + 0xfffff7fc, 0x00000408, 0xfffffbf8, 0x00000808, 0xfffff7f8, 0x000007f8, 0xfffff808, 0x00000bfc, + 0xfffff404, 0xfffffc0c, 0x000003f4, 0x00001008, 0xffffeff8, 0x00000810, 0xfffff7f0, 0x00001010, + 0xffffeff0, 0x00001400, 0xffffec00, 0x00000014, 0xffffffec, 0x00000ff4, 0xfffff00c, 0xfffff410, + 0x00000bf0, 0x000017fc, 0xffffe804, 0xfffffc18, 0x000003e8, 0x00002010, 0xffffdff0, 0x00001020, + 0xffffefe0, 0x00002008, 0xffffdff8, 0x00000820, 0xfffff7e0, 0x00002020, 0xffffdfe0, 0x00002400, + 0xffffdc00, 0x00000024, 0xffffffdc, 0x000017e8, 0xffffe818, 0x00001ff0, 0xffffe010, 0xfffff020, + 0x00000fe0, 0x00003414, 0xffffcbec, 0x00001434, 0xffffebcc, 0x00003824, 0xffffc7dc, 0x00002438, + 0xffffdbc8, 0x00002bf4, 0xffffd40c, 0xfffff42c, 0x00000bd4, 0x00003808, 0xffffc7f8, 0x00000838, + 0xfffff7c8, 0x00003c3c, 0xffffc3c4, 0x00003ffc, 0xffffc004, 0xfffffc40, 0x000003c0, 0x00002bdc, + 0xffffd424, 0xffffdc2c, 0x000023d4, 0x00003be4, 0xffffc41c, 0xffffe43c, 0x00001bc4, 0x00005c2c, + 0xffffa3d4, 0x00002c5c, 0xffffd3a4, 0x00005c18, 0xffffa3e8, 0x0000185c, 0xffffe7a4, 0x00006048, + 0xffff9fb8, 0x00004860, 0xffffb7a0, 0x000053ec, 0xffffac14, 0xffffec54, 0x000013ac, 0x00006408, + 0xffff9bf8, 0x00000864, 0xfffff79c, 0x00006c6c, 0xffff9394, 0x000043bc, 0xffffbc44, 0x000053c8, + 0xffffac38, 0xffffc854, 0x000037ac, 0x000077f4, 0xffff880c, 0xfffff478, 0x00000b88, 0x00006bd0, + 0xffff9430, 0xffffd06c, 0x00002f94, 0x00007b98, 0xffff8468, 0xffff987c, 0x00006784, 0x00001818, + 0xffffe7e8, 0x00002c2c, 0xffffd3d4, 0x00005454, 0xffffabac, 0x00000000, 0x04040000, 0xfbfc0000, + 0x04000000, 0xfc000000, 0x00040000, 0xfffc0000, 0x08040000, 0xf7fc0000, 0x04080000, 0x00000404, + 0x04040404, 0xfbfc0404, 0x04000404, 0xfc000404, 0x00040404, 0xfffc0404, 0x08040404, 0xf7fc0404, + 0x04080404, 0xfffffbfc, 0x0403fbfc, 0xfbfbfbfc, 0x03fffbfc, 0xfbfffbfc, 0x0003fbfc, 0xfffbfbfc, + 0x0803fbfc, 0xf7fbfbfc, 0x0407fbfc, 0x00000400, 0x04040400, 0xfbfc0400, 0x04000400, 0xfc000400, + 0x00040400, 0xfffc0400, 0x08040400, 0xf7fc0400, 0x04080400, 0xfffffc00, 0x0403fc00, 0xfbfbfc00, + 0x03fffc00, 0xfbfffc00, 0x0003fc00, 0xfffbfc00, 0x0803fc00, 0xf7fbfc00, 0x0407fc00, 0x00000004, + 0x04040004, 0xfbfc0004, 0x04000004, 0xfc000004, 0x00040004, 0xfffc0004, 0x08040004, 0xf7fc0004, + 0x04080004, 0xfffffffc, 0x0403fffc, 0xfbfbfffc, 0x03fffffc, 0xfbfffffc, 0x0003fffc, 0xfffbfffc, + 0x0803fffc, 0xf7fbfffc, 0x0407fffc, 0x00000804, 0x04040804, 0xfbfc0804, 0x04000804, 0xfc000804, + 0x00040804, 0xfffc0804, 0x08040804, 0xf7fc0804, 0x04080804, 0xfffff7fc, 0x0403f7fc, 0xfbfbf7fc, + 0x03fff7fc, 0xfbfff7fc, 0x0003f7fc, 0xfffbf7fc, 0x0803f7fc, 0xf7fbf7fc, 0x0407f7fc, 0x00000408, + 0x04040408, 0xfbfc0408, 0x04000408, 0xfc000408, 0x00040408, 0xfffc0408, 0x08040408, 0xf7fc0408, + 0x04080408, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000505, 0xfffffafb, 0x00000500, 0xfffffb00, 0x00000005, 0xfffffffb, 0x00000a0a, + 0xfffff5f6, 0x00000f05, 0xfffff0fb, 0x0000050f, 0xfffffaf1, 0x000009f6, 0xfffff60a, 0x00000efb, + 0xfffff105, 0xfffffb0f, 0x000004f1, 0x0000140a, 0xffffebf6, 0x00000a14, 0xfffff5ec, 0x00001414, + 0xffffebec, 0x00001900, 0xffffe700, 0x00000019, 0xffffffe7, 0x000013f1, 0xffffec0f, 0xfffff114, + 0x00000eec, 0x00002819, 0xffffd7e7, 0x00001928, 0xffffe6d8, 0x00001df6, 0xffffe20a, 0xfffff61e, + 0x000009e2, 0x0000280a, 0xffffd7f6, 0x00000a28, 0xfffff5d8, 0x00002828, 0xffffd7d8, 0x00002d00, + 0xffffd300, 0x0000002d, 0xffffffd3, 0x00001de2, 0xffffe21e, 0x000027ec, 0xffffd814, 0xffffec28, + 0x000013d8, 0x00004119, 0xffffbee7, 0x00001941, 0xffffe6bf, 0x0000462d, 0xffffb9d3, 0x00002d46, + 0xffffd2ba, 0x000036f1, 0xffffc90f, 0xfffff137, 0x00000ec9, 0x0000460a, 0xffffb9f6, 0x00000a46, + 0xfffff5ba, 0x00004b4b, 0xffffb4b5, 0x000054fb, 0xffffab05, 0xfffffb55, 0x000004ab, 0x000036d3, + 0xffffc92d, 0xffffd337, 0x00002cc9, 0x00004add, 0xffffb523, 0xffffdd4b, 0x000022b5, 0x00007337, + 0xffff8cc9, 0x00003773, 0xffffc88d, 0x0000731e, 0xffff8ce2, 0x00001e73, 0xffffe18d, 0x0000785a, + 0xffff87a6, 0x00005a78, 0xffffa588, 0x000068e2, 0xffff971e, 0xffffe269, 0x00001d97, 0x000054ab, + 0xffffab55, 0x000068ba, 0xffff9746, 0xffffba69, 0x00004597, 0x00001e1e, 0xffffe1e2, 0x00003c3c, + 0xffffc3c4, 0x00006969, 0xffff9697, 0x00000000, 0x05050000, 0xfafb0000, 0x05000000, 0xfb000000, + 0x00050000, 0xfffb0000, 0x0a0a0000, 0xf5f60000, 0x0f050000, 0xf0fb0000, 0x00000505, 0x05050505, + 0xfafb0505, 0x05000505, 0xfb000505, 0x00050505, 0xfffb0505, 0x0a0a0505, 0xf5f60505, 0x0f050505, + 0xf0fb0505, 0xfffffafb, 0x0504fafb, 0xfafafafb, 0x04fffafb, 0xfafffafb, 0x0004fafb, 0xfffafafb, + 0x0a09fafb, 0xf5f5fafb, 0x0f04fafb, 0xf0fafafb, 0x00000500, 0x05050500, 0xfafb0500, 0x05000500, + 0xfb000500, 0x00050500, 0xfffb0500, 0x0a0a0500, 0xf5f60500, 0x0f050500, 0xf0fb0500, 0xfffffb00, + 0x0504fb00, 0xfafafb00, 0x04fffb00, 0xfafffb00, 0x0004fb00, 0xfffafb00, 0x0a09fb00, 0xf5f5fb00, + 0x0f04fb00, 0xf0fafb00, 0x00000005, 0x05050005, 0xfafb0005, 0x05000005, 0xfb000005, 0x00050005, + 0xfffb0005, 0x0a0a0005, 0xf5f60005, 0x0f050005, 0xf0fb0005, 0xfffffffb, 0x0504fffb, 0xfafafffb, + 0x04fffffb, 0xfafffffb, 0x0004fffb, 0xfffafffb, 0x0a09fffb, 0xf5f5fffb, 0x0f04fffb, 0xf0fafffb, + 0x00000a0a, 0x05050a0a, 0xfafb0a0a, 0x05000a0a, 0xfb000a0a, 0x00050a0a, 0xfffb0a0a, 0x0a0a0a0a, + 0xf5f60a0a, 0x0f050a0a, 0xf0fb0a0a, 0xfffff5f6, 0x0504f5f6, 0xfafaf5f6, 0x04fff5f6, 0xfafff5f6, + 0x0004f5f6, 0xfffaf5f6, 0x0a09f5f6, 0xf5f5f5f6, 0x0f04f5f6, 0xf0faf5f6, 0x00000f05, 0x05050f05, + 0xfafb0f05, 0x05000f05, 0xfb000f05, 0x00050f05, 0xfffb0f05, 0x0a0a0f05, 0xf5f60f05, 0x0f050f05, + 0xf0fb0f05, 0xfffff0fb, 0x0504f0fb, 0xfafaf0fb, 0x04fff0fb, 0xfafff0fb, 0x0004f0fb, 0xfffaf0fb, + 0x0a09f0fb, 0xf5f5f0fb, 0x0f04f0fb, 0xf0faf0fb, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000606, 0xfffff9fa, 0x00000600, 0xfffffa00, 0x00000006, 0xfffffffa, 0x00000c0c, + 0xfffff3f4, 0x00000c06, 0xfffff3fa, 0x0000060c, 0xfffff9f4, 0x00000bf4, 0xfffff40c, 0x000011fa, + 0xffffee06, 0xfffffa12, 0x000005ee, 0x0000180c, 0xffffe7f4, 0x00000c18, 0xfffff3e8, 0x00001818, + 0xffffe7e8, 0x00001e00, 0xffffe200, 0x0000001e, 0xffffffe2, 0x000017ee, 0xffffe812, 0xffffee18, + 0x000011e8, 0x0000301e, 0xffffcfe2, 0x00001e30, 0xffffe1d0, 0x000023fa, 0xffffdc06, 0xfffffa24, + 0x000005dc, 0x0000300c, 0xffffcff4, 0x00000c30, 0xfffff3d0, 0x00003030, 0xffffcfd0, 0x00003600, + 0xffffca00, 0x00000036, 0xffffffca, 0x000023dc, 0xffffdc24, 0x00002fe8, 0xffffd018, 0xffffe830, + 0x000017d0, 0x00004e1e, 0xffffb1e2, 0x00001e4e, 0xffffe1b2, 0x00005436, 0xffffabca, 0x00003654, + 0xffffc9ac, 0x000041ee, 0xffffbe12, 0xffffee42, 0x000011be, 0x0000540c, 0xffffabf4, 0x00000c54, + 0xfffff3ac, 0x00005a5a, 0xffffa5a6, 0x00005ffa, 0xffffa006, 0xfffffa60, 0x000005a0, 0x000041ca, + 0xffffbe36, 0xffffca42, 0x000035be, 0x000059d6, 0xffffa62a, 0xffffd65a, 0x000029a6, 0x00007de2, + 0xffff821e, 0xffffe27e, 0x00001d82, 0x0000659a, 0xffff9a66, 0x00007dac, 0xffff8254, 0xffffac7e, + 0x00005382, 0x00002424, 0xffffdbdc, 0x00004242, 0xffffbdbe, 0x00000000, 0x06060000, 0xf9fa0000, + 0x06000000, 0xfa000000, 0x00060000, 0xfffa0000, 0x0c0c0000, 0xf3f40000, 0x0c060000, 0xf3fa0000, + 0x060c0000, 0x00000606, 0x06060606, 0xf9fa0606, 0x06000606, 0xfa000606, 0x00060606, 0xfffa0606, + 0x0c0c0606, 0xf3f40606, 0x0c060606, 0xf3fa0606, 0x060c0606, 0xfffff9fa, 0x0605f9fa, 0xf9f9f9fa, + 0x05fff9fa, 0xf9fff9fa, 0x0005f9fa, 0xfff9f9fa, 0x0c0bf9fa, 0xf3f3f9fa, 0x0c05f9fa, 0xf3f9f9fa, + 0x060bf9fa, 0x00000600, 0x06060600, 0xf9fa0600, 0x06000600, 0xfa000600, 0x00060600, 0xfffa0600, + 0x0c0c0600, 0xf3f40600, 0x0c060600, 0xf3fa0600, 0x060c0600, 0xfffffa00, 0x0605fa00, 0xf9f9fa00, + 0x05fffa00, 0xf9fffa00, 0x0005fa00, 0xfff9fa00, 0x0c0bfa00, 0xf3f3fa00, 0x0c05fa00, 0xf3f9fa00, + 0x060bfa00, 0x00000006, 0x06060006, 0xf9fa0006, 0x06000006, 0xfa000006, 0x00060006, 0xfffa0006, + 0x0c0c0006, 0xf3f40006, 0x0c060006, 0xf3fa0006, 0x060c0006, 0xfffffffa, 0x0605fffa, 0xf9f9fffa, + 0x05fffffa, 0xf9fffffa, 0x0005fffa, 0xfff9fffa, 0x0c0bfffa, 0xf3f3fffa, 0x0c05fffa, 0xf3f9fffa, + 0x060bfffa, 0x00000c0c, 0x06060c0c, 0xf9fa0c0c, 0x06000c0c, 0xfa000c0c, 0x00060c0c, 0xfffa0c0c, + 0x0c0c0c0c, 0xf3f40c0c, 0x0c060c0c, 0xf3fa0c0c, 0x060c0c0c, 0xfffff3f4, 0x0605f3f4, 0xf9f9f3f4, + 0x05fff3f4, 0xf9fff3f4, 0x0005f3f4, 0xfff9f3f4, 0x0c0bf3f4, 0xf3f3f3f4, 0x0c05f3f4, 0xf3f9f3f4, + 0x060bf3f4, 0x00000c06, 0x06060c06, 0xf9fa0c06, 0x06000c06, 0xfa000c06, 0x00060c06, 0xfffa0c06, + 0x0c0c0c06, 0xf3f40c06, 0x0c060c06, 0xf3fa0c06, 0x060c0c06, 0xfffff3fa, 0x0605f3fa, 0xf9f9f3fa, + 0x05fff3fa, 0xf9fff3fa, 0x0005f3fa, 0xfff9f3fa, 0x0c0bf3fa, 0xf3f3f3fa, 0x0c05f3fa, 0xf3f9f3fa, + 0x060bf3fa, 0x0000060c, 0x0606060c, 0xf9fa060c, 0x0600060c, 0xfa00060c, 0x0006060c, 0xfffa060c, + 0x0c0c060c, 0xf3f4060c, 0x0c06060c, 0xf3fa060c, 0x060c060c, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000707, 0xfffff8f9, 0x00000700, 0xfffff900, 0x00000007, 0xfffffff9, 0x00000e0e, + 0xfffff1f2, 0x00001507, 0xffffeaf9, 0x00000715, 0xfffff8eb, 0x00000df2, 0xfffff20e, 0x000014f9, + 0xffffeb07, 0xfffff915, 0x000006eb, 0x00001c0e, 0xffffe3f2, 0x00000e1c, 0xfffff1e4, 0x00001c1c, + 0xffffe3e4, 0x00002300, 0xffffdd00, 0x00000023, 0xffffffdd, 0x00001beb, 0xffffe415, 0xffffeb1c, + 0x000014e4, 0x00003823, 0xffffc7dd, 0x00002338, 0xffffdcc8, 0x000029f2, 0xffffd60e, 0xfffff22a, + 0x00000dd6, 0x0000380e, 0xffffc7f2, 0x00000e38, 0xfffff1c8, 0x00003838, 0xffffc7c8, 0x00003f00, + 0xffffc100, 0x0000003f, 0xffffffc1, 0x000029d6, 0xffffd62a, 0x000037e4, 0xffffc81c, 0xffffe438, + 0x00001bc8, 0x00005b23, 0xffffa4dd, 0x0000235b, 0xffffdca5, 0x0000623f, 0xffff9dc1, 0x00003f62, + 0xffffc09e, 0x00004ceb, 0xffffb315, 0xffffeb4d, 0x000014b3, 0x0000620e, 0xffff9df2, 0x00000e62, + 0xfffff19e, 0x00006969, 0xffff9697, 0x000076f9, 0xffff8907, 0xfffff977, 0x00000689, 0x00004cc1, + 0xffffb33f, 0xffffc14d, 0x00003eb3, 0x000068cf, 0xffff9731, 0xffffcf69, 0x00003097, 0x00007689, + 0xffff8977, 0x00002a2a, 0xffffd5d6, 0x00004d4d, 0xffffb2b3, 0x00000000, 0x07070000, 0xf8f90000, + 0x07000000, 0xf9000000, 0x00070000, 0xfff90000, 0x0e0e0000, 0xf1f20000, 0x15070000, 0xeaf90000, + 0x07150000, 0x00000707, 0x07070707, 0xf8f90707, 0x07000707, 0xf9000707, 0x00070707, 0xfff90707, + 0x0e0e0707, 0xf1f20707, 0x15070707, 0xeaf90707, 0x07150707, 0xfffff8f9, 0x0706f8f9, 0xf8f8f8f9, + 0x06fff8f9, 0xf8fff8f9, 0x0006f8f9, 0xfff8f8f9, 0x0e0df8f9, 0xf1f1f8f9, 0x1506f8f9, 0xeaf8f8f9, + 0x0714f8f9, 0x00000700, 0x07070700, 0xf8f90700, 0x07000700, 0xf9000700, 0x00070700, 0xfff90700, + 0x0e0e0700, 0xf1f20700, 0x15070700, 0xeaf90700, 0x07150700, 0xfffff900, 0x0706f900, 0xf8f8f900, + 0x06fff900, 0xf8fff900, 0x0006f900, 0xfff8f900, 0x0e0df900, 0xf1f1f900, 0x1506f900, 0xeaf8f900, + 0x0714f900, 0x00000007, 0x07070007, 0xf8f90007, 0x07000007, 0xf9000007, 0x00070007, 0xfff90007, + 0x0e0e0007, 0xf1f20007, 0x15070007, 0xeaf90007, 0x07150007, 0xfffffff9, 0x0706fff9, 0xf8f8fff9, + 0x06fffff9, 0xf8fffff9, 0x0006fff9, 0xfff8fff9, 0x0e0dfff9, 0xf1f1fff9, 0x1506fff9, 0xeaf8fff9, + 0x0714fff9, 0x00000e0e, 0x07070e0e, 0xf8f90e0e, 0x07000e0e, 0xf9000e0e, 0x00070e0e, 0xfff90e0e, + 0x0e0e0e0e, 0xf1f20e0e, 0x15070e0e, 0xeaf90e0e, 0x07150e0e, 0xfffff1f2, 0x0706f1f2, 0xf8f8f1f2, + 0x06fff1f2, 0xf8fff1f2, 0x0006f1f2, 0xfff8f1f2, 0x0e0df1f2, 0xf1f1f1f2, 0x1506f1f2, 0xeaf8f1f2, + 0x0714f1f2, 0x00001507, 0x07071507, 0xf8f91507, 0x07001507, 0xf9001507, 0x00071507, 0xfff91507, + 0x0e0e1507, 0xf1f21507, 0x15071507, 0xeaf91507, 0x07151507, 0xffffeaf9, 0x0706eaf9, 0xf8f8eaf9, + 0x06ffeaf9, 0xf8ffeaf9, 0x0006eaf9, 0xfff8eaf9, 0x0e0deaf9, 0xf1f1eaf9, 0x1506eaf9, 0xeaf8eaf9, + 0x0714eaf9, 0x00000715, 0x07070715, 0xf8f90715, 0x07000715, 0xf9000715, 0x00070715, 0xfff90715, + 0x0e0e0715, 0xf1f20715, 0x15070715, 0xeaf90715, 0x07150715, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000808, 0xfffff7f8, 0x00000800, 0xfffff800, 0x00000008, 0xfffffff8, 0x00001010, + 0xffffeff0, 0x00001008, 0xffffeff8, 0x00000810, 0xfffff7f0, 0x00000ff0, 0xfffff010, 0x000017f8, + 0xffffe808, 0xfffff818, 0x000007e8, 0x00002010, 0xffffdff0, 0x00001020, 0xffffefe0, 0x00002020, + 0xffffdfe0, 0x00002800, 0xffffd800, 0x00000028, 0xffffffd8, 0x00001fe8, 0xffffe018, 0xffffe820, + 0x000017e0, 0x00004028, 0xffffbfd8, 0x00002840, 0xffffd7c0, 0x00002ff0, 0xffffd010, 0xfffff030, + 0x00000fd0, 0x00004010, 0xffffbff0, 0x00001040, 0xffffefc0, 0x00004040, 0xffffbfc0, 0x00004800, + 0xffffb800, 0x00000048, 0xffffffb8, 0x00002fd0, 0xffffd030, 0x00003fe0, 0xffffc020, 0xffffe040, + 0x00001fc0, 0x00006828, 0xffff97d8, 0x00002868, 0xffffd798, 0x00007048, 0xffff8fb8, 0x00004870, + 0xffffb790, 0x000057e8, 0xffffa818, 0xffffe858, 0x000017a8, 0x00007010, 0xffff8ff0, 0x00001070, + 0xffffef90, 0x00007878, 0xffff8788, 0x000057b8, 0xffffa848, 0xffffb858, 0x000047a8, 0x000077c8, + 0xffff8838, 0xffffc878, 0x00003788, 0x00003030, 0xffffcfd0, 0x00005858, 0xffffa7a8, 0x00000000, + 0x08080000, 0xf7f80000, 0x08000000, 0xf8000000, 0x00080000, 0xfff80000, 0x10100000, 0xeff00000, + 0x10080000, 0xeff80000, 0x08100000, 0x00000808, 0x08080808, 0xf7f80808, 0x08000808, 0xf8000808, + 0x00080808, 0xfff80808, 0x10100808, 0xeff00808, 0x10080808, 0xeff80808, 0x08100808, 0xfffff7f8, + 0x0807f7f8, 0xf7f7f7f8, 0x07fff7f8, 0xf7fff7f8, 0x0007f7f8, 0xfff7f7f8, 0x100ff7f8, 0xefeff7f8, + 0x1007f7f8, 0xeff7f7f8, 0x080ff7f8, 0x00000800, 0x08080800, 0xf7f80800, 0x08000800, 0xf8000800, + 0x00080800, 0xfff80800, 0x10100800, 0xeff00800, 0x10080800, 0xeff80800, 0x08100800, 0xfffff800, + 0x0807f800, 0xf7f7f800, 0x07fff800, 0xf7fff800, 0x0007f800, 0xfff7f800, 0x100ff800, 0xefeff800, + 0x1007f800, 0xeff7f800, 0x080ff800, 0x00000008, 0x08080008, 0xf7f80008, 0x08000008, 0xf8000008, + 0x00080008, 0xfff80008, 0x10100008, 0xeff00008, 0x10080008, 0xeff80008, 0x08100008, 0xfffffff8, + 0x0807fff8, 0xf7f7fff8, 0x07fffff8, 0xf7fffff8, 0x0007fff8, 0xfff7fff8, 0x100ffff8, 0xefeffff8, + 0x1007fff8, 0xeff7fff8, 0x080ffff8, 0x00001010, 0x08081010, 0xf7f81010, 0x08001010, 0xf8001010, + 0x00081010, 0xfff81010, 0x10101010, 0xeff01010, 0x10081010, 0xeff81010, 0x08101010, 0xffffeff0, + 0x0807eff0, 0xf7f7eff0, 0x07ffeff0, 0xf7ffeff0, 0x0007eff0, 0xfff7eff0, 0x100feff0, 0xefefeff0, + 0x1007eff0, 0xeff7eff0, 0x080feff0, 0x00001008, 0x08081008, 0xf7f81008, 0x08001008, 0xf8001008, + 0x00081008, 0xfff81008, 0x10101008, 0xeff01008, 0x10081008, 0xeff81008, 0x08101008, 0xffffeff8, + 0x0807eff8, 0xf7f7eff8, 0x07ffeff8, 0xf7ffeff8, 0x0007eff8, 0xfff7eff8, 0x100feff8, 0xefefeff8, + 0x1007eff8, 0xeff7eff8, 0x080feff8, 0x00000810, 0x08080810, 0xf7f80810, 0x08000810, 0xf8000810, + 0x00080810, 0xfff80810, 0x10100810, 0xeff00810, 0x10080810, 0xeff80810, 0x08100810, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000909, 0xfffff6f7, 0x00000900, 0xfffff700, 0x00000009, 0xfffffff7, 0x00001212, + 0xffffedee, 0x00001b09, 0xffffe4f7, 0x0000091b, 0xfffff6e5, 0x000011ee, 0xffffee12, 0x00001af7, + 0xffffe509, 0xfffff71b, 0x000008e5, 0x00002412, 0xffffdbee, 0x00001224, 0xffffeddc, 0x00002424, + 0xffffdbdc, 0x00002d00, 0xffffd300, 0x0000002d, 0xffffffd3, 0x000023e5, 0xffffdc1b, 0xffffe524, + 0x00001adc, 0x0000482d, 0xffffb7d3, 0x00002d48, 0xffffd2b8, 0x000035ee, 0xffffca12, 0xffffee36, + 0x000011ca, 0x00004812, 0xffffb7ee, 0x00001248, 0xffffedb8, 0x00004848, 0xffffb7b8, 0x00005100, + 0xffffaf00, 0x00000051, 0xffffffaf, 0x000035ca, 0xffffca36, 0x000047dc, 0xffffb824, 0xffffdc48, + 0x000023b8, 0x0000752d, 0xffff8ad3, 0x00002d75, 0xffffd28b, 0x00007e51, 0xffff81af, 0x0000517e, + 0xffffae82, 0x000062e5, 0xffff9d1b, 0xffffe563, 0x00001a9d, 0x000062af, 0xffff9d51, 0xffffaf63, + 0x0000509d, 0x00003636, 0xffffc9ca, 0x00006c6c, 0xffff9394, 0x00000000, 0x09090000, 0xf6f70000, + 0x09000000, 0xf7000000, 0x00090000, 0xfff70000, 0x12120000, 0xedee0000, 0x1b090000, 0xe4f70000, + 0x091b0000, 0xf6e50000, 0x00000909, 0x09090909, 0xf6f70909, 0x09000909, 0xf7000909, 0x00090909, + 0xfff70909, 0x12120909, 0xedee0909, 0x1b090909, 0xe4f70909, 0x091b0909, 0xf6e50909, 0xfffff6f7, + 0x0908f6f7, 0xf6f6f6f7, 0x08fff6f7, 0xf6fff6f7, 0x0008f6f7, 0xfff6f6f7, 0x1211f6f7, 0xededf6f7, + 0x1b08f6f7, 0xe4f6f6f7, 0x091af6f7, 0xf6e4f6f7, 0x00000900, 0x09090900, 0xf6f70900, 0x09000900, + 0xf7000900, 0x00090900, 0xfff70900, 0x12120900, 0xedee0900, 0x1b090900, 0xe4f70900, 0x091b0900, + 0xf6e50900, 0xfffff700, 0x0908f700, 0xf6f6f700, 0x08fff700, 0xf6fff700, 0x0008f700, 0xfff6f700, + 0x1211f700, 0xededf700, 0x1b08f700, 0xe4f6f700, 0x091af700, 0xf6e4f700, 0x00000009, 0x09090009, + 0xf6f70009, 0x09000009, 0xf7000009, 0x00090009, 0xfff70009, 0x12120009, 0xedee0009, 0x1b090009, + 0xe4f70009, 0x091b0009, 0xf6e50009, 0xfffffff7, 0x0908fff7, 0xf6f6fff7, 0x08fffff7, 0xf6fffff7, + 0x0008fff7, 0xfff6fff7, 0x1211fff7, 0xededfff7, 0x1b08fff7, 0xe4f6fff7, 0x091afff7, 0xf6e4fff7, + 0x00001212, 0x09091212, 0xf6f71212, 0x09001212, 0xf7001212, 0x00091212, 0xfff71212, 0x12121212, + 0xedee1212, 0x1b091212, 0xe4f71212, 0x091b1212, 0xf6e51212, 0xffffedee, 0x0908edee, 0xf6f6edee, + 0x08ffedee, 0xf6ffedee, 0x0008edee, 0xfff6edee, 0x1211edee, 0xedededee, 0x1b08edee, 0xe4f6edee, + 0x091aedee, 0xf6e4edee, 0x00001b09, 0x09091b09, 0xf6f71b09, 0x09001b09, 0xf7001b09, 0x00091b09, + 0xfff71b09, 0x12121b09, 0xedee1b09, 0x1b091b09, 0xe4f71b09, 0x091b1b09, 0xf6e51b09, 0xffffe4f7, + 0x0908e4f7, 0xf6f6e4f7, 0x08ffe4f7, 0xf6ffe4f7, 0x0008e4f7, 0xfff6e4f7, 0x1211e4f7, 0xedede4f7, + 0x1b08e4f7, 0xe4f6e4f7, 0x091ae4f7, 0xf6e4e4f7, 0x0000091b, 0x0909091b, 0xf6f7091b, 0x0900091b, + 0xf700091b, 0x0009091b, 0xfff7091b, 0x1212091b, 0xedee091b, 0x1b09091b, 0xe4f7091b, 0x091b091b, + 0xf6e5091b, 0xfffff6e5, 0x0908f6e5, 0xf6f6f6e5, 0x08fff6e5, 0xf6fff6e5, 0x0008f6e5, 0xfff6f6e5, + 0x1211f6e5, 0xededf6e5, 0x1b08f6e5, 0xe4f6f6e5, 0x091af6e5, 0xf6e4f6e5, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000202, 0xfffffdfe, 0x00000300, 0xfffffd00, 0x00000003, 0xfffffffd, 0x00000606, + 0xfffff9fa, 0x00000700, 0xfffff900, 0x00000007, 0xfffffff9, 0x000004fb, 0xfffffb05, 0xfffffb05, + 0x000004fb, 0x00000b06, 0xfffff4fa, 0x0000060b, 0xfffff9f5, 0x00000800, 0xfffff800, 0x00000008, + 0xfffffff8, 0x00000b0b, 0xfffff4f5, 0x00000c00, 0xfffff400, 0x0000000c, 0xfffffff4, 0x0000110c, + 0xffffeef4, 0x00000c11, 0xfffff3ef, 0x00001111, 0xffffeeef, 0x00001206, 0xffffedfa, 0x00000612, + 0xfffff9ee, 0x00000af8, 0xfffff508, 0xfffff80b, 0x000007f5, 0x00000f00, 0xfffff100, 0x0000000f, + 0xfffffff1, 0x00001400, 0xffffec00, 0x00000014, 0xffffffec, 0x00001912, 0xffffe6ee, 0x00001219, + 0xffffede7, 0x0000190b, 0xffffe6f5, 0x00000b19, 0xfffff4e7, 0x00001919, 0xffffe6e7, 0x00000df2, + 0xfffff20e, 0xfffff20e, 0x00000df2, 0x00001a00, 0xffffe600, 0x0000001a, 0xffffffe6, 0x000011f5, + 0xffffee0b, 0xfffff512, 0x00000aee, 0x000015f9, 0xffffea07, 0xfffff916, 0x000006ea, 0x0000221a, + 0xffffdde6, 0x00001a22, 0xffffe5de, 0x00002212, 0xffffddee, 0x00001222, 0xffffedde, 0x00002222, + 0xffffddde, 0x0000230b, 0xffffdcf5, 0x00000b23, 0xfffff4dd, 0x00001d00, 0xffffe300, 0x0000001d, + 0xffffffe3, 0x000015ed, 0xffffea13, 0xffffed16, 0x000012ea, 0x000019f1, 0xffffe60f, 0xfffff11a, + 0x00000ee6, 0x00002500, 0xffffdb00, 0x00000025, 0xffffffdb, 0x00002c1b, 0xffffd3e5, 0x00001b2c, + 0xffffe4d4, 0x00002c24, 0xffffd3dc, 0x0000242c, 0xffffdbd4, 0x00002c12, 0xffffd3ee, 0x0000122c, + 0xffffedd4, 0x000020f6, 0xffffdf0a, 0xfffff621, 0x000009df, 0x00002d2d, 0xffffd2d3, 0x00000000, + 0x00000000, 0x00000202, 0xfffffdfe, 0x00000300, 0xfffffd00, 0x00000003, 0xfffffffd, 0x00000606, + 0xfffff9fa, 0x00000700, 0xfffff900, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020300, 0x0201fd00, + 0x02020003, 0x0201fffd, 0x02020606, 0x0201f9fa, 0x02020700, 0x0201f900, 0xfdfe0000, 0xfdfe0202, + 0xfdfdfdfe, 0xfdfe0300, 0xfdfdfd00, 0xfdfe0003, 0xfdfdfffd, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0700, + 0xfdfdf900, 0x03000000, 0x03000202, 0x02fffdfe, 0x03000300, 0x02fffd00, 0x03000003, 0x02fffffd, + 0x03000606, 0x02fff9fa, 0x03000700, 0x02fff900, 0xfd000000, 0xfd000202, 0xfcfffdfe, 0xfd000300, + 0xfcfffd00, 0xfd000003, 0xfcfffffd, 0xfd000606, 0xfcfff9fa, 0xfd000700, 0xfcfff900, 0x00030000, + 0x00030202, 0x0002fdfe, 0x00030300, 0x0002fd00, 0x00030003, 0x0002fffd, 0x00030606, 0x0002f9fa, + 0x00030700, 0x0002f900, 0xfffd0000, 0xfffd0202, 0xfffcfdfe, 0xfffd0300, 0xfffcfd00, 0xfffd0003, + 0xfffcfffd, 0xfffd0606, 0xfffcf9fa, 0xfffd0700, 0xfffcf900, 0x06060000, 0x06060202, 0x0605fdfe, + 0x06060300, 0x0605fd00, 0x06060003, 0x0605fffd, 0x06060606, 0x0605f9fa, 0x06060700, 0x0605f900, + 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0300, 0xf9f9fd00, 0xf9fa0003, 0xf9f9fffd, 0xf9fa0606, + 0xf9f9f9fa, 0xf9fa0700, 0xf9f9f900, 0x07000000, 0x07000202, 0x06fffdfe, 0x07000300, 0x06fffd00, + 0x07000003, 0x06fffffd, 0x07000606, 0x06fff9fa, 0x07000700, 0x06fff900, 0xf9000000, 0xf9000202, + 0xf8fffdfe, 0xf9000300, 0xf8fffd00, 0xf9000003, 0xf8fffffd, 0xf9000606, 0xf8fff9fa, 0xf9000700, + 0xf8fff900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000202, 0xfffffdfe, 0x00000606, + 0xfffff9fa, 0x00000600, 0xfffffa00, 0x00000006, 0xfffffffa, 0x000003fc, 0xfffffc04, 0xfffffa0a, + 0x000005f6, 0xfffff400, 0x00000c00, 0xfffff3fa, 0xfffff406, 0x00000bfa, 0x00000c06, 0xfffffff2, + 0x0000000e, 0x00000c0c, 0xfffff3f4, 0xffffee00, 0x00001200, 0xfffff40e, 0x00000bf2, 0xfffff9ee, + 0xfffffa12, 0x000005ee, 0x00000612, 0xffffedf6, 0xffffee0a, 0x000011f6, 0x0000120a, 0xffffffea, + 0x00000016, 0xffffe800, 0x00001800, 0xfffff3ea, 0xfffff416, 0x00000bea, 0x00000c16, 0xffffe7f8, + 0xffffe808, 0x000017f8, 0x00001808, 0xfffff9e6, 0xfffffa1a, 0x000005e6, 0x0000061a, 0xffffffe4, + 0x0000001c, 0x00001414, 0xffffebec, 0xffffe5f2, 0x00001a0e, 0xfffff3e2, 0x00000c1e, 0xffffdff6, + 0x0000200a, 0xffffdfee, 0x00002012, 0xffffe5e6, 0x00001a1a, 0xffffebde, 0x00001422, 0xfffff3da, + 0x00000c26, 0xffffdfe0, 0x00002020, 0x00002020, 0xffffd7ea, 0xffffddde, 0x00002222, 0x00000000, + 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, + 0x00000600, 0xfffffa00, 0x00000006, 0xfffffffa, 0x02000000, 0x02000200, 0x01fffe00, 0x02000002, + 0x01fffffe, 0x02000202, 0x01fffdfe, 0x02000606, 0x01fff9fa, 0x02000600, 0x01fffa00, 0x02000006, + 0x01fffffa, 0xfe000000, 0xfe000200, 0xfdfffe00, 0xfe000002, 0xfdfffffe, 0xfe000202, 0xfdfffdfe, + 0xfe000606, 0xfdfff9fa, 0xfe000600, 0xfdfffa00, 0xfe000006, 0xfdfffffa, 0x00020000, 0x00020200, + 0x0001fe00, 0x00020002, 0x0001fffe, 0x00020202, 0x0001fdfe, 0x00020606, 0x0001f9fa, 0x00020600, + 0x0001fa00, 0x00020006, 0x0001fffa, 0xfffe0000, 0xfffe0200, 0xfffdfe00, 0xfffe0002, 0xfffdfffe, + 0xfffe0202, 0xfffdfdfe, 0xfffe0606, 0xfffdf9fa, 0xfffe0600, 0xfffdfa00, 0xfffe0006, 0xfffdfffa, + 0x02020000, 0x02020200, 0x0201fe00, 0x02020002, 0x0201fffe, 0x02020202, 0x0201fdfe, 0x02020606, + 0x0201f9fa, 0x02020600, 0x0201fa00, 0x02020006, 0x0201fffa, 0xfdfe0000, 0xfdfe0200, 0xfdfdfe00, + 0xfdfe0002, 0xfdfdfffe, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0600, 0xfdfdfa00, + 0xfdfe0006, 0xfdfdfffa, 0x06060000, 0x06060200, 0x0605fe00, 0x06060002, 0x0605fffe, 0x06060202, + 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060600, 0x0605fa00, 0x06060006, 0x0605fffa, 0xf9fa0000, + 0xf9fa0200, 0xf9f9fe00, 0xf9fa0002, 0xf9f9fffe, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa, + 0xf9fa0600, 0xf9f9fa00, 0xf9fa0006, 0xf9f9fffa, 0x06000000, 0x06000200, 0x05fffe00, 0x06000002, + 0x05fffffe, 0x06000202, 0x05fffdfe, 0x06000606, 0x05fff9fa, 0x06000600, 0x05fffa00, 0x06000006, + 0x05fffffa, 0xfa000000, 0xfa000200, 0xf9fffe00, 0xfa000002, 0xf9fffffe, 0xfa000202, 0xf9fffdfe, + 0xfa000606, 0xf9fff9fa, 0xfa000600, 0xf9fffa00, 0xfa000006, 0xf9fffffa, 0x00060000, 0x00060200, + 0x0005fe00, 0x00060002, 0x0005fffe, 0x00060202, 0x0005fdfe, 0x00060606, 0x0005f9fa, 0x00060600, + 0x0005fa00, 0x00060006, 0x0005fffa, 0xfffa0000, 0xfffa0200, 0xfff9fe00, 0xfffa0002, 0xfff9fffe, + 0xfffa0202, 0xfff9fdfe, 0xfffa0606, 0xfff9f9fa, 0xfffa0600, 0xfff9fa00, 0xfffa0006, 0xfff9fffa, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000404, 0xfffffbfc, 0x00000a0a, + 0xfffff5f6, 0x00000a00, 0xfffff600, 0x0000000a, 0xfffffff6, 0x000005fa, 0xfffffa06, 0xfffff80e, + 0x000007f2, 0xffffffee, 0x00000012, 0xfffff00a, 0x00000ff6, 0xffffe800, 0x00001800, 0xfffff7e8, + 0xfffff818, 0x000007e8, 0x00000818, 0x00001212, 0xffffedee, 0xfffff014, 0x00000fec, 0xffffe5f2, + 0xffffe60e, 0x000019f2, 0x00001a0e, 0xffffffe2, 0x0000001e, 0xffffde00, 0x00002200, 0xfffff7de, + 0xfffff822, 0x000007de, 0x00000822, 0xffffede2, 0xffffee1e, 0x000011e2, 0x0000121e, 0xffffddf6, + 0xffffde0a, 0x000021f6, 0x0000220a, 0xffffddec, 0x00002214, 0xffffffd8, 0x00000028, 0x00001e1e, + 0xffffe1e2, 0xffffedd8, 0x00001228, 0xffffd400, 0x00002c00, 0xffffd3f0, 0x00002c10, 0xffffdbdc, + 0xffffdbdc, 0x00002424, 0xffffd3e6, 0x00002c1a, 0xffffe5d2, 0x00001a2e, 0xffffedcc, 0x00001234, + 0xffffc9ec, 0xffffd3d4, 0x00002c2c, 0xffffc9e0, 0xffffd1d2, 0xffffd1d2, 0x00002e2e, 0x00000000, + 0x00000200, 0xfffffe00, 0x00000002, 0xfffffffe, 0x00000404, 0xfffffbfc, 0x00000a0a, 0xfffff5f6, + 0x00000a00, 0xfffff600, 0x0000000a, 0xfffffff6, 0x02000000, 0x02000200, 0x01fffe00, 0x02000002, + 0x01fffffe, 0x02000404, 0x01fffbfc, 0x02000a0a, 0x01fff5f6, 0x02000a00, 0x01fff600, 0x0200000a, + 0x01fffff6, 0xfe000000, 0xfe000200, 0xfdfffe00, 0xfe000002, 0xfdfffffe, 0xfe000404, 0xfdfffbfc, + 0xfe000a0a, 0xfdfff5f6, 0xfe000a00, 0xfdfff600, 0xfe00000a, 0xfdfffff6, 0x00020000, 0x00020200, + 0x0001fe00, 0x00020002, 0x0001fffe, 0x00020404, 0x0001fbfc, 0x00020a0a, 0x0001f5f6, 0x00020a00, + 0x0001f600, 0x0002000a, 0x0001fff6, 0xfffe0000, 0xfffe0200, 0xfffdfe00, 0xfffe0002, 0xfffdfffe, + 0xfffe0404, 0xfffdfbfc, 0xfffe0a0a, 0xfffdf5f6, 0xfffe0a00, 0xfffdf600, 0xfffe000a, 0xfffdfff6, + 0x04040000, 0x04040200, 0x0403fe00, 0x04040002, 0x0403fffe, 0x04040404, 0x0403fbfc, 0x04040a0a, + 0x0403f5f6, 0x04040a00, 0x0403f600, 0x0404000a, 0x0403fff6, 0xfbfc0000, 0xfbfc0200, 0xfbfbfe00, + 0xfbfc0002, 0xfbfbfffe, 0xfbfc0404, 0xfbfbfbfc, 0xfbfc0a0a, 0xfbfbf5f6, 0xfbfc0a00, 0xfbfbf600, + 0xfbfc000a, 0xfbfbfff6, 0x0a0a0000, 0x0a0a0200, 0x0a09fe00, 0x0a0a0002, 0x0a09fffe, 0x0a0a0404, + 0x0a09fbfc, 0x0a0a0a0a, 0x0a09f5f6, 0x0a0a0a00, 0x0a09f600, 0x0a0a000a, 0x0a09fff6, 0xf5f60000, + 0xf5f60200, 0xf5f5fe00, 0xf5f60002, 0xf5f5fffe, 0xf5f60404, 0xf5f5fbfc, 0xf5f60a0a, 0xf5f5f5f6, + 0xf5f60a00, 0xf5f5f600, 0xf5f6000a, 0xf5f5fff6, 0x0a000000, 0x0a000200, 0x09fffe00, 0x0a000002, + 0x09fffffe, 0x0a000404, 0x09fffbfc, 0x0a000a0a, 0x09fff5f6, 0x0a000a00, 0x09fff600, 0x0a00000a, + 0x09fffff6, 0xf6000000, 0xf6000200, 0xf5fffe00, 0xf6000002, 0xf5fffffe, 0xf6000404, 0xf5fffbfc, + 0xf6000a0a, 0xf5fff5f6, 0xf6000a00, 0xf5fff600, 0xf600000a, 0xf5fffff6, 0x000a0000, 0x000a0200, + 0x0009fe00, 0x000a0002, 0x0009fffe, 0x000a0404, 0x0009fbfc, 0x000a0a0a, 0x0009f5f6, 0x000a0a00, + 0x0009f600, 0x000a000a, 0x0009fff6, 0xfff60000, 0xfff60200, 0xfff5fe00, 0xfff60002, 0xfff5fffe, + 0xfff60404, 0xfff5fbfc, 0xfff60a0a, 0xfff5f5f6, 0xfff60a00, 0xfff5f600, 0xfff6000a, 0xfff5fff6, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000400, 0xfffffc00, 0x00000004, 0xfffffffc, 0x00000404, 0xfffffbfc, 0x00000c0c, + 0xfffff3f4, 0x00000c00, 0xfffff400, 0x0000000c, 0xfffffff4, 0x000007f8, 0xfffff808, 0xfffff008, + 0x00000ff8, 0xffffe800, 0x00001800, 0xfffff7e8, 0xfffff818, 0x000007e8, 0x00000818, 0xfffff014, + 0x00000fec, 0xffffffe4, 0x0000001c, 0xffffe7f0, 0xffffe810, 0x000017f0, 0x00001810, 0xffffe000, + 0x00002000, 0xffffefe4, 0xfffff01c, 0x00000fe4, 0x0000101c, 0xffffdff8, 0xffffe008, 0xfffff7e0, + 0xfffff820, 0x000007e0, 0x00000820, 0x00001ff8, 0x00002008, 0x00001818, 0xffffe7e8, 0xffffe818, + 0x000017e8, 0xffffdfec, 0x00002014, 0xffffffd8, 0x00000028, 0xffffefd8, 0x00001028, 0xffffd400, + 0xffffd400, 0xffffffd4, 0x0000002c, 0x00002c00, 0x00002c00, 0xffffdfe0, 0x00002020, 0xffffd3f0, + 0x00002c10, 0xffffd3e8, 0xffffe7d4, 0x0000182c, 0x00002c18, 0xffffefd0, 0x00001030, 0xffffdbdc, + 0xffffdbdc, 0x00002424, 0x00002424, 0xffffcbec, 0x00002828, 0xffffd7d8, 0xffffcbe0, 0x00000000, + 0x00000400, 0xfffffc00, 0x00000004, 0xfffffffc, 0x00000404, 0xfffffbfc, 0x00000c0c, 0xfffff3f4, + 0x00000c00, 0xfffff400, 0x0000000c, 0xfffffff4, 0x04000000, 0x04000400, 0x03fffc00, 0x04000004, + 0x03fffffc, 0x04000404, 0x03fffbfc, 0x04000c0c, 0x03fff3f4, 0x04000c00, 0x03fff400, 0x0400000c, + 0x03fffff4, 0xfc000000, 0xfc000400, 0xfbfffc00, 0xfc000004, 0xfbfffffc, 0xfc000404, 0xfbfffbfc, + 0xfc000c0c, 0xfbfff3f4, 0xfc000c00, 0xfbfff400, 0xfc00000c, 0xfbfffff4, 0x00040000, 0x00040400, + 0x0003fc00, 0x00040004, 0x0003fffc, 0x00040404, 0x0003fbfc, 0x00040c0c, 0x0003f3f4, 0x00040c00, + 0x0003f400, 0x0004000c, 0x0003fff4, 0xfffc0000, 0xfffc0400, 0xfffbfc00, 0xfffc0004, 0xfffbfffc, + 0xfffc0404, 0xfffbfbfc, 0xfffc0c0c, 0xfffbf3f4, 0xfffc0c00, 0xfffbf400, 0xfffc000c, 0xfffbfff4, + 0x04040000, 0x04040400, 0x0403fc00, 0x04040004, 0x0403fffc, 0x04040404, 0x0403fbfc, 0x04040c0c, + 0x0403f3f4, 0x04040c00, 0x0403f400, 0x0404000c, 0x0403fff4, 0xfbfc0000, 0xfbfc0400, 0xfbfbfc00, + 0xfbfc0004, 0xfbfbfffc, 0xfbfc0404, 0xfbfbfbfc, 0xfbfc0c0c, 0xfbfbf3f4, 0xfbfc0c00, 0xfbfbf400, + 0xfbfc000c, 0xfbfbfff4, 0x0c0c0000, 0x0c0c0400, 0x0c0bfc00, 0x0c0c0004, 0x0c0bfffc, 0x0c0c0404, + 0x0c0bfbfc, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c0c00, 0x0c0bf400, 0x0c0c000c, 0x0c0bfff4, 0xf3f40000, + 0xf3f40400, 0xf3f3fc00, 0xf3f40004, 0xf3f3fffc, 0xf3f40404, 0xf3f3fbfc, 0xf3f40c0c, 0xf3f3f3f4, + 0xf3f40c00, 0xf3f3f400, 0xf3f4000c, 0xf3f3fff4, 0x0c000000, 0x0c000400, 0x0bfffc00, 0x0c000004, + 0x0bfffffc, 0x0c000404, 0x0bfffbfc, 0x0c000c0c, 0x0bfff3f4, 0x0c000c00, 0x0bfff400, 0x0c00000c, + 0x0bfffff4, 0xf4000000, 0xf4000400, 0xf3fffc00, 0xf4000004, 0xf3fffffc, 0xf4000404, 0xf3fffbfc, + 0xf4000c0c, 0xf3fff3f4, 0xf4000c00, 0xf3fff400, 0xf400000c, 0xf3fffff4, 0x000c0000, 0x000c0400, + 0x000bfc00, 0x000c0004, 0x000bfffc, 0x000c0404, 0x000bfbfc, 0x000c0c0c, 0x000bf3f4, 0x000c0c00, + 0x000bf400, 0x000c000c, 0x000bfff4, 0xfff40000, 0xfff40400, 0xfff3fc00, 0xfff40004, 0xfff3fffc, + 0xfff40404, 0xfff3fbfc, 0xfff40c0c, 0xfff3f3f4, 0xfff40c00, 0xfff3f400, 0xfff4000c, 0xfff3fff4, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, + 0xffffebec, 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, 0xffffebec, + 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020606, + 0x0201f9fa, 0x02020c0c, 0x0201f3f4, 0x02021414, 0x0201ebec, 0x02022020, 0x0201dfe0, 0x02022e2e, + 0x0201d1d2, 0xfdfe0000, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0c0c, 0xfdfdf3f4, + 0xfdfe1414, 0xfdfdebec, 0xfdfe2020, 0xfdfddfe0, 0xfdfe2e2e, 0xfdfdd1d2, 0x06060000, 0x06060202, + 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060c0c, 0x0605f3f4, 0x06061414, 0x0605ebec, 0x06062020, + 0x0605dfe0, 0x06062e2e, 0x0605d1d2, 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa, + 0xf9fa0c0c, 0xf9f9f3f4, 0xf9fa1414, 0xf9f9ebec, 0xf9fa2020, 0xf9f9dfe0, 0xf9fa2e2e, 0xf9f9d1d2, + 0x0c0c0000, 0x0c0c0202, 0x0c0bfdfe, 0x0c0c0606, 0x0c0bf9fa, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c1414, + 0x0c0bebec, 0x0c0c2020, 0x0c0bdfe0, 0x0c0c2e2e, 0x0c0bd1d2, 0xf3f40000, 0xf3f40202, 0xf3f3fdfe, + 0xf3f40606, 0xf3f3f9fa, 0xf3f40c0c, 0xf3f3f3f4, 0xf3f41414, 0xf3f3ebec, 0xf3f42020, 0xf3f3dfe0, + 0xf3f42e2e, 0xf3f3d1d2, 0x14140000, 0x14140202, 0x1413fdfe, 0x14140606, 0x1413f9fa, 0x14140c0c, + 0x1413f3f4, 0x14141414, 0x1413ebec, 0x14142020, 0x1413dfe0, 0x14142e2e, 0x1413d1d2, 0xebec0000, + 0xebec0202, 0xebebfdfe, 0xebec0606, 0xebebf9fa, 0xebec0c0c, 0xebebf3f4, 0xebec1414, 0xebebebec, + 0xebec2020, 0xebebdfe0, 0xebec2e2e, 0xebebd1d2, 0x20200000, 0x20200202, 0x201ffdfe, 0x20200606, + 0x201ff9fa, 0x20200c0c, 0x201ff3f4, 0x20201414, 0x201febec, 0x20202020, 0x201fdfe0, 0x20202e2e, + 0x201fd1d2, 0xdfe00000, 0xdfe00202, 0xdfdffdfe, 0xdfe00606, 0xdfdff9fa, 0xdfe00c0c, 0xdfdff3f4, + 0xdfe01414, 0xdfdfebec, 0xdfe02020, 0xdfdfdfe0, 0xdfe02e2e, 0xdfdfd1d2, 0x2e2e0000, 0x2e2e0202, + 0x2e2dfdfe, 0x2e2e0606, 0x2e2df9fa, 0x2e2e0c0c, 0x2e2df3f4, 0x2e2e1414, 0x2e2debec, 0x2e2e2020, + 0x2e2ddfe0, 0x2e2e2e2e, 0x2e2dd1d2, 0xd1d20000, 0xd1d20202, 0xd1d1fdfe, 0xd1d20606, 0xd1d1f9fa, + 0xd1d20c0c, 0xd1d1f3f4, 0xd1d21414, 0xd1d1ebec, 0xd1d22020, 0xd1d1dfe0, 0xd1d22e2e, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, + 0xffffebec, 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, 0xffffebec, + 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020606, + 0x0201f9fa, 0x02020c0c, 0x0201f3f4, 0x02021414, 0x0201ebec, 0x02022020, 0x0201dfe0, 0x02022e2e, + 0x0201d1d2, 0xfdfe0000, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0c0c, 0xfdfdf3f4, + 0xfdfe1414, 0xfdfdebec, 0xfdfe2020, 0xfdfddfe0, 0xfdfe2e2e, 0xfdfdd1d2, 0x06060000, 0x06060202, + 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060c0c, 0x0605f3f4, 0x06061414, 0x0605ebec, 0x06062020, + 0x0605dfe0, 0x06062e2e, 0x0605d1d2, 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa, + 0xf9fa0c0c, 0xf9f9f3f4, 0xf9fa1414, 0xf9f9ebec, 0xf9fa2020, 0xf9f9dfe0, 0xf9fa2e2e, 0xf9f9d1d2, + 0x0c0c0000, 0x0c0c0202, 0x0c0bfdfe, 0x0c0c0606, 0x0c0bf9fa, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c1414, + 0x0c0bebec, 0x0c0c2020, 0x0c0bdfe0, 0x0c0c2e2e, 0x0c0bd1d2, 0xf3f40000, 0xf3f40202, 0xf3f3fdfe, + 0xf3f40606, 0xf3f3f9fa, 0xf3f40c0c, 0xf3f3f3f4, 0xf3f41414, 0xf3f3ebec, 0xf3f42020, 0xf3f3dfe0, + 0xf3f42e2e, 0xf3f3d1d2, 0x14140000, 0x14140202, 0x1413fdfe, 0x14140606, 0x1413f9fa, 0x14140c0c, + 0x1413f3f4, 0x14141414, 0x1413ebec, 0x14142020, 0x1413dfe0, 0x14142e2e, 0x1413d1d2, 0xebec0000, + 0xebec0202, 0xebebfdfe, 0xebec0606, 0xebebf9fa, 0xebec0c0c, 0xebebf3f4, 0xebec1414, 0xebebebec, + 0xebec2020, 0xebebdfe0, 0xebec2e2e, 0xebebd1d2, 0x20200000, 0x20200202, 0x201ffdfe, 0x20200606, + 0x201ff9fa, 0x20200c0c, 0x201ff3f4, 0x20201414, 0x201febec, 0x20202020, 0x201fdfe0, 0x20202e2e, + 0x201fd1d2, 0xdfe00000, 0xdfe00202, 0xdfdffdfe, 0xdfe00606, 0xdfdff9fa, 0xdfe00c0c, 0xdfdff3f4, + 0xdfe01414, 0xdfdfebec, 0xdfe02020, 0xdfdfdfe0, 0xdfe02e2e, 0xdfdfd1d2, 0x2e2e0000, 0x2e2e0202, + 0x2e2dfdfe, 0x2e2e0606, 0x2e2df9fa, 0x2e2e0c0c, 0x2e2df3f4, 0x2e2e1414, 0x2e2debec, 0x2e2e2020, + 0x2e2ddfe0, 0x2e2e2e2e, 0x2e2dd1d2, 0xd1d20000, 0xd1d20202, 0xd1d1fdfe, 0xd1d20606, 0xd1d1f9fa, + 0xd1d20c0c, 0xd1d1f3f4, 0xd1d21414, 0xd1d1ebec, 0xd1d22020, 0xd1d1dfe0, 0xd1d22e2e, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, + 0xffffebec, 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, 0xffffebec, + 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020606, + 0x0201f9fa, 0x02020c0c, 0x0201f3f4, 0x02021414, 0x0201ebec, 0x02022020, 0x0201dfe0, 0x02022e2e, + 0x0201d1d2, 0xfdfe0000, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0c0c, 0xfdfdf3f4, + 0xfdfe1414, 0xfdfdebec, 0xfdfe2020, 0xfdfddfe0, 0xfdfe2e2e, 0xfdfdd1d2, 0x06060000, 0x06060202, + 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060c0c, 0x0605f3f4, 0x06061414, 0x0605ebec, 0x06062020, + 0x0605dfe0, 0x06062e2e, 0x0605d1d2, 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa, + 0xf9fa0c0c, 0xf9f9f3f4, 0xf9fa1414, 0xf9f9ebec, 0xf9fa2020, 0xf9f9dfe0, 0xf9fa2e2e, 0xf9f9d1d2, + 0x0c0c0000, 0x0c0c0202, 0x0c0bfdfe, 0x0c0c0606, 0x0c0bf9fa, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c1414, + 0x0c0bebec, 0x0c0c2020, 0x0c0bdfe0, 0x0c0c2e2e, 0x0c0bd1d2, 0xf3f40000, 0xf3f40202, 0xf3f3fdfe, + 0xf3f40606, 0xf3f3f9fa, 0xf3f40c0c, 0xf3f3f3f4, 0xf3f41414, 0xf3f3ebec, 0xf3f42020, 0xf3f3dfe0, + 0xf3f42e2e, 0xf3f3d1d2, 0x14140000, 0x14140202, 0x1413fdfe, 0x14140606, 0x1413f9fa, 0x14140c0c, + 0x1413f3f4, 0x14141414, 0x1413ebec, 0x14142020, 0x1413dfe0, 0x14142e2e, 0x1413d1d2, 0xebec0000, + 0xebec0202, 0xebebfdfe, 0xebec0606, 0xebebf9fa, 0xebec0c0c, 0xebebf3f4, 0xebec1414, 0xebebebec, + 0xebec2020, 0xebebdfe0, 0xebec2e2e, 0xebebd1d2, 0x20200000, 0x20200202, 0x201ffdfe, 0x20200606, + 0x201ff9fa, 0x20200c0c, 0x201ff3f4, 0x20201414, 0x201febec, 0x20202020, 0x201fdfe0, 0x20202e2e, + 0x201fd1d2, 0xdfe00000, 0xdfe00202, 0xdfdffdfe, 0xdfe00606, 0xdfdff9fa, 0xdfe00c0c, 0xdfdff3f4, + 0xdfe01414, 0xdfdfebec, 0xdfe02020, 0xdfdfdfe0, 0xdfe02e2e, 0xdfdfd1d2, 0x2e2e0000, 0x2e2e0202, + 0x2e2dfdfe, 0x2e2e0606, 0x2e2df9fa, 0x2e2e0c0c, 0x2e2df3f4, 0x2e2e1414, 0x2e2debec, 0x2e2e2020, + 0x2e2ddfe0, 0x2e2e2e2e, 0x2e2dd1d2, 0xd1d20000, 0xd1d20202, 0xd1d1fdfe, 0xd1d20606, 0xd1d1f9fa, + 0xd1d20c0c, 0xd1d1f3f4, 0xd1d21414, 0xd1d1ebec, 0xd1d22020, 0xd1d1dfe0, 0xd1d22e2e, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, + 0xffffebec, 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000202, 0xfffffdfe, 0x00000606, 0xfffff9fa, 0x00000c0c, 0xfffff3f4, 0x00001414, 0xffffebec, + 0x00002020, 0xffffdfe0, 0x00002e2e, 0xffffd1d2, 0x02020000, 0x02020202, 0x0201fdfe, 0x02020606, + 0x0201f9fa, 0x02020c0c, 0x0201f3f4, 0x02021414, 0x0201ebec, 0x02022020, 0x0201dfe0, 0x02022e2e, + 0x0201d1d2, 0xfdfe0000, 0xfdfe0202, 0xfdfdfdfe, 0xfdfe0606, 0xfdfdf9fa, 0xfdfe0c0c, 0xfdfdf3f4, + 0xfdfe1414, 0xfdfdebec, 0xfdfe2020, 0xfdfddfe0, 0xfdfe2e2e, 0xfdfdd1d2, 0x06060000, 0x06060202, + 0x0605fdfe, 0x06060606, 0x0605f9fa, 0x06060c0c, 0x0605f3f4, 0x06061414, 0x0605ebec, 0x06062020, + 0x0605dfe0, 0x06062e2e, 0x0605d1d2, 0xf9fa0000, 0xf9fa0202, 0xf9f9fdfe, 0xf9fa0606, 0xf9f9f9fa, + 0xf9fa0c0c, 0xf9f9f3f4, 0xf9fa1414, 0xf9f9ebec, 0xf9fa2020, 0xf9f9dfe0, 0xf9fa2e2e, 0xf9f9d1d2, + 0x0c0c0000, 0x0c0c0202, 0x0c0bfdfe, 0x0c0c0606, 0x0c0bf9fa, 0x0c0c0c0c, 0x0c0bf3f4, 0x0c0c1414, + 0x0c0bebec, 0x0c0c2020, 0x0c0bdfe0, 0x0c0c2e2e, 0x0c0bd1d2, 0xf3f40000, 0xf3f40202, 0xf3f3fdfe, + 0xf3f40606, 0xf3f3f9fa, 0xf3f40c0c, 0xf3f3f3f4, 0xf3f41414, 0xf3f3ebec, 0xf3f42020, 0xf3f3dfe0, + 0xf3f42e2e, 0xf3f3d1d2, 0x14140000, 0x14140202, 0x1413fdfe, 0x14140606, 0x1413f9fa, 0x14140c0c, + 0x1413f3f4, 0x14141414, 0x1413ebec, 0x14142020, 0x1413dfe0, 0x14142e2e, 0x1413d1d2, 0xebec0000, + 0xebec0202, 0xebebfdfe, 0xebec0606, 0xebebf9fa, 0xebec0c0c, 0xebebf3f4, 0xebec1414, 0xebebebec, + 0xebec2020, 0xebebdfe0, 0xebec2e2e, 0xebebd1d2, 0x20200000, 0x20200202, 0x201ffdfe, 0x20200606, + 0x201ff9fa, 0x20200c0c, 0x201ff3f4, 0x20201414, 0x201febec, 0x20202020, 0x201fdfe0, 0x20202e2e, + 0x201fd1d2, 0xdfe00000, 0xdfe00202, 0xdfdffdfe, 0xdfe00606, 0xdfdff9fa, 0xdfe00c0c, 0xdfdff3f4, + 0xdfe01414, 0xdfdfebec, 0xdfe02020, 0xdfdfdfe0, 0xdfe02e2e, 0xdfdfd1d2, 0x2e2e0000, 0x2e2e0202, + 0x2e2dfdfe, 0x2e2e0606, 0x2e2df9fa, 0x2e2e0c0c, 0x2e2df3f4, 0x2e2e1414, 0x2e2debec, 0x2e2e2020, + 0x2e2ddfe0, 0x2e2e2e2e, 0x2e2dd1d2, 0xd1d20000, 0xd1d20202, 0xd1d1fdfe, 0xd1d20606, 0xd1d1f9fa, + 0xd1d20c0c, 0xd1d1f3f4, 0xd1d21414, 0xd1d1ebec, 0xd1d22020, 0xd1d1dfe0, 0xd1d22e2e, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + + +static const uint32_t correctionloworder[] = { + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x04040404, + 0xfbfbfbfc, 0x05050101, 0xfafafeff, 0x01010505, 0xfefefafb, 0x0403fbfc, 0xfbfc0404, 0x0605fdfe, + 0xf9fa0202, 0xfdfe0606, 0x0201f9fa, 0x09090404, 0xf6f6fbfc, 0x04040909, 0xfbfbf6f7, 0x09090909, + 0xf6f6f6f7, 0x0a0a0101, 0xf5f5feff, 0x01010a0a, 0xfefef5f6, 0x0807fafb, 0xf7f80505, 0xfafb0808, + 0x0504f7f8, 0x0f0f0909, 0xf0f0f6f7, 0x09090f0f, 0xf6f6f0f1, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, + 0x0302f3f4, 0x10100404, 0xefeffbfc, 0x04041010, 0xfbfbeff0, 0x10101010, 0xefefeff0, 0x12120000, + 0xedee0000, 0x00001212, 0xffffedee, 0x0c0bf3f4, 0xf3f40c0c, 0x100ff6f7, 0xeff00909, 0xf6f71010, + 0x0908eff0, 0x1b1b0b0b, 0xe4e4f4f5, 0x0b0b1b1b, 0xf4f4e4e5, 0x1c1c1313, 0xe3e3eced, 0x13131c1c, + 0xecece3e4, 0x1615f9fa, 0xe9ea0606, 0xf9fa1616, 0x0605e9ea, 0x1d1d0404, 0xe2e2fbfc, 0x04041d1d, + 0xfbfbe2e3, 0x1e1e1e1e, 0xe1e1e1e2, 0x2120fdfe, 0xdedf0202, 0xfdfe2121, 0x0201dedf, 0x1716edee, + 0xe8e91212, 0xedee1717, 0x1211e8e9, 0x1e1df0f1, 0xe1e20f0f, 0xf0f11e1e, 0x0f0ee1e2, 0x2e2e1616, + 0xd1d1e9ea, 0x16162e2e, 0xe9e9d1d2, 0x2f2f0d0d, 0xd0d0f2f3, 0x0d0d2f2f, 0xf2f2d0d1, 0x31312323, + 0xcecedcdd, 0x23233131, 0xdcdccecf, 0x2928f4f5, 0xd6d70b0b, 0xf4f52929, 0x0b0ad6d7, 0x33330404, + 0xccccfbfc, 0x04043333, 0xfbfbcccd, 0x36363636, 0xc9c9c9ca, 0x2221ddde, 0xddde2222, 0x2a29e2e3, + 0xd5d61d1d, 0xe2e32a2a, 0x1d1cd5d6, 0x3c3bf9fa, 0xc3c40606, 0xf9fa3c3c, 0x0605c3c4, 0x4c4c1b1b, + 0xb3b3e4e5, 0x1b1b4c4c, 0xe4e4b3b4, 0x4d4d2b2b, 0xb2b2d4d5, 0x2b2b4d4d, 0xd4d4b2b3, 0x3736e7e8, + 0xc8c91818, 0xe7e83737, 0x1817c8c9, 0x4f4f0e0e, 0xb0b0f1f2, 0x0e0e4f4f, 0xf1f1b0b1, 0x53533f3f, + 0xacacc0c1, 0x3f3f5353, 0xc0c0acad, 0x4a49ebec, 0xb5b61414, 0xebec4a4a, 0x1413b5b6, 0x58580202, + 0xa7a7fdfe, 0x02025858, 0xfdfda7a8, 0x5d5d5d5d, 0xa2a2a2a3, 0x3d3ccbcc, 0xc2c33434, 0xcbcc3d3d, + 0x3433c2c3, 0x78783434, 0x8787cbcc, 0x34347878, 0xcbcb8788, 0x4b4ad2d3, 0xb4b52d2d, 0xd2d34b4b, + 0x2d2cb4b5, 0x7d7d4b4b, 0x8282b4b5, 0x4b4b7d7d, 0xb4b48283, 0x7a7a2121, 0x8585dedf, 0x21217a7a, + 0xdede8586, 0x6766f2f3, 0x98990d0d, 0xf2f36767, 0x0d0c9899, 0x605fd7d8, 0x9fa02828, 0xd7d86060, + 0x28279fa0, 0x7f7eddde, 0x80812222, 0xddde7f7f, 0x22218081, 0x5958a6a7, 0xa6a75959, 0x6968b1b2, + 0x96974e4e, 0xb1b26969, 0x4e4d9697, 0x0c0c0c0c, 0xf3f3f3f4, 0x17171717, 0xe8e8e8e9, 0x2a2a2a2a, + 0xd5d5d5d6, 0x49494949, 0xb6b6b6b7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, + 0x0302feff, 0x0302feff, 0x0302feff, 0x0302feff, 0x0302feff, 0x0302feff, 0x0302feff, 0xfcfd0101, + 0xfcfd0101, 0xfcfd0101, 0xfcfd0101, 0xfcfd0101, 0xfcfd0101, 0xfcfd0101, 0xfeff0303, 0xfeff0303, + 0xfeff0303, 0xfeff0303, 0xfeff0303, 0xfeff0303, 0xfeff0303, 0x0100fcfd, 0x0100fcfd, 0x0100fcfd, + 0x0100fcfd, 0x0100fcfd, 0x0100fcfd, 0x0100fcfd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, + 0xf8f8f8f9, 0x08080202, 0xf7f7fdfe, 0x02020808, 0xfdfdf7f8, 0x0908fdfe, 0xf6f70202, 0xfdfe0909, + 0x0201f6f7, 0x0605f9fa, 0xf9fa0606, 0x0d0d0606, 0xf2f2f9fa, 0x06060d0d, 0xf9f9f2f3, 0x0d0d0d0d, + 0xf2f2f2f3, 0x0e0e0101, 0xf1f1feff, 0x01010e0e, 0xfefef1f2, 0x0c0bf7f8, 0xf3f40808, 0xf7f80c0c, + 0x0807f3f4, 0x17170e0e, 0xe8e8f1f2, 0x0e0e1717, 0xf1f1e8e9, 0x1211fafb, 0xedee0505, 0xfafb1212, + 0x0504edee, 0x18180606, 0xe7e7f9fa, 0x06061818, 0xf9f9e7e8, 0x18181818, 0xe7e7e7e8, 0x1b1afeff, + 0xe4e50101, 0xfeff1b1b, 0x0100e4e5, 0x1110eeef, 0xeeef1111, 0x1716f2f3, 0xe8e90d0d, 0xf2f31717, + 0x0d0ce8e9, 0x28281010, 0xd7d7eff0, 0x10102828, 0xefefd7d8, 0x29291c1c, 0xd6d6e3e4, 0x1c1c2929, + 0xe3e3d6d7, 0x2120f6f7, 0xdedf0909, 0xf6f72121, 0x0908dedf, 0x2b2b0606, 0xd4d4f9fa, 0x06062b2b, + 0xf9f9d4d5, 0x2e2e2e2e, 0xd1d1d1d2, 0x3231fbfc, 0xcdce0404, 0xfbfc3232, 0x0403cdce, 0x2221e4e5, + 0xddde1b1b, 0xe4e52222, 0x1b1addde, 0x2d2ce9ea, 0xd2d31616, 0xe9ea2d2d, 0x1615d2d3, 0x45452222, + 0xbabaddde, 0x22224545, 0xddddbabb, 0x46461313, 0xb9b9eced, 0x13134646, 0xececb9ba, 0x49493535, + 0xb6b6cacb, 0x35354949, 0xcacab6b7, 0x3e3deeef, 0xc1c21111, 0xeeef3e3e, 0x1110c1c2, 0x4d4d0505, + 0xb2b2fafb, 0x05054d4d, 0xfafab2b3, 0x52525252, 0xadadadae, 0x3332cccd, 0xcccd3333, 0x403fd4d5, + 0xbfc02b2b, 0xd4d54040, 0x2b2abfc0, 0x5a59f5f6, 0xa5a60a0a, 0xf5f65a5a, 0x0a09a5a6, 0x72722929, + 0x8d8dd6d7, 0x29297272, 0xd6d68d8e, 0x74744040, 0x8b8bbfc0, 0x40407474, 0xbfbf8b8c, 0x5251dadb, + 0xadae2525, 0xdadb5252, 0x2524adae, 0x77771616, 0x8888e9ea, 0x16167777, 0xe9e98889, 0x7c7c5f5f, + 0x8383a0a1, 0x5f5f7c7c, 0xa0a08384, 0x6f6ee1e2, 0x90911e1e, 0xe1e26f6f, 0x1e1d9091, 0x5c5bb1b2, + 0xa3a44e4e, 0xb1b25c5c, 0x4e4da3a4, 0x7170bbbc, 0x8e8f4444, 0xbbbc7171, 0x44438e8f, 0x12121212, + 0xedededee, 0x22222222, 0xddddddde, 0x3f3f3f3f, 0xc0c0c0c1, 0x6d6d6d6d, 0x92929293, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, + 0x03030303, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, + 0xfcfcfcfd, 0xfcfcfcfd, 0x0403feff, 0x0403feff, 0x0403feff, 0x0403feff, 0x0403feff, 0x0403feff, + 0x0403feff, 0x0403feff, 0x0403feff, 0xfbfc0101, 0xfbfc0101, 0xfbfc0101, 0xfbfc0101, 0xfbfc0101, + 0xfbfc0101, 0xfbfc0101, 0xfbfc0101, 0xfbfc0101, 0xfeff0404, 0xfeff0404, 0xfeff0404, 0xfeff0404, + 0xfeff0404, 0xfeff0404, 0xfeff0404, 0xfeff0404, 0xfeff0404, 0x0100fbfc, 0x0100fbfc, 0x0100fbfc, + 0x0100fbfc, 0x0100fbfc, 0x0100fbfc, 0x0100fbfc, 0x0100fbfc, 0x0100fbfc, 0x07070707, 0x07070707, + 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0xf8f8f8f9, + 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, + 0xf5f5fcfd, 0x03030a0a, 0xfcfcf5f6, 0x09090909, 0xf6f6f6f7, 0x0706f8f9, 0xf8f90707, 0x0c0bfcfd, + 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x11110808, 0xeeeef7f8, 0x08081111, 0xf7f7eeef, 0x11111111, + 0xeeeeeeef, 0x13130101, 0xececfeff, 0x01011313, 0xfefeeced, 0x100ff4f5, 0xeff00b0b, 0xf4f51010, + 0x0b0aeff0, 0x1716f9fa, 0xe8e90606, 0xf9fa1717, 0x0605e8e9, 0x1f1f1212, 0xe0e0edee, 0x12121f1f, + 0xedede0e1, 0x20200808, 0xdfdff7f8, 0x08082020, 0xf7f7dfe0, 0x21212121, 0xdedededf, 0x2423feff, + 0xdbdc0101, 0xfeff2424, 0x0100dbdc, 0x1716e8e9, 0xe8e91717, 0x1f1eeeef, 0xe0e11111, 0xeeef1f1f, + 0x1110e0e1, 0x36361515, 0xc9c9eaeb, 0x15153636, 0xeaeac9ca, 0x37372525, 0xc8c8dadb, 0x25253737, + 0xdadac8c9, 0x2c2bf3f4, 0xd3d40c0c, 0xf3f42c2c, 0x0c0bd3d4, 0x39390808, 0xc6c6f7f8, 0x08083939, + 0xf7f7c6c7, 0x3d3d3d3d, 0xc2c2c2c3, 0x4241fafb, 0xbdbe0505, 0xfafb4242, 0x0504bdbe, 0x2d2cdbdc, + 0xd2d32424, 0xdbdc2d2d, 0x2423d2d3, 0x3c3be2e3, 0xc3c41d1d, 0xe2e33c3c, 0x1d1cc3c4, 0x5c5c2d2d, + 0xa3a3d2d3, 0x2d2d5c5c, 0xd2d2a3a4, 0x5d5d1919, 0xa2a2e6e7, 0x19195d5d, 0xe6e6a2a3, 0x61614747, + 0x9e9eb8b9, 0x47476161, 0xb8b89e9f, 0x5352e9ea, 0xacad1616, 0xe9ea5353, 0x1615acad, 0x66660707, + 0x9999f8f9, 0x07076666, 0xf8f8999a, 0x6d6d6d6d, 0x92929293, 0x4443bbbc, 0xbbbc4444, 0x5554c6c7, + 0xaaab3939, 0xc6c75555, 0x3938aaab, 0x7877f2f3, 0x87880d0d, 0xf2f37878, 0x0d0c8788, 0x6e6dcecf, + 0x91923131, 0xcecf6e6e, 0x31309192, 0x7b7a9798, 0x84856868, 0x97987b7b, 0x68678485, 0x18181818, + 0xe7e7e7e8, 0x2e2e2e2e, 0xd1d1d1d2, 0x54545454, 0xabababac, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04040404, + 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, + 0x04040404, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, + 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0x0504feff, 0x0504feff, 0x0504feff, 0x0504feff, 0x0504feff, + 0x0504feff, 0x0504feff, 0x0504feff, 0x0504feff, 0x0504feff, 0xfafb0101, 0xfafb0101, 0xfafb0101, + 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfafb0101, 0xfeff0505, + 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505, 0xfeff0505, + 0xfeff0505, 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0100fafb, + 0x0100fafb, 0x0100fafb, 0x0100fafb, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, + 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0x0a0a0303, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, + 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0xf5f5fcfd, 0x03030a0a, + 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a, 0x03030a0a, + 0x03030a0a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, + 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x03030d0d, 0xfcfcf2f3, 0x0908f6f7, 0xf6f70909, 0x0f0efbfc, + 0xf0f10404, 0xfbfc0f0f, 0x0403f0f1, 0x16160b0b, 0xe9e9f4f5, 0x0b0b1616, 0xf4f4e9ea, 0x15151515, + 0xeaeaeaeb, 0x18180202, 0xe7e7fdfe, 0x02021818, 0xfdfde7e8, 0x1413f1f2, 0xebec0e0e, 0xf1f21414, + 0x0e0debec, 0x26261717, 0xd9d9e8e9, 0x17172626, 0xe8e8d9da, 0x1d1cf7f8, 0xe2e30808, 0xf7f81d1d, + 0x0807e2e3, 0x27270b0b, 0xd8d8f4f5, 0x0b0b2727, 0xf4f4d8d9, 0x29292929, 0xd6d6d6d7, 0x2d2cfeff, + 0xd2d30101, 0xfeff2d2d, 0x0100d2d3, 0x1d1ce2e3, 0xe2e31d1d, 0x2726e9ea, 0xd8d91616, 0xe9ea2727, + 0x1615d8d9, 0x43431b1b, 0xbcbce4e5, 0x1b1b4343, 0xe4e4bcbd, 0x45452f2f, 0xbabad0d1, 0x2f2f4545, + 0xd0d0babb, 0x3837f0f1, 0xc7c80f0f, 0xf0f13838, 0x0f0ec7c8, 0x47470b0b, 0xb8b8f4f5, 0x0b0b4747, + 0xf4f4b8b9, 0x4c4c4c4c, 0xb3b3b3b4, 0x5352f9fa, 0xacad0606, 0xf9fa5353, 0x0605acad, 0x3938d2d3, + 0xc6c72d2d, 0xd2d33939, 0x2d2cc6c7, 0x4b4adbdc, 0xb4b52424, 0xdbdc4b4b, 0x2423b4b5, 0x73733838, + 0x8c8cc7c8, 0x38387373, 0xc7c78c8d, 0x75751f1f, 0x8a8ae0e1, 0x1f1f7575, 0xe0e08a8b, 0x7a7a5858, + 0x8585a7a8, 0x58587a7a, 0xa7a78586, 0x6867e3e4, 0x97981c1c, 0xe3e46868, 0x1c1b9798, 0x5554aaab, + 0xaaab5555, 0x6a69b7b8, 0x95964848, 0xb7b86a6a, 0x48479596, 0x1e1e1e1e, 0xe1e1e1e2, 0x3a3a3a3a, + 0xc5c5c5c6, 0x69696969, 0x96969697, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x05050505, 0x05050505, + 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, + 0x05050505, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, + 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, + 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0x0706fdfe, 0xf8f90202, + 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202, 0xf8f90202, + 0xf8f90202, 0xf8f90202, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, + 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0xfdfe0707, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, + 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, 0x0201f8f9, + 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, + 0x0b0b0b0b, 0x0b0b0b0b, 0x0b0b0b0b, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, + 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0xf4f4f4f5, 0x0d0d0303, 0x0d0d0303, + 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, 0x0d0d0303, + 0x0d0d0303, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, + 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0xf2f2fcfd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, + 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0xfbfbf0f1, 0x0b0af4f5, 0xf4f50b0b, 0x1211fafb, + 0xedee0505, 0xfafb1212, 0x0504edee, 0x1a1a0d0d, 0xe5e5f2f3, 0x0d0d1a1a, 0xf2f2e5e6, 0x1a1a1a1a, + 0xe5e5e5e6, 0x1d1d0202, 0xe2e2fdfe, 0x02021d1d, 0xfdfde2e3, 0x1817eff0, 0xe7e81010, 0xeff01818, + 0x100fe7e8, 0x2e2e1c1c, 0xd1d1e3e4, 0x1c1c2e2e, 0xe3e3d1d2, 0x2322f6f7, 0xdcdd0909, 0xf6f72323, + 0x0908dcdd, 0x2f2f0d0d, 0xd0d0f2f3, 0x0d0d2f2f, 0xf2f2d0d1, 0x31313131, 0xcecececf, 0x3635feff, + 0xc9ca0101, 0xfeff3636, 0x0100c9ca, 0x2322dcdd, 0xdcdd2323, 0x2f2ee5e6, 0xd0d11a1a, 0xe5e62f2f, + 0x1a19d0d1, 0x51512020, 0xaeaedfe0, 0x20205151, 0xdfdfaeaf, 0x53533838, 0xacacc7c8, 0x38385353, + 0xc7c7acad, 0x4342edee, 0xbcbd1212, 0xedee4343, 0x1211bcbd, 0x56560d0d, 0xa9a9f2f3, 0x0d0d5656, + 0xf2f2a9aa, 0x5b5b5b5b, 0xa4a4a4a5, 0x6362f8f9, 0x9c9d0707, 0xf8f96363, 0x07069c9d, 0x4443c9ca, + 0xbbbc3636, 0xc9ca4444, 0x3635bbbc, 0x5a59d3d4, 0xa5a62c2c, 0xd3d45a5a, 0x2c2ba5a6, 0x7c7bdedf, + 0x83842121, 0xdedf7c7c, 0x21208384, 0x67669899, 0x98996767, 0x7f7ea9aa, 0x80815656, 0xa9aa7f7f, + 0x56558081, 0x25252525, 0xdadadadb, 0x45454545, 0xbabababb, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, + 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0x0807fdfe, 0xf7f80202, 0xf7f80202, 0xf7f80202, + 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202, 0xf7f80202, + 0xf7f80202, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, + 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0xfdfe0808, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, + 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, 0x0201f7f8, + 0x0201f7f8, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, + 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0x0d0d0d0d, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, + 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, 0xf2f2f2f3, + 0xf2f2f2f3, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, + 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0x0f0f0404, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, + 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, 0xf0f0fbfc, + 0xf0f0fbfc, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, + 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x04040f0f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, + 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0xfafaedee, 0x0d0cf2f3, 0xf2f30d0d, 0x1514f9fa, + 0xeaeb0606, 0xf9fa1515, 0x0605eaeb, 0x1e1e0f0f, 0xe1e1f0f1, 0x0f0f1e1e, 0xf0f0e1e2, 0x1e1e1e1e, + 0xe1e1e1e2, 0x22220202, 0xddddfdfe, 0x02022222, 0xfdfdddde, 0x1c1beced, 0xe3e41313, 0xeced1c1c, + 0x1312e3e4, 0x36362020, 0xc9c9dfe0, 0x20203636, 0xdfdfc9ca, 0x2928f4f5, 0xd6d70b0b, 0xf4f52929, + 0x0b0ad6d7, 0x37370f0f, 0xc8c8f0f1, 0x0f0f3737, 0xf0f0c8c9, 0x39393939, 0xc6c6c6c7, 0x3f3efeff, + 0xc0c10101, 0xfeff3f3f, 0x0100c0c1, 0x2827d7d8, 0xd7d82828, 0x3736e1e2, 0xc8c91e1e, 0xe1e23737, + 0x1e1dc8c9, 0x5e5e2525, 0xa1a1dadb, 0x25255e5e, 0xdadaa1a2, 0x60604141, 0x9f9fbebf, 0x41416060, + 0xbebe9fa0, 0x4e4deaeb, 0xb1b21515, 0xeaeb4e4e, 0x1514b1b2, 0x64640f0f, 0x9b9bf0f1, 0x0f0f6464, + 0xf0f09b9c, 0x6a6a6a6a, 0x95959596, 0x7473f7f8, 0x8b8c0808, 0xf7f87474, 0x08078b8c, 0x4f4ec0c1, + 0xb0b13f3f, 0xc0c14f4f, 0x3f3eb0b1, 0x6968cccd, 0x96973333, 0xcccd6969, 0x33329697, 0x78778788, + 0x87887878, 0x2b2b2b2b, 0xd4d4d4d5, 0x50505050, 0xafafafb0, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, + 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, + 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, + 0xf8f8f8f9, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, + 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0x0a09fcfd, 0xf5f60303, 0xf5f60303, 0xf5f60303, + 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303, 0xf5f60303, + 0xf5f60303, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, + 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0xfcfd0a0a, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, + 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, 0x0302f5f6, + 0x0302f5f6, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0xefefeff0, 0xefefeff0, 0xefefeff0, + 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, + 0xefefeff0, 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0x12120505, + 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0x12120505, 0xededfafb, 0xededfafb, 0xededfafb, + 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb, 0xededfafb, + 0xededfafb, 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x05051212, + 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x05051212, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, + 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0xfafaebec, 0x0f0ef0f1, 0xf0f10f0f, 0x1817f8f9, + 0xe7e80707, 0xf8f91818, 0x0706e7e8, 0x23231111, 0xdcdceeef, 0x11112323, 0xeeeedcdd, 0x22222222, + 0xddddddde, 0x26260303, 0xd9d9fcfd, 0x03032626, 0xfcfcd9da, 0x201fe9ea, 0xdfe01616, 0xe9ea2020, + 0x1615dfe0, 0x3d3d2525, 0xc2c2dadb, 0x25253d3d, 0xdadac2c3, 0x2f2ef2f3, 0xd0d10d0d, 0xf2f32f2f, + 0x0d0cd0d1, 0x3f3f1111, 0xc0c0eeef, 0x11113f3f, 0xeeeec0c1, 0x41414141, 0xbebebebf, 0x4847feff, + 0xb7b80101, 0xfeff4848, 0x0100b7b8, 0x2e2dd1d2, 0xd1d22e2e, 0x3f3edcdd, 0xc0c12323, 0xdcdd3f3f, + 0x2322c0c1, 0x6b6b2b2b, 0x9494d4d5, 0x2b2b6b6b, 0xd4d49495, 0x6e6e4b4b, 0x9191b4b5, 0x4b4b6e6e, + 0xb4b49192, 0x5958e7e8, 0xa6a71818, 0xe7e85959, 0x1817a6a7, 0x72721111, 0x8d8deeef, 0x11117272, + 0xeeee8d8e, 0x79797979, 0x86868687, 0x5b5ab7b8, 0xa4a54848, 0xb7b85b5b, 0x4847a4a5, 0x7877c5c6, + 0x87883a3a, 0xc5c67878, 0x3a398788, 0x31313131, 0xcecececf, 0x5c5c5c5c, 0xa3a3a3a4, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, + 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0xf7f7f7f8, + 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, + 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, + 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0x0b0afcfd, 0xf4f50303, + 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xf4f50303, + 0xf4f50303, 0xf4f50303, 0xf4f50303, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, + 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0xfcfd0b0b, 0x0302f4f5, + 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, + 0x0302f4f5, 0x0302f4f5, 0x0302f4f5, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, + 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0xedededee, + 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, + 0xedededee, 0xedededee, 0xedededee, 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0x14140505, + 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0x14140505, 0xebebfafb, + 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb, 0xebebfafb, + 0xebebfafb, 0xebebfafb, 0xebebfafb, 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x05051414, + 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x05051414, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, + 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x1110eeef, 0xeeef1111, 0x1b1af8f9, + 0xe4e50707, 0xf8f91b1b, 0x0706e4e5, 0x27271313, 0xd8d8eced, 0x13132727, 0xececd8d9, 0x27272727, + 0xd8d8d8d9, 0x2b2b0303, 0xd4d4fcfd, 0x03032b2b, 0xfcfcd4d5, 0x2423e7e8, 0xdbdc1818, 0xe7e82424, + 0x1817dbdc, 0x45452a2a, 0xbabad5d6, 0x2a2a4545, 0xd5d5babb, 0x3534f1f2, 0xcacb0e0e, 0xf1f23535, + 0x0e0dcacb, 0x47471313, 0xb8b8eced, 0x13134747, 0xececb8b9, 0x49494949, 0xb6b6b6b7, 0x504ffdfe, + 0xafb00202, 0xfdfe5050, 0x0201afb0, 0x3433cbcc, 0xcbcc3434, 0x4645d8d9, 0xb9ba2727, 0xd8d94646, + 0x2726b9ba, 0x79793030, 0x8686cfd0, 0x30307979, 0xcfcf8687, 0x7c7c5454, 0x8383abac, 0x54547c7c, + 0xabab8384, 0x6463e4e5, 0x9b9c1b1b, 0xe4e56464, 0x1b1a9b9c, 0x6665aeaf, 0x999a5151, 0xaeaf6666, + 0x5150999a, 0x37373737, 0xc8c8c8c9, 0x68686868, 0x97979798, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, + 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0xf6f6f6f7, + 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, + 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, + 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, 0x0c0bfcfd, + 0x0c0bfcfd, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, + 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xf3f40303, 0xfcfd0c0c, 0xfcfd0c0c, + 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, + 0xfcfd0c0c, 0xfcfd0c0c, 0xfcfd0c0c, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, + 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, 0x0302f3f4, + 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, + 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec, 0xebebebec, 0xebebebec, + 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, + 0xebebebec, 0xebebebec, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606, + 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0x17170606, 0xe8e8f9fa, + 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, + 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0xe8e8f9fa, 0x06061717, 0x06061717, 0x06061717, 0x06061717, + 0x06061717, 0x06061717, 0x06061717, 0x06061717, 0x06061717, 0x06061717, 0x06061717, 0x06061717, + 0x06061717, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, + 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0xf9f9e8e9, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, + 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x0403fbfc, 0xfbfc0404, 0x0605fdfe, + 0xf9fa0202, 0xfdfe0606, 0x0201f9fa, 0x08080404, 0xf7f7fbfc, 0x04040808, 0xfbfbf7f8, 0x08080808, + 0xf7f7f7f8, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x0807fbfc, 0xf7f80404, 0xfbfc0808, + 0x0403f7f8, 0x0e0e0808, 0xf1f1f7f8, 0x08080e0e, 0xf7f7f1f2, 0x0c0bfdfe, 0xf3f40202, 0xfdfe0c0c, + 0x0201f3f4, 0x10100404, 0xefeffbfc, 0x04041010, 0xfbfbeff0, 0x10101010, 0xefefeff0, 0x12120000, + 0xedee0000, 0x00001212, 0xffffedee, 0x0c0bf3f4, 0xf3f40c0c, 0x100ff7f8, 0xeff00808, 0xf7f81010, + 0x0807eff0, 0x1a1a0a0a, 0xe5e5f5f6, 0x0a0a1a1a, 0xf5f5e5e6, 0x1c1c1212, 0xe3e3edee, 0x12121c1c, + 0xedede3e4, 0x1615f9fa, 0xe9ea0606, 0xf9fa1616, 0x0605e9ea, 0x1c1c0404, 0xe3e3fbfc, 0x04041c1c, + 0xfbfbe3e4, 0x1e1e1e1e, 0xe1e1e1e2, 0x201ffdfe, 0xdfe00202, 0xfdfe2020, 0x0201dfe0, 0x1615edee, + 0xe9ea1212, 0xedee1616, 0x1211e9ea, 0x1e1df1f2, 0xe1e20e0e, 0xf1f21e1e, 0x0e0de1e2, 0x2e2e1616, + 0xd1d1e9ea, 0x16162e2e, 0xe9e9d1d2, 0x2e2e0c0c, 0xd1d1f3f4, 0x0c0c2e2e, 0xf3f3d1d2, 0x30302222, + 0xcfcfddde, 0x22223030, 0xddddcfd0, 0x2827f5f6, 0xd7d80a0a, 0xf5f62828, 0x0a09d7d8, 0x32320404, + 0xcdcdfbfc, 0x04043232, 0xfbfbcdce, 0x36363636, 0xc9c9c9ca, 0x2221ddde, 0xddde2222, 0x2a29e3e4, + 0xd5d61c1c, 0xe3e42a2a, 0x1c1bd5d6, 0x3c3bf9fa, 0xc3c40606, 0xf9fa3c3c, 0x0605c3c4, 0x4c4c1a1a, + 0xb3b3e5e6, 0x1a1a4c4c, 0xe5e5b3b4, 0x4c4c2a2a, 0xb3b3d5d6, 0x2a2a4c4c, 0xd5d5b3b4, 0x3635e7e8, + 0xc9ca1818, 0xe7e83636, 0x1817c9ca, 0x4e4e0e0e, 0xb1b1f1f2, 0x0e0e4e4e, 0xf1f1b1b2, 0x52523e3e, + 0xadadc1c2, 0x3e3e5252, 0xc1c1adae, 0x4a49ebec, 0xb5b61414, 0xebec4a4a, 0x1413b5b6, 0x58580202, + 0xa7a7fdfe, 0x02025858, 0xfdfda7a8, 0x5c5c5c5c, 0xa3a3a3a4, 0x3c3bcbcc, 0xc3c43434, 0xcbcc3c3c, + 0x3433c3c4, 0x76763434, 0x8989cbcc, 0x34347676, 0xcbcb898a, 0x4a49d3d4, 0xb5b62c2c, 0xd3d44a4a, + 0x2c2bb5b6, 0x76764a4a, 0x8989b5b6, 0x4a4a7676, 0xb5b5898a, 0x76762020, 0x8989dfe0, 0x20207676, + 0xdfdf898a, 0x6665f3f4, 0x999a0c0c, 0xf3f46666, 0x0c0b999a, 0x605fd7d8, 0x9fa02828, 0xd7d86060, + 0x28279fa0, 0x7675ddde, 0x898a2222, 0xddde7676, 0x2221898a, 0x5857a7a8, 0xa7a85858, 0x6867b1b2, + 0x97984e4e, 0xb1b26868, 0x4e4d9798, 0x0c0c0c0c, 0xf3f3f3f4, 0x16161616, 0xe9e9e9ea, 0x2a2a2a2a, + 0xd5d5d5d6, 0x48484848, 0xb7b7b7b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, + 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0xfdfe0000, + 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0x00000202, 0x00000202, + 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, + 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, + 0xf9f9f9fa, 0x09090303, 0xf6f6fcfd, 0x03030909, 0xfcfcf6f7, 0x0908fcfd, 0xf6f70303, 0xfcfd0909, + 0x0302f6f7, 0x0605f9fa, 0xf9fa0606, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0xf9f9f3f4, 0x0c0c0c0c, + 0xf3f3f3f4, 0x0f0f0000, 0xf0f10000, 0x00000f0f, 0xfffff0f1, 0x0c0bf6f7, 0xf3f40909, 0xf6f70c0c, + 0x0908f3f4, 0x18180f0f, 0xe7e7f0f1, 0x0f0f1818, 0xf0f0e7e8, 0x1211f9fa, 0xedee0606, 0xf9fa1212, + 0x0605edee, 0x18180606, 0xe7e7f9fa, 0x06061818, 0xf9f9e7e8, 0x18181818, 0xe7e7e7e8, 0x1b1b0000, + 0xe4e50000, 0x00001b1b, 0xffffe4e5, 0x1211edee, 0xedee1212, 0x1817f3f4, 0xe7e80c0c, 0xf3f41818, + 0x0c0be7e8, 0x27270f0f, 0xd8d8f0f1, 0x0f0f2727, 0xf0f0d8d9, 0x2a2a1b1b, 0xd5d5e4e5, 0x1b1b2a2a, + 0xe4e4d5d6, 0x2120f6f7, 0xdedf0909, 0xf6f72121, 0x0908dedf, 0x2a2a0606, 0xd5d5f9fa, 0x06062a2a, + 0xf9f9d5d6, 0x2d2d2d2d, 0xd2d2d2d3, 0x3332fcfd, 0xcccd0303, 0xfcfd3333, 0x0302cccd, 0x2120e4e5, + 0xdedf1b1b, 0xe4e52121, 0x1b1adedf, 0x2d2ceaeb, 0xd2d31515, 0xeaeb2d2d, 0x1514d2d3, 0x45452121, + 0xbabadedf, 0x21214545, 0xdedebabb, 0x45451212, 0xbabaedee, 0x12124545, 0xededbabb, 0x48483636, + 0xb7b7c9ca, 0x36364848, 0xc9c9b7b8, 0x3f3eedee, 0xc0c11212, 0xedee3f3f, 0x1211c0c1, 0x4e4e0606, + 0xb1b1f9fa, 0x06064e4e, 0xf9f9b1b2, 0x51515151, 0xaeaeaeaf, 0x3332cccd, 0xcccd3333, 0x3f3ed5d6, + 0xc0c12a2a, 0xd5d63f3f, 0x2a29c0c1, 0x5a59f6f7, 0xa5a60909, 0xf6f75a5a, 0x0908a5a6, 0x72722a2a, + 0x8d8dd5d6, 0x2a2a7272, 0xd5d58d8e, 0x75753f3f, 0x8a8ac0c1, 0x3f3f7575, 0xc0c08a8b, 0x5150dbdc, + 0xaeaf2424, 0xdbdc5151, 0x2423aeaf, 0x78781515, 0x8787eaeb, 0x15157878, 0xeaea8788, 0x7b7b6060, + 0x84849fa0, 0x60607b7b, 0x9f9f8485, 0x6f6ee1e2, 0x90911e1e, 0xe1e26f6f, 0x1e1d9091, 0x5d5cb1b2, + 0xa2a34e4e, 0xb1b25d5d, 0x4e4da2a3, 0x7271babb, 0x8d8e4545, 0xbabb7272, 0x45448d8e, 0x12121212, + 0xedededee, 0x21212121, 0xdedededf, 0x3f3f3f3f, 0xc0c0c0c1, 0x6c6c6c6c, 0x93939394, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, 0x03030303, + 0x03030303, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, 0xfcfcfcfd, + 0xfcfcfcfd, 0xfcfcfcfd, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000, + 0x03030000, 0x03030000, 0x03030000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, + 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0x00000303, 0x00000303, 0x00000303, 0x00000303, + 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, + 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, + 0xf7f7fbfc, 0x04040808, 0xfbfbf7f8, 0x08080808, 0xf7f7f7f8, 0x0807f7f8, 0xf7f80808, 0x0c0bfbfc, + 0xf3f40404, 0xfbfc0c0c, 0x0403f3f4, 0x10100808, 0xefeff7f8, 0x08081010, 0xf7f7eff0, 0x10101010, + 0xefefeff0, 0x14140000, 0xebec0000, 0x00001414, 0xffffebec, 0x100ff3f4, 0xeff00c0c, 0xf3f41010, + 0x0c0beff0, 0x1817fbfc, 0xe7e80404, 0xfbfc1818, 0x0403e7e8, 0x20201010, 0xdfdfeff0, 0x10102020, + 0xefefdfe0, 0x20200808, 0xdfdff7f8, 0x08082020, 0xf7f7dfe0, 0x20202020, 0xdfdfdfe0, 0x24240000, + 0xdbdc0000, 0x00002424, 0xffffdbdc, 0x1817e7e8, 0xe7e81818, 0x201feff0, 0xdfe01010, 0xeff02020, + 0x100fdfe0, 0x34341414, 0xcbcbebec, 0x14143434, 0xebebcbcc, 0x38382424, 0xc7c7dbdc, 0x24243838, + 0xdbdbc7c8, 0x2c2bf3f4, 0xd3d40c0c, 0xf3f42c2c, 0x0c0bd3d4, 0x38380808, 0xc7c7f7f8, 0x08083838, + 0xf7f7c7c8, 0x3c3c3c3c, 0xc3c3c3c4, 0x403ffbfc, 0xbfc00404, 0xfbfc4040, 0x0403bfc0, 0x2c2bdbdc, + 0xd3d42424, 0xdbdc2c2c, 0x2423d3d4, 0x3c3be3e4, 0xc3c41c1c, 0xe3e43c3c, 0x1c1bc3c4, 0x5c5c2c2c, + 0xa3a3d3d4, 0x2c2c5c5c, 0xd3d3a3a4, 0x5c5c1818, 0xa3a3e7e8, 0x18185c5c, 0xe7e7a3a4, 0x60604848, + 0x9f9fb7b8, 0x48486060, 0xb7b79fa0, 0x5453ebec, 0xabac1414, 0xebec5454, 0x1413abac, 0x64640808, + 0x9b9bf7f8, 0x08086464, 0xf7f79b9c, 0x6c6c6c6c, 0x93939394, 0x4443bbbc, 0xbbbc4444, 0x5453c7c8, + 0xabac3838, 0xc7c85454, 0x3837abac, 0x7877f3f4, 0x87880c0c, 0xf3f47878, 0x0c0b8788, 0x6c6bcfd0, + 0x93943030, 0xcfd06c6c, 0x302f9394, 0x7c7b9798, 0x83846868, 0x97987c7c, 0x68678384, 0x18181818, + 0xe7e7e7e8, 0x2c2c2c2c, 0xd3d3d3d4, 0x54545454, 0xabababac, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04040404, + 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, + 0x04040404, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, + 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, + 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, + 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0x00000404, + 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, + 0x00000404, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, + 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0x08080404, 0x08080404, 0x08080404, 0x08080404, 0x08080404, + 0x08080404, 0x08080404, 0x08080404, 0x08080404, 0x08080404, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, + 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0xf7f7fbfc, 0x04040808, + 0x04040808, 0x04040808, 0x04040808, 0x04040808, 0x04040808, 0x04040808, 0x04040808, 0x04040808, + 0x04040808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, + 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x05050f0f, 0xfafaf0f1, 0x0a09f5f6, 0xf5f60a0a, 0x0f0efafb, + 0xf0f10505, 0xfafb0f0f, 0x0504f0f1, 0x14140a0a, 0xebebf5f6, 0x0a0a1414, 0xf5f5ebec, 0x14141414, + 0xebebebec, 0x19190000, 0xe6e70000, 0x00001919, 0xffffe6e7, 0x1413f0f1, 0xebec0f0f, 0xf0f11414, + 0x0f0eebec, 0x28281919, 0xd7d7e6e7, 0x19192828, 0xe6e6d7d8, 0x1e1df5f6, 0xe1e20a0a, 0xf5f61e1e, + 0x0a09e1e2, 0x28280a0a, 0xd7d7f5f6, 0x0a0a2828, 0xf5f5d7d8, 0x28282828, 0xd7d7d7d8, 0x2d2d0000, + 0xd2d30000, 0x00002d2d, 0xffffd2d3, 0x1e1de1e2, 0xe1e21e1e, 0x2827ebec, 0xd7d81414, 0xebec2828, + 0x1413d7d8, 0x41411919, 0xbebee6e7, 0x19194141, 0xe6e6bebf, 0x46462d2d, 0xb9b9d2d3, 0x2d2d4646, + 0xd2d2b9ba, 0x3736f0f1, 0xc8c90f0f, 0xf0f13737, 0x0f0ec8c9, 0x46460a0a, 0xb9b9f5f6, 0x0a0a4646, + 0xf5f5b9ba, 0x4b4b4b4b, 0xb4b4b4b5, 0x5554fafb, 0xaaab0505, 0xfafb5555, 0x0504aaab, 0x3736d2d3, + 0xc8c92d2d, 0xd2d33737, 0x2d2cc8c9, 0x4b4adcdd, 0xb4b52323, 0xdcdd4b4b, 0x2322b4b5, 0x73733737, + 0x8c8cc8c9, 0x37377373, 0xc8c88c8d, 0x73731e1e, 0x8c8ce1e2, 0x1e1e7373, 0xe1e18c8d, 0x78785a5a, + 0x8787a5a6, 0x5a5a7878, 0xa5a58788, 0x6968e1e2, 0x96971e1e, 0xe1e26969, 0x1e1d9697, 0x5554aaab, + 0xaaab5555, 0x6968b9ba, 0x96974646, 0xb9ba6969, 0x46459697, 0x1e1e1e1e, 0xe1e1e1e2, 0x3c3c3c3c, + 0xc3c3c3c4, 0x69696969, 0x96969697, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x05050505, 0x05050505, + 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x05050505, + 0x05050505, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, + 0xfafafafb, 0xfafafafb, 0xfafafafb, 0xfafafafb, 0x05050000, 0x05050000, 0x05050000, 0x05050000, + 0x05050000, 0x05050000, 0x05050000, 0x05050000, 0x05050000, 0x05050000, 0x05050000, 0xfafb0000, + 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000, 0xfafb0000, + 0xfafb0000, 0xfafb0000, 0x00000505, 0x00000505, 0x00000505, 0x00000505, 0x00000505, 0x00000505, + 0x00000505, 0x00000505, 0x00000505, 0x00000505, 0x00000505, 0xfffffafb, 0xfffffafb, 0xfffffafb, + 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb, 0xfffffafb, + 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, + 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, + 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0x0f0f0505, 0x0f0f0505, + 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, 0x0f0f0505, + 0x0f0f0505, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, + 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0xf0f0fafb, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, + 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0xf9f9f3f4, 0x0c0bf3f4, 0xf3f40c0c, 0x1211f9fa, + 0xedee0606, 0xf9fa1212, 0x0605edee, 0x18180c0c, 0xe7e7f3f4, 0x0c0c1818, 0xf3f3e7e8, 0x18181818, + 0xe7e7e7e8, 0x1e1e0000, 0xe1e20000, 0x00001e1e, 0xffffe1e2, 0x1817edee, 0xe7e81212, 0xedee1818, + 0x1211e7e8, 0x30301e1e, 0xcfcfe1e2, 0x1e1e3030, 0xe1e1cfd0, 0x2423f9fa, 0xdbdc0606, 0xf9fa2424, + 0x0605dbdc, 0x30300c0c, 0xcfcff3f4, 0x0c0c3030, 0xf3f3cfd0, 0x30303030, 0xcfcfcfd0, 0x36360000, + 0xc9ca0000, 0x00003636, 0xffffc9ca, 0x2423dbdc, 0xdbdc2424, 0x302fe7e8, 0xcfd01818, 0xe7e83030, + 0x1817cfd0, 0x4e4e1e1e, 0xb1b1e1e2, 0x1e1e4e4e, 0xe1e1b1b2, 0x54543636, 0xababc9ca, 0x36365454, + 0xc9c9abac, 0x4241edee, 0xbdbe1212, 0xedee4242, 0x1211bdbe, 0x54540c0c, 0xababf3f4, 0x0c0c5454, + 0xf3f3abac, 0x5a5a5a5a, 0xa5a5a5a6, 0x605ff9fa, 0x9fa00606, 0xf9fa6060, 0x06059fa0, 0x4241c9ca, + 0xbdbe3636, 0xc9ca4242, 0x3635bdbe, 0x5a59d5d6, 0xa5a62a2a, 0xd5d65a5a, 0x2a29a5a6, 0x7e7de1e2, + 0x81821e1e, 0xe1e27e7e, 0x1e1d8182, 0x6665999a, 0x999a6666, 0x7e7dabac, 0x81825454, 0xabac7e7e, + 0x54538182, 0x24242424, 0xdbdbdbdc, 0x42424242, 0xbdbdbdbe, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, + 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, + 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, + 0xf9fa0000, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, + 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, + 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, + 0xfffff9fa, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, + 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0x0c0c0606, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, + 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, 0xf3f3f9fa, + 0xf3f3f9fa, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, + 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x06060c0c, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, + 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0xf8f8eaeb, 0x0e0df1f2, 0xf1f20e0e, 0x1514f8f9, + 0xeaeb0707, 0xf8f91515, 0x0706eaeb, 0x1c1c0e0e, 0xe3e3f1f2, 0x0e0e1c1c, 0xf1f1e3e4, 0x1c1c1c1c, + 0xe3e3e3e4, 0x23230000, 0xdcdd0000, 0x00002323, 0xffffdcdd, 0x1c1beaeb, 0xe3e41515, 0xeaeb1c1c, + 0x1514e3e4, 0x38382323, 0xc7c7dcdd, 0x23233838, 0xdcdcc7c8, 0x2a29f1f2, 0xd5d60e0e, 0xf1f22a2a, + 0x0e0dd5d6, 0x38380e0e, 0xc7c7f1f2, 0x0e0e3838, 0xf1f1c7c8, 0x38383838, 0xc7c7c7c8, 0x3f3f0000, + 0xc0c10000, 0x00003f3f, 0xffffc0c1, 0x2a29d5d6, 0xd5d62a2a, 0x3837e3e4, 0xc7c81c1c, 0xe3e43838, + 0x1c1bc7c8, 0x5b5b2323, 0xa4a4dcdd, 0x23235b5b, 0xdcdca4a5, 0x62623f3f, 0x9d9dc0c1, 0x3f3f6262, + 0xc0c09d9e, 0x4d4ceaeb, 0xb2b31515, 0xeaeb4d4d, 0x1514b2b3, 0x62620e0e, 0x9d9df1f2, 0x0e0e6262, + 0xf1f19d9e, 0x69696969, 0x96969697, 0x7776f8f9, 0x88890707, 0xf8f97777, 0x07068889, 0x4d4cc0c1, + 0xb2b33f3f, 0xc0c14d4d, 0x3f3eb2b3, 0x6968cecf, 0x96973131, 0xcecf6969, 0x31309697, 0x77768889, + 0x88897777, 0x2a2a2a2a, 0xd5d5d5d6, 0x4d4d4d4d, 0xb2b2b2b3, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, + 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, + 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, 0xf8f8f8f9, + 0xf8f8f8f9, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, + 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0xf8f90000, 0xf8f90000, 0xf8f90000, + 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, + 0xf8f90000, 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707, + 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0x00000707, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, + 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, 0xfffff8f9, + 0xfffff8f9, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, + 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0x0e0e0e0e, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, + 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, 0xf1f1f1f2, + 0xf1f1f1f2, 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0x15150707, + 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0x15150707, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, + 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, 0xeaeaf8f9, + 0xeaeaf8f9, 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x07071515, + 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x07071515, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, + 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0xf7f7eff0, 0x100feff0, 0xeff01010, 0x1817f7f8, + 0xe7e80808, 0xf7f81818, 0x0807e7e8, 0x20201010, 0xdfdfeff0, 0x10102020, 0xefefdfe0, 0x20202020, + 0xdfdfdfe0, 0x28280000, 0xd7d80000, 0x00002828, 0xffffd7d8, 0x201fe7e8, 0xdfe01818, 0xe7e82020, + 0x1817dfe0, 0x40402828, 0xbfbfd7d8, 0x28284040, 0xd7d7bfc0, 0x302feff0, 0xcfd01010, 0xeff03030, + 0x100fcfd0, 0x40401010, 0xbfbfeff0, 0x10104040, 0xefefbfc0, 0x40404040, 0xbfbfbfc0, 0x48480000, + 0xb7b80000, 0x00004848, 0xffffb7b8, 0x302fcfd0, 0xcfd03030, 0x403fdfe0, 0xbfc02020, 0xdfe04040, + 0x201fbfc0, 0x68682828, 0x9797d7d8, 0x28286868, 0xd7d79798, 0x70704848, 0x8f8fb7b8, 0x48487070, + 0xb7b78f90, 0x5857e7e8, 0xa7a81818, 0xe7e85858, 0x1817a7a8, 0x70701010, 0x8f8feff0, 0x10107070, + 0xefef8f90, 0x78787878, 0x87878788, 0x5857b7b8, 0xa7a84848, 0xb7b85858, 0x4847a7a8, 0x7877c7c8, + 0x87883838, 0xc7c87878, 0x38378788, 0x30303030, 0xcfcfcfd0, 0x58585858, 0xa7a7a7a8, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, + 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0xf7f7f7f8, + 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, + 0xf7f7f7f8, 0xf7f7f7f8, 0xf7f7f7f8, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, + 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0x08080000, 0xf7f80000, + 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000, 0xf7f80000, + 0xf7f80000, 0xf7f80000, 0xf7f80000, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, + 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0x00000808, 0xfffff7f8, + 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, + 0xfffff7f8, 0xfffff7f8, 0xfffff7f8, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, + 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0x10101010, 0xefefeff0, + 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, 0xefefeff0, + 0xefefeff0, 0xefefeff0, 0xefefeff0, 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0x10100808, + 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0x10100808, 0xefeff7f8, + 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, + 0xefeff7f8, 0xefeff7f8, 0xefeff7f8, 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x08081010, + 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x08081010, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, + 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x1211edee, 0xedee1212, 0x1b1af6f7, + 0xe4e50909, 0xf6f71b1b, 0x0908e4e5, 0x24241212, 0xdbdbedee, 0x12122424, 0xededdbdc, 0x24242424, + 0xdbdbdbdc, 0x2d2d0000, 0xd2d30000, 0x00002d2d, 0xffffd2d3, 0x2423e4e5, 0xdbdc1b1b, 0xe4e52424, + 0x1b1adbdc, 0x48482d2d, 0xb7b7d2d3, 0x2d2d4848, 0xd2d2b7b8, 0x3635edee, 0xc9ca1212, 0xedee3636, + 0x1211c9ca, 0x48481212, 0xb7b7edee, 0x12124848, 0xededb7b8, 0x48484848, 0xb7b7b7b8, 0x51510000, + 0xaeaf0000, 0x00005151, 0xffffaeaf, 0x3635c9ca, 0xc9ca3636, 0x4847dbdc, 0xb7b82424, 0xdbdc4848, + 0x2423b7b8, 0x75752d2d, 0x8a8ad2d3, 0x2d2d7575, 0xd2d28a8b, 0x7e7e5151, 0x8181aeaf, 0x51517e7e, + 0xaeae8182, 0x6362e4e5, 0x9c9d1b1b, 0xe4e56363, 0x1b1a9c9d, 0x6362aeaf, 0x9c9d5151, 0xaeaf6363, + 0x51509c9d, 0x36363636, 0xc9c9c9ca, 0x6c6c6c6c, 0x93939394, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, + 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0x09090909, 0xf6f6f6f7, + 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, + 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0xf6f6f6f7, 0x09090000, 0x09090000, 0x09090000, 0x09090000, + 0x09090000, 0x09090000, 0x09090000, 0x09090000, 0x09090000, 0x09090000, 0x09090000, 0x09090000, + 0x09090000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, + 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0xf6f70000, 0x00000909, 0x00000909, + 0x00000909, 0x00000909, 0x00000909, 0x00000909, 0x00000909, 0x00000909, 0x00000909, 0x00000909, + 0x00000909, 0x00000909, 0x00000909, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, + 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, 0xfffff6f7, + 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, + 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0x12121212, 0xedededee, 0xedededee, 0xedededee, + 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, 0xedededee, + 0xedededee, 0xedededee, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, + 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0x1b1b0909, 0xe4e4f6f7, + 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, + 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0xe4e4f6f7, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, + 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, 0x09091b1b, + 0x09091b1b, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, + 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0xf6f6e4e5, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, + 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0504fafb, 0xfafb0505, 0xfafb0505, + 0x0504fafb, 0x0b0b0606, 0xf4f4f9fa, 0x06060b0b, 0xf9f9f4f5, 0x08080000, 0xf7f80000, 0x00000808, + 0xfffff7f8, 0x0b0b0b0b, 0xf4f4f4f5, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x11110c0c, + 0xeeeef3f4, 0x0c0c1111, 0xf3f3eeef, 0x11111111, 0xeeeeeeef, 0x12120606, 0xededf9fa, 0x06061212, + 0xf9f9edee, 0x0b0af7f8, 0xf4f50808, 0xf7f80b0b, 0x0807f4f5, 0x0f0f0000, 0xf0f10000, 0x00000f0f, + 0xfffff0f1, 0x14140000, 0xebec0000, 0x00001414, 0xffffebec, 0x19191212, 0xe6e6edee, 0x12121919, + 0xedede6e7, 0x19190b0b, 0xe6e6f4f5, 0x0b0b1919, 0xf4f4e6e7, 0x19191919, 0xe6e6e6e7, 0x0e0df1f2, + 0xf1f20e0e, 0xf1f20e0e, 0x0e0df1f2, 0x1a1a0000, 0xe5e60000, 0x00001a1a, 0xffffe5e6, 0x1211f4f5, + 0xedee0b0b, 0xf4f51212, 0x0b0aedee, 0x1615f8f9, 0xe9ea0707, 0xf8f91616, 0x0706e9ea, 0x22221a1a, + 0xdddde5e6, 0x1a1a2222, 0xe5e5ddde, 0x22221212, 0xddddedee, 0x12122222, 0xededddde, 0x22222222, + 0xddddddde, 0x23230b0b, 0xdcdcf4f5, 0x0b0b2323, 0xf4f4dcdd, 0x1d1d0000, 0xe2e30000, 0x00001d1d, + 0xffffe2e3, 0x1615eced, 0xe9ea1313, 0xeced1616, 0x1312e9ea, 0x1a19f0f1, 0xe5e60f0f, 0xf0f11a1a, + 0x0f0ee5e6, 0x25250000, 0xdadb0000, 0x00002525, 0xffffdadb, 0x2c2c1b1b, 0xd3d3e4e5, 0x1b1b2c2c, + 0xe4e4d3d4, 0x2c2c2424, 0xd3d3dbdc, 0x24242c2c, 0xdbdbd3d4, 0x2c2c1212, 0xd3d3edee, 0x12122c2c, + 0xededd3d4, 0x2120f5f6, 0xdedf0a0a, 0xf5f62121, 0x0a09dedf, 0x2d2d2d2d, 0xd2d2d2d3, 0x00000000, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, + 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, + 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, + 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, + 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, + 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, + 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, + 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, + 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, + 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x03030000, 0xfcfd0000, + 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, 0xf8f90000, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x07070000, + 0xf8f90000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0403fbfc, 0xfbfc0404, 0xf9fa0a0a, + 0x0605f5f6, 0xf3f40000, 0x0c0c0000, 0xf3f3f9fa, 0xf3f40606, 0x0c0bf9fa, 0x0c0c0606, 0xfffff1f2, + 0x00000e0e, 0x0c0c0c0c, 0xf3f3f3f4, 0xedee0000, 0x12120000, 0xf3f40e0e, 0x0c0bf1f2, 0xf9f9edee, + 0xf9fa1212, 0x0605edee, 0x06061212, 0xededf5f6, 0xedee0a0a, 0x1211f5f6, 0x12120a0a, 0xffffe9ea, + 0x00001616, 0xe7e80000, 0x18180000, 0xf3f3e9ea, 0xf3f41616, 0x0c0be9ea, 0x0c0c1616, 0xe7e7f7f8, + 0xe7e80808, 0x1817f7f8, 0x18180808, 0xf9f9e5e6, 0xf9fa1a1a, 0x0605e5e6, 0x06061a1a, 0xffffe3e4, + 0x00001c1c, 0x14141414, 0xebebebec, 0xe5e5f1f2, 0x1a1a0e0e, 0xf3f3e1e2, 0x0c0c1e1e, 0xdfdff5f6, + 0x20200a0a, 0xdfdfedee, 0x20201212, 0xe5e5e5e6, 0x1a1a1a1a, 0xebebddde, 0x14142222, 0xf3f3d9da, + 0x0c0c2626, 0xdfdfdfe0, 0x20202020, 0x20202020, 0xd7d7e9ea, 0xddddddde, 0x22222222, 0x00000000, + 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, + 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, + 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, + 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, + 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, + 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, + 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, + 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, + 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, + 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, + 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, + 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, + 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, + 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, + 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, + 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, + 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x0605f9fa, 0xf9fa0606, 0xf7f80e0e, + 0x0807f1f2, 0xffffedee, 0x00001212, 0xeff00a0a, 0x100ff5f6, 0xe7e80000, 0x18180000, 0xf7f7e7e8, + 0xf7f81818, 0x0807e7e8, 0x08081818, 0x12121212, 0xedededee, 0xeff01414, 0x100febec, 0xe5e5f1f2, + 0xe5e60e0e, 0x1a19f1f2, 0x1a1a0e0e, 0xffffe1e2, 0x00001e1e, 0xddde0000, 0x22220000, 0xf7f7ddde, + 0xf7f82222, 0x0807ddde, 0x08082222, 0xedede1e2, 0xedee1e1e, 0x1211e1e2, 0x12121e1e, 0xddddf5f6, + 0xddde0a0a, 0x2221f5f6, 0x22220a0a, 0xddddebec, 0x22221414, 0xffffd7d8, 0x00002828, 0x1e1e1e1e, + 0xe1e1e1e2, 0xededd7d8, 0x12122828, 0xd3d40000, 0x2c2c0000, 0xd3d3eff0, 0x2c2c1010, 0xdbdbdbdc, + 0xdbdbdbdc, 0x24242424, 0xd3d3e5e6, 0x2c2c1a1a, 0xe5e5d1d2, 0x1a1a2e2e, 0xededcbcc, 0x12123434, + 0xc9c9ebec, 0xd3d3d3d4, 0x2c2c2c2c, 0xc9c9dfe0, 0xd1d1d1d2, 0xd1d1d1d2, 0x2e2e2e2e, 0x00000000, + 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, + 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, + 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, + 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, + 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, + 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, + 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, + 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, + 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, + 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, + 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, + 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, + 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, + 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, + 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, + 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, + 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, + 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, + 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, + 0xf5f60000, 0x00000a0a, 0xfffff5f6, 0x00000000, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, + 0x04040404, 0xfbfbfbfc, 0x0a0a0a0a, 0xf5f5f5f6, 0x0a0a0000, 0xf5f60000, 0x00000a0a, 0xfffff5f6, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, + 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x0807f7f8, 0xf7f80808, 0xeff00808, + 0x100ff7f8, 0xe7e80000, 0x18180000, 0xf7f7e7e8, 0xf7f81818, 0x0807e7e8, 0x08081818, 0xeff01414, + 0x100febec, 0xffffe3e4, 0x00001c1c, 0xe7e7eff0, 0xe7e81010, 0x1817eff0, 0x18181010, 0xdfe00000, + 0x20200000, 0xefefe3e4, 0xeff01c1c, 0x100fe3e4, 0x10101c1c, 0xdfdff7f8, 0xdfe00808, 0xf7f7dfe0, + 0xf7f82020, 0x0807dfe0, 0x08082020, 0x201ff7f8, 0x20200808, 0x18181818, 0xe7e7e7e8, 0xe7e81818, + 0x1817e7e8, 0xdfdfebec, 0x20201414, 0xffffd7d8, 0x00002828, 0xefefd7d8, 0x10102828, 0xd3d40000, + 0xd3d40000, 0xffffd3d4, 0x00002c2c, 0x2c2c0000, 0x2c2c0000, 0xdfdfdfe0, 0x20202020, 0xd3d3eff0, + 0x2c2c1010, 0xd3d3e7e8, 0xe7e7d3d4, 0x18182c2c, 0x2c2c1818, 0xefefcfd0, 0x10103030, 0xdbdbdbdc, + 0xdbdbdbdc, 0x24242424, 0x24242424, 0xcbcbebec, 0x28282828, 0xd7d7d7d8, 0xcbcbdfe0, 0x00000000, + 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, + 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, + 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, + 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, + 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, + 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, + 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, + 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, + 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, + 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, + 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, + 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, + 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, + 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, + 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, + 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, + 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, + 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, + 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, + 0xf3f40000, 0x00000c0c, 0xfffff3f4, 0x00000000, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, + 0x04040404, 0xfbfbfbfc, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0000, 0xf3f40000, 0x00000c0c, 0xfffff3f4, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, + 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, + 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, + 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, + 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, + 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, + 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, + 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, + 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, + 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, + 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, + 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, + 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, + 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, + 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, + 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, + 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, + 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, + 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, + 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, + 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, + 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, + 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, + 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, + 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, + 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, + 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, + 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, + 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, + 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, + 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, + 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, + 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, + 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, + 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, + 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, + 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, + 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, + 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, + 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, + 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, + 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, + 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, + 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, + 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, + 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, + 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, + 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, + 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, + 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, + 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, + 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, + 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, + 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x06060606, 0xf9f9f9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x14141414, 0xebebebec, 0x20202020, 0xdfdfdfe0, 0x2e2e2e2e, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + + +static const uint32_t correctionhighorder[] = { + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, + 0xfeff0303, 0x0100fcfd, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, + 0x0100fcfd, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x00000000, 0x02020202, 0xfdfdfdfe, + 0x0302feff, 0xfcfd0101, 0xfeff0303, 0x0100fcfd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, + 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, + 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, + 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, + 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, + 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x0403feff, + 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303, 0xfcfcfcfd, + 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000, 0x03030303, + 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, 0x00000000, + 0x03030303, 0xfcfcfcfd, 0x0403feff, 0xfbfc0101, 0xfeff0404, 0x0100fbfc, 0x07070707, 0xf8f8f8f9, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x04040404, 0xfbfbfbfc, + 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, + 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, + 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, + 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, + 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, + 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, + 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, + 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, + 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, + 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, 0x04040404, 0xfbfbfbfc, + 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, 0x03030a0a, 0x00000000, + 0x04040404, 0xfbfbfbfc, 0x0504feff, 0xfafb0101, 0xfeff0505, 0x0100fafb, 0x0a0a0303, 0xf5f5fcfd, + 0x03030a0a, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, + 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, + 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, + 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, + 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, + 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, + 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, + 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, + 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, + 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, + 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, + 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, + 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x05050505, + 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, + 0xf2f2fcfd, 0x00000000, 0x05050505, 0xfafafafb, 0x0706fdfe, 0xf8f90202, 0xfdfe0707, 0x0201f8f9, + 0x0b0b0b0b, 0xf4f4f4f5, 0x0d0d0303, 0xf2f2fcfd, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, + 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, + 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, + 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, + 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, + 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, + 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, + 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, + 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, + 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, + 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, + 0x04040f0f, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x0807fdfe, 0xf7f80202, 0xfdfe0808, 0x0201f7f8, + 0x0d0d0d0d, 0xf2f2f2f3, 0x0f0f0404, 0xf0f0fbfc, 0x04040f0f, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, + 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, + 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, + 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, + 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, + 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, + 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, + 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, + 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, + 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, + 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, + 0x05051212, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x0a09fcfd, 0xf5f60303, 0xfcfd0a0a, 0x0302f5f6, + 0x10101010, 0xefefeff0, 0x12120505, 0xededfafb, 0x05051212, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, + 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, + 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, + 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, + 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, + 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, + 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, + 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, + 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, + 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, + 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, + 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x0b0afcfd, 0xf4f50303, + 0xfcfd0b0b, 0x0302f4f5, 0x12121212, 0xedededee, 0x14140505, 0xebebfafb, 0x05051414, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x09090909, 0xf6f6f6f7, + 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, + 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, + 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, + 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, + 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, + 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, + 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, + 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, + 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, + 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, + 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, + 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, + 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, + 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, + 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, + 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, + 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, + 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, + 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, + 0xf9f9e8e9, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x0c0bfcfd, 0xf3f40303, 0xfcfd0c0c, 0x0302f3f4, + 0x14141414, 0xebebebec, 0x17170606, 0xe8e8f9fa, 0x06061717, 0xf9f9e8e9, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, + 0x00000202, 0xfffffdfe, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, + 0xfffffdfe, 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, + 0x00000000, 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x00000000, + 0x02020202, 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x00000000, 0x02020202, + 0xfdfdfdfe, 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x00000000, 0x02020202, 0xfdfdfdfe, + 0x02020000, 0xfdfe0000, 0x00000202, 0xfffffdfe, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, + 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, + 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, + 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, + 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, + 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd, 0x03030000, + 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303, 0xfcfcfcfd, + 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000, 0x03030303, + 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, 0x00000000, + 0x03030303, 0xfcfcfcfd, 0x03030000, 0xfcfd0000, 0x00000303, 0xfffffcfd, 0x06060606, 0xf9f9f9fa, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x04040404, 0xfbfbfbfc, + 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, + 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, + 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, + 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, + 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, + 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, + 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, + 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, + 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, + 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, 0x04040404, 0xfbfbfbfc, + 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, 0x04040808, 0x00000000, + 0x04040404, 0xfbfbfbfc, 0x04040000, 0xfbfc0000, 0x00000404, 0xfffffbfc, 0x08080404, 0xf7f7fbfc, + 0x04040808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, + 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, + 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, + 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, + 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, + 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, + 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, + 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, + 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, + 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, + 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, + 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, + 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x05050505, + 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, + 0xf0f0fafb, 0x00000000, 0x05050505, 0xfafafafb, 0x05050000, 0xfafb0000, 0x00000505, 0xfffffafb, + 0x0a0a0a0a, 0xf5f5f5f6, 0x0f0f0505, 0xf0f0fafb, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, + 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, + 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, + 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, + 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, + 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, + 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, + 0x06060c0c, 0x00000000, 0x06060606, 0xf9f9f9fa, 0x06060000, 0xf9fa0000, 0x00000606, 0xfffff9fa, + 0x0c0c0c0c, 0xf3f3f3f4, 0x0c0c0606, 0xf3f3f9fa, 0x06060c0c, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, + 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, + 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, + 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, + 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, + 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, + 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, + 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, + 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, + 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, + 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, + 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, + 0x07071515, 0x00000000, 0x07070707, 0xf8f8f8f9, 0x07070000, 0xf8f90000, 0x00000707, 0xfffff8f9, + 0x0e0e0e0e, 0xf1f1f1f2, 0x15150707, 0xeaeaf8f9, 0x07071515, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, + 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, + 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, + 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, + 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, + 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, + 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, + 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, + 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, + 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, + 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, + 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, + 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, 0x08080808, 0xf7f7f7f8, 0x08080000, 0xf7f80000, + 0x00000808, 0xfffff7f8, 0x10101010, 0xefefeff0, 0x10100808, 0xefeff7f8, 0x08081010, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, 0x09090909, 0xf6f6f6f7, + 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, + 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, + 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, + 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, + 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, + 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, + 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, + 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, + 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, + 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, + 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, + 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, + 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, + 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, + 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, + 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, + 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, + 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, + 0xf6f70000, 0x00000909, 0xfffff6f7, 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, + 0xf6f6e4e5, 0x00000000, 0x09090909, 0xf6f6f6f7, 0x09090000, 0xf6f70000, 0x00000909, 0xfffff6f7, + 0x12121212, 0xedededee, 0x1b1b0909, 0xe4e4f6f7, 0x09091b1b, 0xf6f6e4e5, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, + 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, + 0xfdfdfdfe, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0x03030000, + 0x03030000, 0x03030000, 0x03030000, 0x03030000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, + 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0xfcfd0000, 0x00000303, + 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303, 0x00000303, + 0x00000303, 0x00000303, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, + 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0xfffffcfd, 0x06060606, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, + 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0x07070000, 0xf8f90000, 0xf8f90000, + 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, 0xf8f90000, + 0xf8f90000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, + 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, + 0x02020000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, + 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0x00000202, 0x00000202, + 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, + 0x00000202, 0x00000202, 0x00000202, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, + 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, + 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, + 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, + 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0x06060000, 0x06060000, 0x06060000, 0x06060000, + 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, 0x06060000, + 0x06060000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, + 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0xf9fa0000, 0x00000606, 0x00000606, + 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, 0x00000606, + 0x00000606, 0x00000606, 0x00000606, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, + 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, 0xfffff9fa, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, + 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, + 0x02020000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, + 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0xfdfe0000, 0x00000202, 0x00000202, + 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, 0x00000202, + 0x00000202, 0x00000202, 0x00000202, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, + 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, 0xfffffdfe, + 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, + 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, + 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, + 0xfbfbfbfc, 0xfbfbfbfc, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, + 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0x0a0a0a0a, 0xf5f5f5f6, + 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, + 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0xf5f5f5f6, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, + 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, 0x0a0a0000, + 0x0a0a0000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, + 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0xf5f60000, 0x00000a0a, 0x00000a0a, + 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a, 0x00000a0a, + 0x00000a0a, 0x00000a0a, 0x00000a0a, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, + 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, 0xfffff5f6, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, + 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, 0x04040000, + 0x04040000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, + 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0xfbfc0000, 0x00000404, 0x00000404, + 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, 0x00000404, + 0x00000404, 0x00000404, 0x00000404, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, + 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, 0xfffffbfc, + 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, + 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0x04040404, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, + 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, 0xfbfbfbfc, + 0xfbfbfbfc, 0xfbfbfbfc, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, + 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, 0x0c0c0000, + 0x0c0c0000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, + 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0xf3f40000, 0x00000c0c, 0x00000c0c, + 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c, 0x00000c0c, + 0x00000c0c, 0x00000c0c, 0x00000c0c, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, + 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, 0xfffff3f4, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, + 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, + 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec, + 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, + 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0x20202020, 0x20202020, 0x20202020, 0x20202020, + 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, + 0x20202020, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, + 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0x2e2e2e2e, 0x2e2e2e2e, + 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, + 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, + 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, + 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, + 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec, + 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, + 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0x20202020, 0x20202020, 0x20202020, 0x20202020, + 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, + 0x20202020, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, + 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0x2e2e2e2e, 0x2e2e2e2e, + 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, + 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, + 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, + 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, + 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec, + 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, + 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0x20202020, 0x20202020, 0x20202020, 0x20202020, + 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, + 0x20202020, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, + 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0x2e2e2e2e, 0x2e2e2e2e, + 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, + 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, + 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, + 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, 0x02020202, + 0x02020202, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, + 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0xfdfdfdfe, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, 0xf9f9f9fa, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, + 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0x0c0c0c0c, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, 0xf3f3f3f4, + 0xf3f3f3f4, 0xf3f3f3f4, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, + 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0x14141414, 0xebebebec, + 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, + 0xebebebec, 0xebebebec, 0xebebebec, 0xebebebec, 0x20202020, 0x20202020, 0x20202020, 0x20202020, + 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, 0x20202020, + 0x20202020, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, + 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0xdfdfdfe0, 0x2e2e2e2e, 0x2e2e2e2e, + 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, + 0x2e2e2e2e, 0x2e2e2e2e, 0x2e2e2e2e, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, + 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, 0xd1d1d1d2, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; diff --git a/mpeg4/src/libavcodec/internal.h b/mpeg4/src/libavcodec/internal.h new file mode 100644 index 00000000..189090ea --- /dev/null +++ b/mpeg4/src/libavcodec/internal.h @@ -0,0 +1,12 @@ +#ifndef INTERNAL_H +#define INTERNAL_H + +/** + * @file internal.h + * common functions for internal libavcodec use + */ + + +int av_tempfile(char *prefix, char **filename); + +#endif /* INTERNAL_H */ diff --git a/mpeg4/src/libavcodec/interplayvideo.c b/mpeg4/src/libavcodec/interplayvideo.c new file mode 100644 index 00000000..73165e79 --- /dev/null +++ b/mpeg4/src/libavcodec/interplayvideo.c @@ -0,0 +1,962 @@ +/* + * Interplay MVE Video Decoder + * Copyright (C) 2003 the ffmpeg project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file interplayvideo.c + * Interplay MVE Video Decoder by Mike Melanson (melanson@pcisys.net) + * For more information about the Interplay MVE format, visit: + * http://www.pcisys.net/~melanson/codecs/interplay-mve.txt + * This code is written in such a way that the identifiers match up + * with the encoding descriptions in the document. + * + * This decoder presently only supports a PAL8 output colorspace. + * + * An Interplay video frame consists of 2 parts: The decoding map and + * the video data. A demuxer must load these 2 parts together in a single + * buffer before sending it through the stream to this decoder. + */ + +#include +#include +#include +#include + +#include "common.h" +#include "avcodec.h" +#include "dsputil.h" + +#define PALETTE_COUNT 256 + +/* debugging support */ +#define DEBUG_INTERPLAY 0 +#if DEBUG_INTERPLAY +#define debug_interplay(x,...) av_log(NULL, AV_LOG_DEBUG, x, __VA_ARGS__) +#else +static inline void debug_interplay(const char *format, ...) { } +#endif + +typedef struct IpvideoContext { + + AVCodecContext *avctx; + DSPContext dsp; + AVFrame second_last_frame; + AVFrame last_frame; + AVFrame current_frame; + unsigned char *decoding_map; + int decoding_map_size; + + unsigned char *buf; + int size; + + unsigned char *stream_ptr; + unsigned char *stream_end; + unsigned char *pixel_ptr; + int line_inc; + int stride; + int upper_motion_limit_offset; + +} IpvideoContext; + +#define CHECK_STREAM_PTR(n) \ + if ((s->stream_ptr + n) > s->stream_end) { \ + av_log(s->avctx, AV_LOG_ERROR, "Interplay video warning: stream_ptr out of bounds (%p >= %p)\n", \ + s->stream_ptr + n, s->stream_end); \ + return -1; \ + } + +#define COPY_FROM_CURRENT() \ + motion_offset = current_offset; \ + motion_offset += y * s->stride; \ + motion_offset += x; \ + if (motion_offset < 0) { \ + av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset < 0 (%d)\n", motion_offset); \ + return -1; \ + } else if (motion_offset > s->upper_motion_limit_offset) { \ + av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset above limit (%d >= %d)\n", \ + motion_offset, s->upper_motion_limit_offset); \ + return -1; \ + } \ + s->dsp.put_pixels_tab[0][0](s->pixel_ptr, \ + s->current_frame.data[0] + motion_offset, s->stride, 8); + +#define COPY_FROM_PREVIOUS() \ + motion_offset = current_offset; \ + motion_offset += y * s->stride; \ + motion_offset += x; \ + if (motion_offset < 0) { \ + av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset < 0 (%d)\n", motion_offset); \ + return -1; \ + } else if (motion_offset > s->upper_motion_limit_offset) { \ + av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset above limit (%d >= %d)\n", \ + motion_offset, s->upper_motion_limit_offset); \ + return -1; \ + } \ + s->dsp.put_pixels_tab[0][0](s->pixel_ptr, \ + s->last_frame.data[0] + motion_offset, s->stride, 8); + +#define COPY_FROM_SECOND_LAST() \ + motion_offset = current_offset; \ + motion_offset += y * s->stride; \ + motion_offset += x; \ + if (motion_offset < 0) { \ + av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset < 0 (%d)\n", motion_offset); \ + return -1; \ + } else if (motion_offset > s->upper_motion_limit_offset) { \ + av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset above limit (%d >= %d)\n", \ + motion_offset, s->upper_motion_limit_offset); \ + return -1; \ + } \ + s->dsp.put_pixels_tab[0][0](s->pixel_ptr, \ + s->second_last_frame.data[0] + motion_offset, s->stride, 8); + +static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s) +{ + int x, y; + int motion_offset; + int current_offset = s->pixel_ptr - s->current_frame.data[0]; + + /* copy a block from the previous frame */ + x = y = 0; + COPY_FROM_PREVIOUS(); + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s) +{ + int x, y; + int motion_offset; + int current_offset = s->pixel_ptr - s->current_frame.data[0]; + + /* copy block from 2 frames ago */ + x = y = 0; + COPY_FROM_SECOND_LAST(); + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s) +{ + unsigned char B; + int x, y; + int motion_offset; + int current_offset = s->pixel_ptr - s->current_frame.data[0]; + + /* copy block from 2 frames ago using a motion vector; need 1 more byte */ + CHECK_STREAM_PTR(1); + B = *s->stream_ptr++; + + if (B < 56) { + x = 8 + (B % 7); + y = B / 7; + } else { + x = -14 + ((B - 56) % 29); + y = 8 + ((B - 56) / 29); + } + + debug_interplay (" motion byte = %d, (x, y) = (%d, %d)\n", B, x, y); + COPY_FROM_SECOND_LAST(); + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s) +{ + unsigned char B; + int x, y; + int motion_offset; + int current_offset = s->pixel_ptr - s->current_frame.data[0]; + + /* copy 8x8 block from current frame from an up/left block */ + + /* need 1 more byte for motion */ + CHECK_STREAM_PTR(1); + B = *s->stream_ptr++; + + if (B < 56) { + x = -(8 + (B % 7)); + y = -(B / 7); + } else { + x = -(-14 + ((B - 56) % 29)); + y = -( 8 + ((B - 56) / 29)); + } + + debug_interplay (" motion byte = %d, (x, y) = (%d, %d)\n", B, x, y); + COPY_FROM_CURRENT(); + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s) +{ + int x, y; + unsigned char B, BL, BH; + int motion_offset; + int current_offset = s->pixel_ptr - s->current_frame.data[0]; + + /* copy a block from the previous frame; need 1 more byte */ + CHECK_STREAM_PTR(1); + + B = *s->stream_ptr++; + BL = B & 0x0F; + BH = (B >> 4) & 0x0F; + x = -8 + BL; + y = -8 + BH; + + debug_interplay (" motion byte = %d, (x, y) = (%d, %d)\n", B, x, y); + COPY_FROM_PREVIOUS(); + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s) +{ + signed char x, y; + int motion_offset; + int current_offset = s->pixel_ptr - s->current_frame.data[0]; + + /* copy a block from the previous frame using an expanded range; + * need 2 more bytes */ + CHECK_STREAM_PTR(2); + + x = *s->stream_ptr++; + y = *s->stream_ptr++; + + debug_interplay (" motion bytes = %d, %d\n", x, y); + COPY_FROM_PREVIOUS(); + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s) +{ + /* mystery opcode? skip multiple blocks? */ + av_log(s->avctx, AV_LOG_ERROR, " Interplay video: Help! Mystery opcode 0x6 seen\n"); + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s) +{ + int x, y; + unsigned char P0, P1; + unsigned char B[8]; + unsigned int flags; + int bitmask; + + /* 2-color encoding */ + CHECK_STREAM_PTR(2); + + P0 = *s->stream_ptr++; + P1 = *s->stream_ptr++; + + if (P0 <= P1) { + + /* need 8 more bytes from the stream */ + CHECK_STREAM_PTR(8); + for (y = 0; y < 8; y++) + B[y] = *s->stream_ptr++; + + for (y = 0; y < 8; y++) { + flags = B[y]; + for (x = 0x01; x <= 0x80; x <<= 1) { + if (flags & x) + *s->pixel_ptr++ = P1; + else + *s->pixel_ptr++ = P0; + } + s->pixel_ptr += s->line_inc; + } + + } else { + + /* need 2 more bytes from the stream */ + CHECK_STREAM_PTR(2); + B[0] = *s->stream_ptr++; + B[1] = *s->stream_ptr++; + + flags = (B[1] << 8) | B[0]; + bitmask = 0x0001; + for (y = 0; y < 8; y += 2) { + for (x = 0; x < 8; x += 2, bitmask <<= 1) { + if (flags & bitmask) { + *(s->pixel_ptr + x) = P1; + *(s->pixel_ptr + x + 1) = P1; + *(s->pixel_ptr + s->stride + x) = P1; + *(s->pixel_ptr + s->stride + x + 1) = P1; + } else { + *(s->pixel_ptr + x) = P0; + *(s->pixel_ptr + x + 1) = P0; + *(s->pixel_ptr + s->stride + x) = P0; + *(s->pixel_ptr + s->stride + x + 1) = P0; + } + } + s->pixel_ptr += s->stride * 2; + } + } + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s) +{ + int x, y; + unsigned char P[8]; + unsigned char B[8]; + unsigned int flags = 0; + unsigned int bitmask = 0; + unsigned char P0 = 0, P1 = 0; + int lower_half = 0; + + /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on + * either top and bottom or left and right halves */ + CHECK_STREAM_PTR(2); + + P[0] = *s->stream_ptr++; + P[1] = *s->stream_ptr++; + + if (P[0] <= P[1]) { + + /* need 12 more bytes */ + CHECK_STREAM_PTR(12); + B[0] = *s->stream_ptr++; B[1] = *s->stream_ptr++; + P[2] = *s->stream_ptr++; P[3] = *s->stream_ptr++; + B[2] = *s->stream_ptr++; B[3] = *s->stream_ptr++; + P[4] = *s->stream_ptr++; P[5] = *s->stream_ptr++; + B[4] = *s->stream_ptr++; B[5] = *s->stream_ptr++; + P[6] = *s->stream_ptr++; P[7] = *s->stream_ptr++; + B[6] = *s->stream_ptr++; B[7] = *s->stream_ptr++; + + for (y = 0; y < 8; y++) { + + /* time to reload flags? */ + if (y == 0) { + flags = + ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | + ((B[0] & 0x0F) ) | ((B[4] & 0x0F) << 4) | + ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | + ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); + bitmask = 0x00000001; + lower_half = 0; /* still on top half */ + } else if (y == 4) { + flags = + ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | + ((B[2] & 0x0F) ) | ((B[6] & 0x0F) << 4) | + ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | + ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); + bitmask = 0x00000001; + lower_half = 2; + } + + for (x = 0; x < 8; x++, bitmask <<= 1) { + /* get the pixel values ready for this quadrant */ + if (x == 0) { + P0 = P[lower_half + 0]; + P1 = P[lower_half + 1]; + } else if (x == 4) { + P0 = P[lower_half + 4]; + P1 = P[lower_half + 5]; + } + + if (flags & bitmask) + *s->pixel_ptr++ = P1; + else + *s->pixel_ptr++ = P0; + } + s->pixel_ptr += s->line_inc; + } + + } else { + + /* need 10 more bytes */ + CHECK_STREAM_PTR(10); + B[0] = *s->stream_ptr++; B[1] = *s->stream_ptr++; + B[2] = *s->stream_ptr++; B[3] = *s->stream_ptr++; + P[2] = *s->stream_ptr++; P[3] = *s->stream_ptr++; + B[4] = *s->stream_ptr++; B[5] = *s->stream_ptr++; + B[6] = *s->stream_ptr++; B[7] = *s->stream_ptr++; + + if (P[2] <= P[3]) { + + /* vertical split; left & right halves are 2-color encoded */ + + for (y = 0; y < 8; y++) { + + /* time to reload flags? */ + if (y == 0) { + flags = + ((B[0] & 0xF0) << 4) | ((B[4] & 0xF0) << 8) | + ((B[0] & 0x0F) ) | ((B[4] & 0x0F) << 4) | + ((B[1] & 0xF0) << 20) | ((B[5] & 0xF0) << 24) | + ((B[1] & 0x0F) << 16) | ((B[5] & 0x0F) << 20); + bitmask = 0x00000001; + } else if (y == 4) { + flags = + ((B[2] & 0xF0) << 4) | ((B[6] & 0xF0) << 8) | + ((B[2] & 0x0F) ) | ((B[6] & 0x0F) << 4) | + ((B[3] & 0xF0) << 20) | ((B[7] & 0xF0) << 24) | + ((B[3] & 0x0F) << 16) | ((B[7] & 0x0F) << 20); + bitmask = 0x00000001; + } + + for (x = 0; x < 8; x++, bitmask <<= 1) { + /* get the pixel values ready for this half */ + if (x == 0) { + P0 = P[0]; + P1 = P[1]; + } else if (x == 4) { + P0 = P[2]; + P1 = P[3]; + } + + if (flags & bitmask) + *s->pixel_ptr++ = P1; + else + *s->pixel_ptr++ = P0; + } + s->pixel_ptr += s->line_inc; + } + + } else { + + /* horizontal split; top & bottom halves are 2-color encoded */ + + for (y = 0; y < 8; y++) { + + flags = B[y]; + if (y == 0) { + P0 = P[0]; + P1 = P[1]; + } else if (y == 4) { + P0 = P[2]; + P1 = P[3]; + } + + for (bitmask = 0x01; bitmask <= 0x80; bitmask <<= 1) { + + if (flags & bitmask) + *s->pixel_ptr++ = P1; + else + *s->pixel_ptr++ = P0; + } + s->pixel_ptr += s->line_inc; + } + } + } + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s) +{ + int x, y; + unsigned char P[4]; + unsigned char B[4]; + unsigned int flags = 0; + int shifter = 0; + unsigned char pix; + + /* 4-color encoding */ + CHECK_STREAM_PTR(4); + + for (y = 0; y < 4; y++) + P[y] = *s->stream_ptr++; + + if ((P[0] <= P[1]) && (P[2] <= P[3])) { + + /* 1 of 4 colors for each pixel, need 16 more bytes */ + CHECK_STREAM_PTR(16); + + for (y = 0; y < 8; y++) { + /* get the next set of 8 2-bit flags */ + flags = (s->stream_ptr[1] << 8) | s->stream_ptr[0]; + s->stream_ptr += 2; + for (x = 0, shifter = 0; x < 8; x++, shifter += 2) { + *s->pixel_ptr++ = P[(flags >> shifter) & 0x03]; + } + s->pixel_ptr += s->line_inc; + } + + } else if ((P[0] <= P[1]) && (P[2] > P[3])) { + + /* 1 of 4 colors for each 2x2 block, need 4 more bytes */ + CHECK_STREAM_PTR(4); + + B[0] = *s->stream_ptr++; + B[1] = *s->stream_ptr++; + B[2] = *s->stream_ptr++; + B[3] = *s->stream_ptr++; + flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + shifter = 0; + + for (y = 0; y < 8; y += 2) { + for (x = 0; x < 8; x += 2, shifter += 2) { + pix = P[(flags >> shifter) & 0x03]; + *(s->pixel_ptr + x) = pix; + *(s->pixel_ptr + x + 1) = pix; + *(s->pixel_ptr + s->stride + x) = pix; + *(s->pixel_ptr + s->stride + x + 1) = pix; + } + s->pixel_ptr += s->stride * 2; + } + + } else if ((P[0] > P[1]) && (P[2] <= P[3])) { + + /* 1 of 4 colors for each 2x1 block, need 8 more bytes */ + CHECK_STREAM_PTR(8); + + for (y = 0; y < 8; y++) { + /* time to reload flags? */ + if ((y == 0) || (y == 4)) { + B[0] = *s->stream_ptr++; + B[1] = *s->stream_ptr++; + B[2] = *s->stream_ptr++; + B[3] = *s->stream_ptr++; + flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + shifter = 0; + } + for (x = 0; x < 8; x += 2, shifter += 2) { + pix = P[(flags >> shifter) & 0x03]; + *(s->pixel_ptr + x) = pix; + *(s->pixel_ptr + x + 1) = pix; + } + s->pixel_ptr += s->stride; + } + + } else { + + /* 1 of 4 colors for each 1x2 block, need 8 more bytes */ + CHECK_STREAM_PTR(8); + + for (y = 0; y < 8; y += 2) { + /* time to reload flags? */ + if ((y == 0) || (y == 4)) { + B[0] = *s->stream_ptr++; + B[1] = *s->stream_ptr++; + B[2] = *s->stream_ptr++; + B[3] = *s->stream_ptr++; + flags = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0]; + shifter = 0; + } + for (x = 0; x < 8; x++, shifter += 2) { + pix = P[(flags >> shifter) & 0x03]; + *(s->pixel_ptr + x) = pix; + *(s->pixel_ptr + s->stride + x) = pix; + } + s->pixel_ptr += s->stride * 2; + } + } + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s) +{ + int x, y; + unsigned char P[16]; + unsigned char B[16]; + int flags = 0; + int shifter = 0; + int index; + int split; + int lower_half; + + /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on + * either top and bottom or left and right halves */ + CHECK_STREAM_PTR(4); + + for (y = 0; y < 4; y++) + P[y] = *s->stream_ptr++; + + if (P[0] <= P[1]) { + + /* 4-color encoding for each quadrant; need 28 more bytes */ + CHECK_STREAM_PTR(28); + + for (y = 0; y < 4; y++) + B[y] = *s->stream_ptr++; + for (y = 4; y < 16; y += 4) { + for (x = y; x < y + 4; x++) + P[x] = *s->stream_ptr++; + for (x = y; x < y + 4; x++) + B[x] = *s->stream_ptr++; + } + + for (y = 0; y < 8; y++) { + + lower_half = (y >= 4) ? 4 : 0; + flags = (B[y + 8] << 8) | B[y]; + + for (x = 0, shifter = 0; x < 8; x++, shifter += 2) { + split = (x >= 4) ? 8 : 0; + index = split + lower_half + ((flags >> shifter) & 0x03); + *s->pixel_ptr++ = P[index]; + } + + s->pixel_ptr += s->line_inc; + } + + } else { + + /* 4-color encoding for either left and right or top and bottom + * halves; need 20 more bytes */ + CHECK_STREAM_PTR(20); + + for (y = 0; y < 8; y++) + B[y] = *s->stream_ptr++; + for (y = 4; y < 8; y++) + P[y] = *s->stream_ptr++; + for (y = 8; y < 16; y++) + B[y] = *s->stream_ptr++; + + if (P[4] <= P[5]) { + + /* block is divided into left and right halves */ + for (y = 0; y < 8; y++) { + + flags = (B[y + 8] << 8) | B[y]; + split = 0; + + for (x = 0, shifter = 0; x < 8; x++, shifter += 2) { + if (x == 4) + split = 4; + *s->pixel_ptr++ = P[split + ((flags >> shifter) & 0x03)]; + } + + s->pixel_ptr += s->line_inc; + } + + } else { + + /* block is divided into top and bottom halves */ + split = 0; + for (y = 0; y < 8; y++) { + + flags = (B[y * 2 + 1] << 8) | B[y * 2]; + if (y == 4) + split = 4; + + for (x = 0, shifter = 0; x < 8; x++, shifter += 2) + *s->pixel_ptr++ = P[split + ((flags >> shifter) & 0x03)]; + + s->pixel_ptr += s->line_inc; + } + } + } + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s) +{ + int x, y; + + /* 64-color encoding (each pixel in block is a different color) */ + CHECK_STREAM_PTR(64); + + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + *s->pixel_ptr++ = *s->stream_ptr++; + } + s->pixel_ptr += s->line_inc; + } + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s) +{ + int x, y; + unsigned char pix; + + /* 16-color block encoding: each 2x2 block is a different color */ + CHECK_STREAM_PTR(16); + + for (y = 0; y < 8; y += 2) { + for (x = 0; x < 8; x += 2) { + pix = *s->stream_ptr++; + *(s->pixel_ptr + x) = pix; + *(s->pixel_ptr + x + 1) = pix; + *(s->pixel_ptr + s->stride + x) = pix; + *(s->pixel_ptr + s->stride + x + 1) = pix; + } + s->pixel_ptr += s->stride * 2; + } + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s) +{ + int x, y; + unsigned char P[4]; + unsigned char index = 0; + + /* 4-color block encoding: each 4x4 block is a different color */ + CHECK_STREAM_PTR(4); + + for (y = 0; y < 4; y++) + P[y] = *s->stream_ptr++; + + for (y = 0; y < 8; y++) { + if (y < 4) + index = 0; + else + index = 2; + + for (x = 0; x < 8; x++) { + if (x == 4) + index++; + *s->pixel_ptr++ = P[index]; + } + s->pixel_ptr += s->line_inc; + } + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s) +{ + int x, y; + unsigned char pix; + + /* 1-color encoding: the whole block is 1 solid color */ + CHECK_STREAM_PTR(1); + pix = *s->stream_ptr++; + + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + *s->pixel_ptr++ = pix; + } + s->pixel_ptr += s->line_inc; + } + + /* report success */ + return 0; +} + +static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s) +{ + int x, y; + unsigned char sample0, sample1; + + /* dithered encoding */ + CHECK_STREAM_PTR(2); + sample0 = *s->stream_ptr++; + sample1 = *s->stream_ptr++; + + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x += 2) { + if (y & 1) { + *s->pixel_ptr++ = sample1; + *s->pixel_ptr++ = sample0; + } else { + *s->pixel_ptr++ = sample0; + *s->pixel_ptr++ = sample1; + } + } + s->pixel_ptr += s->line_inc; + } + + /* report success */ + return 0; +} + +static int (*ipvideo_decode_block[16])(IpvideoContext *s); + +static void ipvideo_decode_opcodes(IpvideoContext *s) +{ + int x, y; + int index = 0; + unsigned char opcode; + int ret; + int code_counts[16]; + static int frame = 0; + + debug_interplay("------------------ frame %d\n", frame); + frame++; + + for (x = 0; x < 16; x++) + code_counts[x] = 0; + + /* this is PAL8, so make the palette available */ + memcpy(s->current_frame.data[1], s->avctx->palctrl->palette, PALETTE_COUNT * 4); + + s->stride = s->current_frame.linesize[0]; + s->stream_ptr = s->buf + 14; /* data starts 14 bytes in */ + s->stream_end = s->buf + s->size; + s->line_inc = s->stride - 8; + s->upper_motion_limit_offset = (s->avctx->height - 8) * s->stride + + s->avctx->width - 8; + s->dsp = s->dsp; + + for (y = 0; y < (s->stride * s->avctx->height); y += s->stride * 8) { + for (x = y; x < y + s->avctx->width; x += 8) { + /* bottom nibble first, then top nibble (which makes it + * hard to use a GetBitcontext) */ + if (index & 1) + opcode = s->decoding_map[index >> 1] >> 4; + else + opcode = s->decoding_map[index >> 1] & 0xF; + index++; + + debug_interplay(" block @ (%3d, %3d): encoding 0x%X, data ptr @ %p\n", + x - y, y / s->stride, opcode, s->stream_ptr); + code_counts[opcode]++; + + s->pixel_ptr = s->current_frame.data[0] + x; + ret = ipvideo_decode_block[opcode](s); + if (ret != 0) { + av_log(s->avctx, AV_LOG_ERROR, " Interplay video: decode problem on frame %d, @ block (%d, %d)\n", + frame, x - y, y / s->stride); + return; + } + } + } + if ((s->stream_ptr != s->stream_end) && + (s->stream_ptr + 1 != s->stream_end)) { + av_log(s->avctx, AV_LOG_ERROR, " Interplay video: decode finished with %td bytes left over\n", + s->stream_end - s->stream_ptr); + } +} + +static int ipvideo_decode_init(AVCodecContext *avctx) +{ + IpvideoContext *s = avctx->priv_data; + + s->avctx = avctx; + + if (s->avctx->palctrl == NULL) { + av_log(avctx, AV_LOG_ERROR, " Interplay video: palette expected.\n"); + return -1; + } + + avctx->pix_fmt = PIX_FMT_PAL8; + avctx->has_b_frames = 0; + dsputil_init(&s->dsp, avctx); + + /* decoding map contains 4 bits of information per 8x8 block */ + s->decoding_map_size = avctx->width * avctx->height / (8 * 8 * 2); + + /* assign block decode functions */ + ipvideo_decode_block[0x0] = ipvideo_decode_block_opcode_0x0; + ipvideo_decode_block[0x1] = ipvideo_decode_block_opcode_0x1; + ipvideo_decode_block[0x2] = ipvideo_decode_block_opcode_0x2; + ipvideo_decode_block[0x3] = ipvideo_decode_block_opcode_0x3; + ipvideo_decode_block[0x4] = ipvideo_decode_block_opcode_0x4; + ipvideo_decode_block[0x5] = ipvideo_decode_block_opcode_0x5; + ipvideo_decode_block[0x6] = ipvideo_decode_block_opcode_0x6; + ipvideo_decode_block[0x7] = ipvideo_decode_block_opcode_0x7; + ipvideo_decode_block[0x8] = ipvideo_decode_block_opcode_0x8; + ipvideo_decode_block[0x9] = ipvideo_decode_block_opcode_0x9; + ipvideo_decode_block[0xA] = ipvideo_decode_block_opcode_0xA; + ipvideo_decode_block[0xB] = ipvideo_decode_block_opcode_0xB; + ipvideo_decode_block[0xC] = ipvideo_decode_block_opcode_0xC; + ipvideo_decode_block[0xD] = ipvideo_decode_block_opcode_0xD; + ipvideo_decode_block[0xE] = ipvideo_decode_block_opcode_0xE; + ipvideo_decode_block[0xF] = ipvideo_decode_block_opcode_0xF; + + s->current_frame.data[0] = s->last_frame.data[0] = + s->second_last_frame.data[0] = NULL; + + return 0; +} + +static int ipvideo_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + IpvideoContext *s = avctx->priv_data; + AVPaletteControl *palette_control = avctx->palctrl; + + /* compressed buffer needs to be large enough to at least hold an entire + * decoding map */ + if (buf_size < s->decoding_map_size) + return buf_size; + + s->decoding_map = buf; + s->buf = buf + s->decoding_map_size; + s->size = buf_size - s->decoding_map_size; + + s->current_frame.reference = 3; + if (avctx->get_buffer(avctx, &s->current_frame)) { + av_log(avctx, AV_LOG_ERROR, " Interplay Video: get_buffer() failed\n"); + return -1; + } + + ipvideo_decode_opcodes(s); + + if (palette_control->palette_changed) { + palette_control->palette_changed = 0; + s->current_frame.palette_has_changed = 1; + } + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = s->current_frame; + + /* shuffle frames */ + if (s->second_last_frame.data[0]) + avctx->release_buffer(avctx, &s->second_last_frame); + s->second_last_frame = s->last_frame; + s->last_frame = s->current_frame; + s->current_frame.data[0] = NULL; /* catch any access attempts */ + + /* report that the buffer was completely consumed */ + return buf_size; +} + +static int ipvideo_decode_end(AVCodecContext *avctx) +{ + IpvideoContext *s = avctx->priv_data; + + /* release the last frame */ + if (s->last_frame.data[0]) + avctx->release_buffer(avctx, &s->last_frame); + if (s->second_last_frame.data[0]) + avctx->release_buffer(avctx, &s->second_last_frame); + + return 0; +} + +AVCodec interplay_video_decoder = { + "interplayvideo", + CODEC_TYPE_VIDEO, + CODEC_ID_INTERPLAY_VIDEO, + sizeof(IpvideoContext), + ipvideo_decode_init, + NULL, + ipvideo_decode_end, + ipvideo_decode_frame, + CODEC_CAP_DR1, +}; diff --git a/mpeg4/src/libavcodec/jfdctfst.c b/mpeg4/src/libavcodec/jfdctfst.c new file mode 100644 index 00000000..804fd576 --- /dev/null +++ b/mpeg4/src/libavcodec/jfdctfst.c @@ -0,0 +1,305 @@ +/* + * jfdctfst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README). The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs. These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries. The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values. The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +/** + * @file jfdctfst.c + * Independent JPEG Group's fast AAN dct. + */ + +#include +#include +#include "common.h" +#include "dsputil.h" + +#define DCTSIZE 8 +#define GLOBAL(x) x +#define RIGHT_SHIFT(x, n) ((x) >> (n)) +#define SHIFT_TEMPS + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jfdctint.c for more details. However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * Again to save a few shifts, the intermediate results between pass 1 and + * pass 2 are not upscaled, but are represented only to integral precision. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13. This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ + +#define CONST_BITS 8 + + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_0_382683433 ((int32_t) 98) /* FIX(0.382683433) */ +#define FIX_0_541196100 ((int32_t) 139) /* FIX(0.541196100) */ +#define FIX_0_707106781 ((int32_t) 181) /* FIX(0.707106781) */ +#define FIX_1_306562965 ((int32_t) 334) /* FIX(1.306562965) */ +#else +#define FIX_0_382683433 FIX(0.382683433) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_707106781 FIX(0.707106781) +#define FIX_1_306562965 FIX(1.306562965) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift. This yields an incorrectly + * rounded result half the time... + */ + +#ifndef USE_ACCURATE_ROUNDING +#undef DESCALE +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* Multiply a DCTELEM variable by an int32_t constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) + +static always_inline void row_fdct(DCTELEM * data){ + int_fast16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + int_fast16_t tmp10, tmp11, tmp12, tmp13; + int_fast16_t z1, z2, z3, z4, z5, z11, z13; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = tmp10 + tmp11; /* phase 3 */ + dataptr[4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[3] = z13 - z2; + dataptr[1] = z11 + z4; + dataptr[7] = z11 - z4; + + dataptr += DCTSIZE; /* advance pointer to next row */ + } +} + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +fdct_ifast (DCTELEM * data) +{ + int_fast16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + int_fast16_t tmp10, tmp11, tmp12, tmp13; + int_fast16_t z1, z2, z3, z4, z5, z11, z13; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + row_fdct(data); + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */ + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ + dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */ + dataptr[DCTSIZE*6] = tmp13 - z1; + + /* Odd part */ + + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */ + z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */ + z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ + z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ + + z11 = tmp7 + z3; /* phase 5 */ + z13 = tmp7 - z3; + + dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ + dataptr[DCTSIZE*3] = z13 - z2; + dataptr[DCTSIZE*1] = z11 + z4; + dataptr[DCTSIZE*7] = z11 - z4; + + dataptr++; /* advance pointer to next column */ + } +} + +/* + * Perform the forward 2-4-8 DCT on one block of samples. + */ + +GLOBAL(void) +fdct_ifast248 (DCTELEM * data) +{ + int_fast16_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + int_fast16_t tmp10, tmp11, tmp12, tmp13; + int_fast16_t z1; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + row_fdct(data); + + /* Pass 2: process columns. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*1]; + tmp1 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*3]; + tmp2 = dataptr[DCTSIZE*4] + dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*6] + dataptr[DCTSIZE*7]; + tmp4 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*1]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*3]; + tmp6 = dataptr[DCTSIZE*4] - dataptr[DCTSIZE*5]; + tmp7 = dataptr[DCTSIZE*6] - dataptr[DCTSIZE*7]; + + /* Even part */ + + tmp10 = tmp0 + tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + tmp13 = tmp0 - tmp3; + + dataptr[DCTSIZE*0] = tmp10 + tmp11; + dataptr[DCTSIZE*4] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); + dataptr[DCTSIZE*2] = tmp13 + z1; + dataptr[DCTSIZE*6] = tmp13 - z1; + + tmp10 = tmp4 + tmp7; + tmp11 = tmp5 + tmp6; + tmp12 = tmp5 - tmp6; + tmp13 = tmp4 - tmp7; + + dataptr[DCTSIZE*1] = tmp10 + tmp11; + dataptr[DCTSIZE*5] = tmp10 - tmp11; + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); + dataptr[DCTSIZE*3] = tmp13 + z1; + dataptr[DCTSIZE*7] = tmp13 - z1; + + dataptr++; /* advance pointer to next column */ + } +} + + +#undef GLOBAL +#undef CONST_BITS +#undef DESCALE +#undef FIX_0_541196100 +#undef FIX_1_306562965 diff --git a/mpeg4/src/libavcodec/jfdctint.c b/mpeg4/src/libavcodec/jfdctint.c new file mode 100644 index 00000000..41d27499 --- /dev/null +++ b/mpeg4/src/libavcodec/jfdctint.c @@ -0,0 +1,373 @@ +/* + * jfdctint.c + * + * Copyright (C) 1991-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +/** + * @file jfdctint.c + * Independent JPEG Group's slow & accurate dct. + */ + +#include +#include +#include "common.h" +#include "dsputil.h" + +#define SHIFT_TEMPS +#define DCTSIZE 8 +#define BITS_IN_JSAMPLE 8 +#define GLOBAL(x) x +#define RIGHT_SHIFT(x, n) ((x) >> (n)) +#define MULTIPLY16C16(var,const) ((var)*(const)) + +#if 1 //def USE_ACCURATE_ROUNDING +#define DESCALE(x,n) RIGHT_SHIFT((x) + (1 << ((n) - 1)), n) +#else +#define DESCALE(x,n) RIGHT_SHIFT(x, n) +#endif + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D DCT step produces outputs which are a factor of sqrt(N) + * larger than the true DCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D DCT, + * because the y0 and y4 outputs need not be divided by sqrt(N). + * In the IJG code, this factor of 8 is removed by the quantization step + * (in jcdctmgr.c), NOT in this module. + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (For 12-bit sample data, the intermediate + * array is int32_t anyway.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS 13 +#define PASS1_BITS 4 /* set this to 2 if 16x16 multiplies are faster */ +#else +#define CONST_BITS 13 +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336 ((int32_t) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((int32_t) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((int32_t) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((int32_t) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((int32_t) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((int32_t) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((int32_t) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((int32_t) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((int32_t) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((int32_t) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((int32_t) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((int32_t) 25172) /* FIX(3.072711026) */ +#else +#define FIX_0_298631336 FIX(0.298631336) +#define FIX_0_390180644 FIX(0.390180644) +#define FIX_0_541196100 FIX(0.541196100) +#define FIX_0_765366865 FIX(0.765366865) +#define FIX_0_899976223 FIX(0.899976223) +#define FIX_1_175875602 FIX(1.175875602) +#define FIX_1_501321110 FIX(1.501321110) +#define FIX_1_847759065 FIX(1.847759065) +#define FIX_1_961570560 FIX(1.961570560) +#define FIX_2_053119869 FIX(2.053119869) +#define FIX_2_562915447 FIX(2.562915447) +#define FIX_3_072711026 FIX(3.072711026) +#endif + + +/* Multiply an int32_t variable by an int32_t constant to yield an int32_t result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 && CONST_BITS<=13 && PASS1_BITS<=2 +#define MULTIPLY(var,const) MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +static always_inline void row_fdct(DCTELEM * data){ + int_fast32_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + int_fast32_t tmp10, tmp11, tmp12, tmp13; + int_fast32_t z1, z2, z3, z4, z5; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + /* Pass 1: process rows. */ + /* Note results are scaled up by sqrt(8) compared to a true DCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[0] + dataptr[7]; + tmp7 = dataptr[0] - dataptr[7]; + tmp1 = dataptr[1] + dataptr[6]; + tmp6 = dataptr[1] - dataptr[6]; + tmp2 = dataptr[2] + dataptr[5]; + tmp5 = dataptr[2] - dataptr[5]; + tmp3 = dataptr[3] + dataptr[4]; + tmp4 = dataptr[3] - dataptr[4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS); + dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS-PASS1_BITS); + dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS-PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); + dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); + dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); + dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); + + dataptr += DCTSIZE; /* advance pointer to next row */ + } +} + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL(void) +ff_jpeg_fdct_islow (DCTELEM * data) +{ + int_fast32_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + int_fast32_t tmp10, tmp11, tmp12, tmp13; + int_fast32_t z1, z2, z3, z4, z5; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + row_fdct(data); + + /* Pass 2: process columns. + * We remove the PASS1_BITS scaling, but leave the results scaled up + * by an overall factor of 8. + */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; + tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; + tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; + tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; + tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; + tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; + + /* Even part per LL&M figure 1 --- note that published figure is faulty; + * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". + */ + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + + dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); + dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS+PASS1_BITS); + + /* Odd part per figure 8 --- note paper omits factor of sqrt(2). + * cK represents cos(K*pi/16). + * i0..i3 in the paper are tmp4..tmp7 here. + */ + + z1 = tmp4 + tmp7; + z2 = tmp5 + tmp6; + z3 = tmp4 + tmp6; + z4 = tmp5 + tmp7; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ + + tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ + tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ + tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ + tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ + z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ + z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ + z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ + z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ + + z3 += z5; + z4 += z5; + + dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, + CONST_BITS+PASS1_BITS); + + dataptr++; /* advance pointer to next column */ + } +} + +/* + * The secret of DCT2-4-8 is really simple -- you do the usual 1-DCT + * on the rows and then, instead of doing even and odd, part on the colums + * you do even part two times. + */ +GLOBAL(void) +ff_fdct248_islow (DCTELEM * data) +{ + int_fast32_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; + int_fast32_t tmp10, tmp11, tmp12, tmp13; + int_fast32_t z1; + DCTELEM *dataptr; + int ctr; + SHIFT_TEMPS + + row_fdct(data); + + /* Pass 2: process columns. + * We remove the PASS1_BITS scaling, but leave the results scaled up + * by an overall factor of 8. + */ + + dataptr = data; + for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { + tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*1]; + tmp1 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*3]; + tmp2 = dataptr[DCTSIZE*4] + dataptr[DCTSIZE*5]; + tmp3 = dataptr[DCTSIZE*6] + dataptr[DCTSIZE*7]; + tmp4 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*1]; + tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*3]; + tmp6 = dataptr[DCTSIZE*4] - dataptr[DCTSIZE*5]; + tmp7 = dataptr[DCTSIZE*6] - dataptr[DCTSIZE*7]; + + tmp10 = tmp0 + tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + tmp13 = tmp0 - tmp3; + + dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); + dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS+PASS1_BITS); + + tmp10 = tmp4 + tmp7; + tmp11 = tmp5 + tmp6; + tmp12 = tmp5 - tmp6; + tmp13 = tmp4 - tmp7; + + dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); + dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); + + z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); + dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), + CONST_BITS+PASS1_BITS); + dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), + CONST_BITS+PASS1_BITS); + + dataptr++; /* advance pointer to next column */ + } +} diff --git a/mpeg4/src/libavcodec/jpeg_ls.c b/mpeg4/src/libavcodec/jpeg_ls.c new file mode 100644 index 00000000..4b365bb4 --- /dev/null +++ b/mpeg4/src/libavcodec/jpeg_ls.c @@ -0,0 +1,843 @@ +/* + * JPEG-LS encoder and decoder + * Copyright (c) 2003 Michael Niedermayer + * Copyright (c) 2006 Konstantin Shishkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "golomb.h" + +/** + * @file jpeg_ls.c + * JPEG-LS encoder and decoder. + */ + +typedef struct JpeglsContext{ + AVCodecContext *avctx; + AVFrame picture; +}JpeglsContext; + +typedef struct JLSState{ + int T1, T2, T3; + int A[367], B[367], C[365], N[367]; + int limit, reset, bpp, qbpp, maxval, range; + int near, twonear; + int run_index[3]; +}JLSState; + +static const uint8_t log2_run[32]={ + 0, 0, 0, 0, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9,10,11,12,13,14,15 +}; + +/* +* Uncomment this to significantly speed up decoding of broken JPEG-LS +* (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit. +* +* There is no Golomb code with length >= 32 bits possible, so check and +* avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow +* on this errors. +*/ +//#define JLS_BROKEN + +/********** Functions for both encoder and decoder **********/ + +/** + * Calculate initial JPEG-LS parameters + */ +static void ls_init_state(JLSState *state){ + int i; + + state->twonear = state->near * 2 + 1; + state->range = ((state->maxval + state->twonear - 1) / state->twonear) + 1; + + // QBPP = ceil(log2(RANGE)) + for(state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++); + + if(state->bpp < 8) + state->limit = 16 + 2 * state->bpp - state->qbpp; + else + state->limit = (4 * state->bpp) - state->qbpp; + + for(i = 0; i < 367; i++) { + state->A[i] = (state->range + 32) >> 6; + if(state->A[i] < 2) + state->A[i] = 2; + state->N[i] = 1; + } + +} + +/** + * Calculate quantized gradient value, used for context determination + */ +static inline int quantize(JLSState *s, int v){ //FIXME optimize + if(v==0) return 0; + if(v < 0){ + if(v <= -s->T3) return -4; + if(v <= -s->T2) return -3; + if(v <= -s->T1) return -2; + if(v < -s->near) return -1; + return 0; + }else{ + if(v <= s->near) return 0; + if(v < s->T1) return 1; + if(v < s->T2) return 2; + if(v < s->T3) return 3; + return 4; + } +} + +/** + * Custom value clipping function used in T1, T2, T3 calculation + */ +static inline int iso_clip(int v, int vmin, int vmax){ + if(v > vmax || v < vmin) return vmin; + else return v; +} + +/** + * Calculate JPEG-LS codec values + */ +static void reset_ls_coding_parameters(JLSState *s, int reset_all){ + const int basic_t1= 3; + const int basic_t2= 7; + const int basic_t3= 21; + int factor; + + if(s->maxval==0 || reset_all) s->maxval= (1 << s->bpp) - 1; + + if(s->maxval >=128){ + factor= (FFMIN(s->maxval, 4095) + 128)>>8; + + if(s->T1==0 || reset_all) + s->T1= iso_clip(factor*(basic_t1-2) + 2 + 3*s->near, s->near+1, s->maxval); + if(s->T2==0 || reset_all) + s->T2= iso_clip(factor*(basic_t2-3) + 3 + 5*s->near, s->T1, s->maxval); + if(s->T3==0 || reset_all) + s->T3= iso_clip(factor*(basic_t3-4) + 4 + 7*s->near, s->T2, s->maxval); + }else{ + factor= 256 / (s->maxval + 1); + + if(s->T1==0 || reset_all) + s->T1= iso_clip(FFMAX(2, basic_t1/factor + 3*s->near), s->near+1, s->maxval); + if(s->T2==0 || reset_all) + s->T2= iso_clip(FFMAX(3, basic_t2/factor + 5*s->near), s->T1, s->maxval); + if(s->T3==0 || reset_all) + s->T3= iso_clip(FFMAX(4, basic_t3/factor + 6*s->near), s->T2, s->maxval); + } + + if(s->reset==0 || reset_all) s->reset= 64; +// av_log(NULL, AV_LOG_DEBUG, "[JPEG-LS RESET] T=%i,%i,%i\n", s->T1, s->T2, s->T3); +} + + +/********** Decoder-specific functions **********/ + +/** + * Decode LSE block with initialization parameters + */ +static int decode_lse(MJpegDecodeContext *s) +{ + int len, id; + + /* XXX: verify len field validity */ + len = get_bits(&s->gb, 16); + id = get_bits(&s->gb, 8); + + switch(id){ + case 1: + s->maxval= get_bits(&s->gb, 16); + s->t1= get_bits(&s->gb, 16); + s->t2= get_bits(&s->gb, 16); + s->t3= get_bits(&s->gb, 16); + s->reset= get_bits(&s->gb, 16); + +// reset_ls_coding_parameters(s, 0); + //FIXME quant table? + break; + case 2: + case 3: + av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n"); + return -1; + case 4: + av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n"); + return -1; + default: + av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id); + return -1; + } +// av_log(s->avctx, AV_LOG_DEBUG, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3); + + return 0; +} + + +/** + * Get context-dependent Golomb code, decode it and update context + */ +static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q){ + int k, ret; + + for(k = 0; (state->N[Q] << k) < state->A[Q]; k++); + +#ifdef JLS_BROKEN + if(!show_bits_long(gb, 32))return -1; +#endif + ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp); + + /* decode mapped error */ + if(ret & 1) + ret = -((ret + 1) >> 1); + else + ret >>= 1; + + /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */ + if(!state->near && !k && (2 * state->B[Q] <= -state->N[Q])) + ret = -(ret + 1); + + state->A[Q] += ABS(ret); + ret *= state->twonear; + state->B[Q] += ret; + + if(state->N[Q] == state->reset) { + state->A[Q] >>= 1; + state->B[Q] >>= 1; + state->N[Q] >>= 1; + } + state->N[Q]++; + + if(state->B[Q] <= -state->N[Q]) { + state->B[Q] += state->N[Q]; + if(state->C[Q] > -128) + state->C[Q]--; + if(state->B[Q] <= -state->N[Q]) + state->B[Q] = -state->N[Q] + 1; + }else if(state->B[Q] > 0){ + state->B[Q] -= state->N[Q]; + if(state->C[Q] < 127) + state->C[Q]++; + if(state->B[Q] > 0) + state->B[Q] = 0; + } + + return ret; +} + +/** + * Get Golomb code, decode it and update state for run termination + */ +static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RItype, int limit_add){ + int k, ret, temp, map; + int Q = 365 + RItype; + + if(!RItype) + temp = state->A[Q]; + else + temp = state->A[Q] + (state->N[Q] >> 1); + + for(k = 0; (state->N[Q] << k) < temp; k++); + +#ifdef JLS_BROKEN + if(!show_bits_long(gb, 32))return -1; +#endif + ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp); + + /* decode mapped error */ + map = 0; + if(!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q])) + map = 1; + ret += RItype + map; + + if(ret & 1){ + ret = map - ((ret + 1) >> 1); + state->B[Q]++; + } else { + ret = ret >> 1; + } + + /* update state */ + state->A[Q] += ABS(ret) - RItype; + ret *= state->twonear; + if(state->N[Q] == state->reset){ + state->A[Q] >>=1; + state->B[Q] >>=1; + state->N[Q] >>=1; + } + state->N[Q]++; + + return ret; +} + +/** + * Decode one line of image + */ +static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, uint8_t *last, uint8_t *dst, int last2, int w, int stride, int comp){ + int i, x = 0; + int Ra, Rb, Rc, Rd; + int D0, D1, D2; + + while(x < w) { + int err, pred; + + /* compute gradients */ + Ra = x ? dst[x - stride] : last[x]; + Rb = last[x]; + Rc = x ? last[x - stride] : last2; + Rd = (x >= w - stride) ? last[x] : last[x + stride]; + D0 = Rd - Rb; + D1 = Rb - Rc; + D2 = Rc - Ra; + /* run mode */ + if((ABS(D0) <= state->near) && (ABS(D1) <= state->near) && (ABS(D2) <= state->near)) { + int r; + int RItype; + + /* decode full runs while available */ + while(get_bits1(&s->gb)) { + int r; + r = 1 << log2_run[state->run_index[comp]]; + if(x + r * stride > w) { + r = (w - x) / stride; + } + for(i = 0; i < r; i++) { + dst[x] = Ra; + x += stride; + } + /* if EOL reached, we stop decoding */ + if(r != (1 << log2_run[state->run_index[comp]])) + return; + if(state->run_index[comp] < 31) + state->run_index[comp]++; + if(x + stride > w) + return; + } + /* decode aborted run */ + r = log2_run[state->run_index[comp]]; + if(r) + r = get_bits_long(&s->gb, r); + for(i = 0; i < r; i++) { + dst[x] = Ra; + x += stride; + } + + /* decode run termination value */ + Rb = last[x]; + RItype = (ABS(Ra - Rb) <= state->near) ? 1 : 0; + err = ls_get_code_runterm(&s->gb, state, RItype, log2_run[state->run_index[comp]]); + if(state->run_index[comp]) + state->run_index[comp]--; + + if(state->near && RItype){ + pred = Ra + err; + } else { + if(Rb < Ra) + pred = Rb - err; + else + pred = Rb + err; + } + + if(state->near){ + if(pred < -state->near) + pred += state->range * state->twonear; + else if(pred > state->maxval + state->near) + pred -= state->range * state->twonear; + pred = clip(pred, 0, state->maxval); + } + + dst[x] = pred; + x += stride; + } else { /* regular mode */ + int context, sign; + + context = quantize(state, D0) * 81 + quantize(state, D1) * 9 + quantize(state, D2); + pred = mid_pred(Ra, Ra + Rb - Rc, Rb); + + if(context < 0){ + context = -context; + sign = 1; + }else{ + sign = 0; + } + + if(sign){ + pred = clip(pred - state->C[context], 0, state->maxval); + err = -ls_get_code_regular(&s->gb, state, context); + } else { + pred = clip(pred + state->C[context], 0, state->maxval); + err = ls_get_code_regular(&s->gb, state, context); + } + + /* we have to do something more for near-lossless coding */ + pred += err; + if(state->near) { + if(pred < -state->near) + pred += state->range * state->twonear; + else if(pred > state->maxval + state->near) + pred -= state->range * state->twonear; + pred = clip(pred, 0, state->maxval); + } + + dst[x] = pred; + x += stride; + } + } +} + +static int ls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){ + int i, t = 0; + uint8_t *zero, *last, *cur; + JLSState *state; + int off, stride, width; + + zero = av_mallocz(s->picture.linesize[0]); + last = zero; + cur = s->picture.data[0]; + + state = av_mallocz(sizeof(JLSState)); + /* initialize JPEG-LS state from JPEG parameters */ + state->near = near; + state->bpp = (s->bits < 2) ? 2 : s->bits; + state->maxval = s->maxval; + state->T1 = s->t1; + state->T2 = s->t2; + state->T3 = s->t3; + state->reset = s->reset; + reset_ls_coding_parameters(state, 0); + ls_init_state(state); + +// av_log(s->avctx, AV_LOG_DEBUG, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",s->width,s->height,state->near,state->maxval,state->T1,state->T2,state->T3,state->reset,state->limit,state->qbpp, state->range); +// av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n", ilv, point_transform, s->bits, s->cur_scan); + if(ilv == 0) { /* separate planes */ + off = s->cur_scan - 1; + stride = (s->nb_components > 1) ? 3 : 1; + width = s->width * stride; + cur += off; + for(i = 0; i < s->height; i++) { + ls_decode_line(state, s, last, cur, t, width, stride, off); + t = last[0]; + last = cur; + cur += s->picture.linesize[0]; + + if (s->restart_interval && !--s->restart_count) { + align_get_bits(&s->gb); + skip_bits(&s->gb, 16); /* skip RSTn */ + } + } + } else if(ilv == 1) { /* line interleaving */ + int j; + int Rc[3] = {0, 0, 0}; + memset(cur, 0, s->picture.linesize[0]); + width = s->width * 3; + for(i = 0; i < s->height; i++) { + for(j = 0; j < 3; j++) { + ls_decode_line(state, s, last + j, cur + j, Rc[j], width, 3, j); + Rc[j] = last[j]; + + if (s->restart_interval && !--s->restart_count) { + align_get_bits(&s->gb); + skip_bits(&s->gb, 16); /* skip RSTn */ + } + } + last = cur; + cur += s->picture.linesize[0]; + } + } else if(ilv == 2) { /* sample interleaving */ + av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n"); + return -1; + } + + av_free(state); + av_free(zero); + + return 0; +} + +#if defined(CONFIG_ENCODERS) && defined(CONFIG_JPEGLS_ENCODER) +/********** Encoder-specific functions **********/ + +/** + * Encode error from regular symbol + */ +static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q, int err){ + int k; + int val; + int map; + + for(k = 0; (state->N[Q] << k) < state->A[Q]; k++); + + map = !state->near && !k && (2 * state->B[Q] <= -state->N[Q]); + + if(err < 0) + err += state->range; + if(err >= ((state->range + 1) >> 1)) { + err -= state->range; + val = 2 * ABS(err) - 1 - map; + } else + val = 2 * err + map; + + set_ur_golomb_jpegls(pb, val, k, state->limit, state->qbpp); + + state->A[Q] += ABS(err); + state->B[Q] += err * state->twonear; + + if(state->N[Q] == state->reset) { + state->A[Q] >>= 1; + state->B[Q] >>= 1; + state->N[Q] >>= 1; + } + state->N[Q]++; + + if(state->B[Q] <= -state->N[Q]) { + state->B[Q] += state->N[Q]; + if(state->C[Q] > -128) + state->C[Q]--; + if(state->B[Q] <= -state->N[Q]) + state->B[Q] = -state->N[Q] + 1; + }else if(state->B[Q] > 0){ + state->B[Q] -= state->N[Q]; + if(state->C[Q] < 127) + state->C[Q]++; + if(state->B[Q] > 0) + state->B[Q] = 0; + } +} + +/** + * Encode error from run termination + */ +static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb, int RItype, int err, int limit_add){ + int k; + int val, map; + int Q = 365 + RItype; + int temp; + + temp = state->A[Q]; + if(RItype) + temp += state->N[Q] >> 1; + for(k = 0; (state->N[Q] << k) < temp; k++); + map = 0; + if(!k && err && (2 * state->B[Q] < state->N[Q])) + map = 1; + + if(err < 0) + val = - (2 * err) - 1 - RItype + map; + else + val = 2 * err - RItype - map; + set_ur_golomb_jpegls(pb, val, k, state->limit - limit_add - 1, state->qbpp); + + if(err < 0) + state->B[Q]++; + state->A[Q] += (val + 1 - RItype) >> 1; + + if(state->N[Q] == state->reset) { + state->A[Q] >>= 1; + state->B[Q] >>= 1; + state->N[Q] >>= 1; + } + state->N[Q]++; +} + +/** + * Encode run value as specified by JPEG-LS standard + */ +static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run, int comp, int trail){ + while(run >= (1 << log2_run[state->run_index[comp]])){ + put_bits(pb, 1, 1); + run -= 1 << log2_run[state->run_index[comp]]; + if(state->run_index[comp] < 31) + state->run_index[comp]++; + } + /* if hit EOL, encode another full run, else encode aborted run */ + if(!trail && run) { + put_bits(pb, 1, 1); + }else if(trail){ + put_bits(pb, 1, 0); + if(log2_run[state->run_index[comp]]) + put_bits(pb, log2_run[state->run_index[comp]], run); + } +} + +/** + * Encode one line of image + */ +static inline void ls_encode_line(JLSState *state, PutBitContext *pb, uint8_t *last, uint8_t *cur, int last2, int w, int stride, int comp){ + int x = 0; + int Ra, Rb, Rc, Rd; + int D0, D1, D2; + + while(x < w) { + int err, pred, sign; + + /* compute gradients */ + Ra = x ? cur[x - stride] : last[x]; + Rb = last[x]; + Rc = x ? last[x - stride] : last2; + Rd = (x >= w - stride) ? last[x] : last[x + stride]; + D0 = Rd - Rb; + D1 = Rb - Rc; + D2 = Rc - Ra; + + /* run mode */ + if((ABS(D0) <= state->near) && (ABS(D1) <= state->near) && (ABS(D2) <= state->near)) { + int RUNval, RItype, run; + + run = 0; + RUNval = Ra; + while(x < w && (ABS(cur[x] - RUNval) <= state->near)){ + run++; + cur[x] = Ra; + x += stride; + } + ls_encode_run(state, pb, run, comp, x < w); + if(x >= w) + return; + Rb = last[x]; + RItype = (ABS(Ra - Rb) <= state->near); + pred = RItype ? Ra : Rb; + err = cur[x] - pred; + + if(!RItype && Ra > Rb) + err = -err; + + if(state->near){ + if(err > 0) + err = (state->near + err) / state->twonear; + else + err = -(state->near - err) / state->twonear; + + if(RItype || (Rb >= Ra)) + Ra = clip(pred + err * state->twonear, 0, state->maxval); + else + Ra = clip(pred - err * state->twonear, 0, state->maxval); + cur[x] = Ra; + } + if(err < 0) + err += state->range; + if(err >= ((state->range + 1) >> 1)) + err -= state->range; + + ls_encode_runterm(state, pb, RItype, err, log2_run[state->run_index[comp]]); + + if(state->run_index[comp] > 0) + state->run_index[comp]--; + x += stride; + } else { /* regular mode */ + int context; + + context = quantize(state, D0) * 81 + quantize(state, D1) * 9 + quantize(state, D2); + pred = mid_pred(Ra, Ra + Rb - Rc, Rb); + + if(context < 0){ + context = -context; + sign = 1; + pred = clip(pred - state->C[context], 0, state->maxval); + err = pred - cur[x]; + }else{ + sign = 0; + pred = clip(pred + state->C[context], 0, state->maxval); + err = cur[x] - pred; + } + + if(state->near){ + if(err > 0) + err = (state->near + err) / state->twonear; + else + err = -(state->near - err) / state->twonear; + if(!sign) + Ra = clip(pred + err * state->twonear, 0, state->maxval); + else + Ra = clip(pred - err * state->twonear, 0, state->maxval); + cur[x] = Ra; + } + + ls_encode_regular(state, pb, context, err); + x += stride; + } + } +} + +static void ls_store_lse(JLSState *state, PutBitContext *pb){ + /* Test if we have default params and don't need to store LSE */ + JLSState state2; + memset(&state2, 0, sizeof(JLSState)); + state2.bpp = 8; + state2.near = state->near; + reset_ls_coding_parameters(&state2, 1); + if(state->T1 == state2.T1 && state->T2 == state2.T2 && state->T3 == state2.T3 && state->reset == state2.reset) + return; + /* store LSE type 1 */ + put_marker(pb, LSE); + put_bits(pb, 16, 13); + put_bits(pb, 8, 1); + put_bits(pb, 16, state->maxval); + put_bits(pb, 16, state->T1); + put_bits(pb, 16, state->T2); + put_bits(pb, 16, state->T3); + put_bits(pb, 16, state->reset); +} + +static int encode_picture_ls(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + JpeglsContext * const s = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p= (AVFrame*)&s->picture; + const int near = avctx->prediction_method; + PutBitContext pb, pb2; + GetBitContext gb; + uint8_t *buf2, *zero, *cur, *last; + JLSState *state; + int i, size; + int comps; + + buf2 = av_malloc(buf_size); + + init_put_bits(&pb, buf, buf_size); + init_put_bits(&pb2, buf2, buf_size); + + *p = *pict; + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + + comps = (avctx->pix_fmt == PIX_FMT_GRAY8) ? 1 : 3; + + /* write our own JPEG header, can't use mjpeg_picture_header */ + put_marker(&pb, SOI); + put_marker(&pb, SOF48); + put_bits(&pb, 16, 8 + comps * 3); // header size depends on components + put_bits(&pb, 8, 8); // bpp + put_bits(&pb, 16, avctx->height); + put_bits(&pb, 16, avctx->width); + put_bits(&pb, 8, comps); // components + for(i = 1; i <= comps; i++) { + put_bits(&pb, 8, i); // component ID + put_bits(&pb, 8, 0x11); // subsampling: none + put_bits(&pb, 8, 0); // Tiq, used by JPEG-LS ext + } + + put_marker(&pb, SOS); + put_bits(&pb, 16, 6 + comps * 2); + put_bits(&pb, 8, comps); + for(i = 1; i <= comps; i++) { + put_bits(&pb, 8, i); // component ID + put_bits(&pb, 8, 0); // mapping index: none + } + put_bits(&pb, 8, near); + put_bits(&pb, 8, (comps > 1) ? 1 : 0); // interleaving: 0 - plane, 1 - line + put_bits(&pb, 8, 0); // point transform: none + + state = av_mallocz(sizeof(JLSState)); + /* initialize JPEG-LS state from JPEG parameters */ + state->near = near; + state->bpp = 8; + reset_ls_coding_parameters(state, 0); + ls_init_state(state); + + ls_store_lse(state, &pb); + + zero = av_mallocz(p->linesize[0]); + last = zero; + cur = p->data[0]; + if(avctx->pix_fmt == PIX_FMT_GRAY8){ + int t = 0; + + for(i = 0; i < avctx->height; i++) { + ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0); + t = last[0]; + last = cur; + cur += p->linesize[0]; + } + }else if(avctx->pix_fmt == PIX_FMT_RGB24){ + int j, width; + int Rc[3] = {0, 0, 0}; + + width = avctx->width * 3; + for(i = 0; i < avctx->height; i++) { + for(j = 0; j < 3; j++) { + ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j); + Rc[j] = last[j]; + } + last = cur; + cur += s->picture.linesize[0]; + } + }else if(avctx->pix_fmt == PIX_FMT_BGR24){ + int j, width; + int Rc[3] = {0, 0, 0}; + + width = avctx->width * 3; + for(i = 0; i < avctx->height; i++) { + for(j = 2; j >= 0; j--) { + ls_encode_line(state, &pb2, last + j, cur + j, Rc[j], width, 3, j); + Rc[j] = last[j]; + } + last = cur; + cur += s->picture.linesize[0]; + } + } + + av_free(zero); + av_free(state); + + flush_put_bits(&pb2); + /* do escape coding */ + size = put_bits_count(&pb2) >> 3; + init_get_bits(&gb, buf2, size); + while(get_bits_count(&gb) < size * 8){ + int v; + v = get_bits(&gb, 8); + put_bits(&pb, 8, v); + if(v == 0xFF){ + v = get_bits(&gb, 7); + put_bits(&pb, 8, v); + } + } + align_put_bits(&pb); + av_free(buf2); + + /* End of image */ + put_marker(&pb, EOI); + flush_put_bits(&pb); + + emms_c(); + + return put_bits_count(&pb) >> 3; +} + +static int encode_init_ls(AVCodecContext *ctx) { + JpeglsContext *c = (JpeglsContext*)ctx->priv_data; + + c->avctx = ctx; + ctx->coded_frame = &c->picture; + + if(ctx->pix_fmt != PIX_FMT_GRAY8 && ctx->pix_fmt != PIX_FMT_RGB24 && ctx->pix_fmt != PIX_FMT_BGR24){ + av_log(ctx, AV_LOG_ERROR, "Only grayscale and RGB24/BGR24 images are supported\n"); + return -1; + } + return 0; +} + +AVCodec jpegls_encoder = { //FIXME avoid MPV_* lossless jpeg shouldnt need them + "jpegls", + CODEC_TYPE_VIDEO, + CODEC_ID_JPEGLS, + sizeof(JpeglsContext), + encode_init_ls, + encode_picture_ls, + NULL, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_RGB24, PIX_FMT_GRAY8, -1}, +}; +#endif diff --git a/mpeg4/src/libavcodec/jrevdct.c b/mpeg4/src/libavcodec/jrevdct.c new file mode 100644 index 00000000..dc2ffaff --- /dev/null +++ b/mpeg4/src/libavcodec/jrevdct.c @@ -0,0 +1,1126 @@ +/* + * jrevdct.c + * + * Copyright (C) 1991, 1992, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the basic inverse-DCT transformation subroutine. + * + * This implementation is based on an algorithm described in + * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + * + * I've made lots of modifications to attempt to take advantage of the + * sparse nature of the DCT matrices we're getting. Although the logic + * is cumbersome, it's straightforward and the resulting code is much + * faster. + * + * A better way to do this would be to pass in the DCT block as a sparse + * matrix, perhaps with the difference cases encoded. + */ + +/** + * @file jrevdct.c + * Independent JPEG Group's LLM idct. + */ + +#include "common.h" +#include "dsputil.h" + +#define EIGHT_BIT_SAMPLES + +#define DCTSIZE 8 +#define DCTSIZE2 64 + +#define GLOBAL + +#define RIGHT_SHIFT(x, n) ((x) >> (n)) + +typedef DCTELEM DCTBLOCK[DCTSIZE2]; + +#define CONST_BITS 13 + +/* + * This routine is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 + Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * A 2-D IDCT can be done by 1-D IDCT on each row followed by 1-D IDCT + * on each column. Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * The poop on this scaling stuff is as follows: + * + * Each 1-D IDCT step produces outputs which are a factor of sqrt(N) + * larger than the true IDCT outputs. The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm. The advantage of + * this arrangement is that we save two multiplications per 1-D IDCT, + * because the y0 and y4 inputs need not be divided by sqrt(N). + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic. We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants). After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output. This division can be done + * cheaply as a right shift of CONST_BITS bits. We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision. These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling. (To scale up 12-bit sample data further, an + * intermediate int32 array would be needed.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis + * shows that the values given below are the most effective. + */ + +#ifdef EIGHT_BIT_SAMPLES +#define PASS1_BITS 2 +#else +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#endif + +#define ONE ((int32_t) 1) + +#define CONST_SCALE (ONE << CONST_BITS) + +/* Convert a positive real constant to an integer scaled by CONST_SCALE. + * IMPORTANT: if your compiler doesn't do this arithmetic at compile time, + * you will pay a significant penalty in run time. In that case, figure + * the correct integer constant values and insert them by hand. + */ + +/* Actually FIX is no longer used, we precomputed them all */ +#define FIX(x) ((int32_t) ((x) * CONST_SCALE + 0.5)) + +/* Descale and correctly round an int32_t value that's scaled by N bits. + * We assume RIGHT_SHIFT rounds towards minus infinity, so adding + * the fudge factor is correct for either sign of X. + */ + +#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) + +/* Multiply an int32_t variable by an int32_t constant to yield an int32_t result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply; + * this provides a useful speedup on many machines. + * There is no way to specify a 16x16->32 multiply in portable C, but + * some C compilers will do the right thing if you provide the correct + * combination of casts. + * NB: for 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#ifdef EIGHT_BIT_SAMPLES +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#define MULTIPLY(var,const) (((int16_t) (var)) * ((int16_t) (const))) +#endif +#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ +#define MULTIPLY(var,const) (((int16_t) (var)) * ((int32_t) (const))) +#endif +#endif + +#ifndef MULTIPLY /* default definition */ +#define MULTIPLY(var,const) ((var) * (const)) +#endif + + +/* + Unlike our decoder where we approximate the FIXes, we need to use exact +ones here or successive P-frames will drift too much with Reference frame coding +*/ +#define FIX_0_211164243 1730 +#define FIX_0_275899380 2260 +#define FIX_0_298631336 2446 +#define FIX_0_390180644 3196 +#define FIX_0_509795579 4176 +#define FIX_0_541196100 4433 +#define FIX_0_601344887 4926 +#define FIX_0_765366865 6270 +#define FIX_0_785694958 6436 +#define FIX_0_899976223 7373 +#define FIX_1_061594337 8697 +#define FIX_1_111140466 9102 +#define FIX_1_175875602 9633 +#define FIX_1_306562965 10703 +#define FIX_1_387039845 11363 +#define FIX_1_451774981 11893 +#define FIX_1_501321110 12299 +#define FIX_1_662939225 13623 +#define FIX_1_847759065 15137 +#define FIX_1_961570560 16069 +#define FIX_2_053119869 16819 +#define FIX_2_172734803 17799 +#define FIX_2_562915447 20995 +#define FIX_3_072711026 25172 + +/* + * Perform the inverse DCT on one block of coefficients. + */ + +void j_rev_dct(DCTBLOCK data) +{ + int32_t tmp0, tmp1, tmp2, tmp3; + int32_t tmp10, tmp11, tmp12, tmp13; + int32_t z1, z2, z3, z4, z5; + int32_t d0, d1, d2, d3, d4, d5, d6, d7; + register DCTELEM *dataptr; + int rowctr; + + /* Pass 1: process rows. */ + /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + dataptr = data; + + for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any row in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * row DCT calculations can be simplified this way. + */ + + register int *idataptr = (int*)dataptr; + + /* WARNING: we do the same permutation as MMX idct to simplify the + video core */ + d0 = dataptr[0]; + d2 = dataptr[1]; + d4 = dataptr[2]; + d6 = dataptr[3]; + d1 = dataptr[4]; + d3 = dataptr[5]; + d5 = dataptr[6]; + d7 = dataptr[7]; + + if ((d1 | d2 | d3 | d4 | d5 | d6 | d7) == 0) { + /* AC terms all zero */ + if (d0) { + /* Compute a 32 bit value to assign. */ + DCTELEM dcval = (DCTELEM) (d0 << PASS1_BITS); + register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000); + + idataptr[0] = v; + idataptr[1] = v; + idataptr[2] = v; + idataptr[3] = v; + } + + dataptr += DCTSIZE; /* advance pointer to next row */ + continue; + } + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ +{ + if (d6) { + if (d2) { + /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */ + z1 = MULTIPLY(d2 + d6, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065); + tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } else { + /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */ + tmp2 = MULTIPLY(-d6, FIX_1_306562965); + tmp3 = MULTIPLY(d6, FIX_0_541196100); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } + } else { + if (d2) { + /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */ + tmp2 = MULTIPLY(d2, FIX_0_541196100); + tmp3 = MULTIPLY(d2, FIX_1_306562965); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } else { + /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */ + tmp10 = tmp13 = (d0 + d4) << CONST_BITS; + tmp11 = tmp12 = (d0 - d4) << CONST_BITS; + } + } + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + + if (d7) { + if (d5) { + if (d3) { + if (d1) { + /* d1 != 0, d3 != 0, d5 != 0, d7 != 0 */ + z1 = d7 + d1; + z2 = d5 + d3; + z3 = d7 + d3; + z4 = d5 + d1; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); + + tmp0 = MULTIPLY(d7, FIX_0_298631336); + tmp1 = MULTIPLY(d5, FIX_2_053119869); + tmp2 = MULTIPLY(d3, FIX_3_072711026); + tmp3 = MULTIPLY(d1, FIX_1_501321110); + z1 = MULTIPLY(-z1, FIX_0_899976223); + z2 = MULTIPLY(-z2, FIX_2_562915447); + z3 = MULTIPLY(-z3, FIX_1_961570560); + z4 = MULTIPLY(-z4, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + } else { + /* d1 == 0, d3 != 0, d5 != 0, d7 != 0 */ + z2 = d5 + d3; + z3 = d7 + d3; + z5 = MULTIPLY(z3 + d5, FIX_1_175875602); + + tmp0 = MULTIPLY(d7, FIX_0_298631336); + tmp1 = MULTIPLY(d5, FIX_2_053119869); + tmp2 = MULTIPLY(d3, FIX_3_072711026); + z1 = MULTIPLY(-d7, FIX_0_899976223); + z2 = MULTIPLY(-z2, FIX_2_562915447); + z3 = MULTIPLY(-z3, FIX_1_961570560); + z4 = MULTIPLY(-d5, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 = z1 + z4; + } + } else { + if (d1) { + /* d1 != 0, d3 == 0, d5 != 0, d7 != 0 */ + z1 = d7 + d1; + z4 = d5 + d1; + z5 = MULTIPLY(d7 + z4, FIX_1_175875602); + + tmp0 = MULTIPLY(d7, FIX_0_298631336); + tmp1 = MULTIPLY(d5, FIX_2_053119869); + tmp3 = MULTIPLY(d1, FIX_1_501321110); + z1 = MULTIPLY(-z1, FIX_0_899976223); + z2 = MULTIPLY(-d5, FIX_2_562915447); + z3 = MULTIPLY(-d7, FIX_1_961570560); + z4 = MULTIPLY(-z4, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 = z2 + z3; + tmp3 += z1 + z4; + } else { + /* d1 == 0, d3 == 0, d5 != 0, d7 != 0 */ + tmp0 = MULTIPLY(-d7, FIX_0_601344887); + z1 = MULTIPLY(-d7, FIX_0_899976223); + z3 = MULTIPLY(-d7, FIX_1_961570560); + tmp1 = MULTIPLY(-d5, FIX_0_509795579); + z2 = MULTIPLY(-d5, FIX_2_562915447); + z4 = MULTIPLY(-d5, FIX_0_390180644); + z5 = MULTIPLY(d5 + d7, FIX_1_175875602); + + z3 += z5; + z4 += z5; + + tmp0 += z3; + tmp1 += z4; + tmp2 = z2 + z3; + tmp3 = z1 + z4; + } + } + } else { + if (d3) { + if (d1) { + /* d1 != 0, d3 != 0, d5 == 0, d7 != 0 */ + z1 = d7 + d1; + z3 = d7 + d3; + z5 = MULTIPLY(z3 + d1, FIX_1_175875602); + + tmp0 = MULTIPLY(d7, FIX_0_298631336); + tmp2 = MULTIPLY(d3, FIX_3_072711026); + tmp3 = MULTIPLY(d1, FIX_1_501321110); + z1 = MULTIPLY(-z1, FIX_0_899976223); + z2 = MULTIPLY(-d3, FIX_2_562915447); + z3 = MULTIPLY(-z3, FIX_1_961570560); + z4 = MULTIPLY(-d1, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 = z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + } else { + /* d1 == 0, d3 != 0, d5 == 0, d7 != 0 */ + z3 = d7 + d3; + + tmp0 = MULTIPLY(-d7, FIX_0_601344887); + z1 = MULTIPLY(-d7, FIX_0_899976223); + tmp2 = MULTIPLY(d3, FIX_0_509795579); + z2 = MULTIPLY(-d3, FIX_2_562915447); + z5 = MULTIPLY(z3, FIX_1_175875602); + z3 = MULTIPLY(-z3, FIX_0_785694958); + + tmp0 += z3; + tmp1 = z2 + z5; + tmp2 += z3; + tmp3 = z1 + z5; + } + } else { + if (d1) { + /* d1 != 0, d3 == 0, d5 == 0, d7 != 0 */ + z1 = d7 + d1; + z5 = MULTIPLY(z1, FIX_1_175875602); + + z1 = MULTIPLY(z1, FIX_0_275899380); + z3 = MULTIPLY(-d7, FIX_1_961570560); + tmp0 = MULTIPLY(-d7, FIX_1_662939225); + z4 = MULTIPLY(-d1, FIX_0_390180644); + tmp3 = MULTIPLY(d1, FIX_1_111140466); + + tmp0 += z1; + tmp1 = z4 + z5; + tmp2 = z3 + z5; + tmp3 += z1; + } else { + /* d1 == 0, d3 == 0, d5 == 0, d7 != 0 */ + tmp0 = MULTIPLY(-d7, FIX_1_387039845); + tmp1 = MULTIPLY(d7, FIX_1_175875602); + tmp2 = MULTIPLY(-d7, FIX_0_785694958); + tmp3 = MULTIPLY(d7, FIX_0_275899380); + } + } + } + } else { + if (d5) { + if (d3) { + if (d1) { + /* d1 != 0, d3 != 0, d5 != 0, d7 == 0 */ + z2 = d5 + d3; + z4 = d5 + d1; + z5 = MULTIPLY(d3 + z4, FIX_1_175875602); + + tmp1 = MULTIPLY(d5, FIX_2_053119869); + tmp2 = MULTIPLY(d3, FIX_3_072711026); + tmp3 = MULTIPLY(d1, FIX_1_501321110); + z1 = MULTIPLY(-d1, FIX_0_899976223); + z2 = MULTIPLY(-z2, FIX_2_562915447); + z3 = MULTIPLY(-d3, FIX_1_961570560); + z4 = MULTIPLY(-z4, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 = z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + } else { + /* d1 == 0, d3 != 0, d5 != 0, d7 == 0 */ + z2 = d5 + d3; + + z5 = MULTIPLY(z2, FIX_1_175875602); + tmp1 = MULTIPLY(d5, FIX_1_662939225); + z4 = MULTIPLY(-d5, FIX_0_390180644); + z2 = MULTIPLY(-z2, FIX_1_387039845); + tmp2 = MULTIPLY(d3, FIX_1_111140466); + z3 = MULTIPLY(-d3, FIX_1_961570560); + + tmp0 = z3 + z5; + tmp1 += z2; + tmp2 += z2; + tmp3 = z4 + z5; + } + } else { + if (d1) { + /* d1 != 0, d3 == 0, d5 != 0, d7 == 0 */ + z4 = d5 + d1; + + z5 = MULTIPLY(z4, FIX_1_175875602); + z1 = MULTIPLY(-d1, FIX_0_899976223); + tmp3 = MULTIPLY(d1, FIX_0_601344887); + tmp1 = MULTIPLY(-d5, FIX_0_509795579); + z2 = MULTIPLY(-d5, FIX_2_562915447); + z4 = MULTIPLY(z4, FIX_0_785694958); + + tmp0 = z1 + z5; + tmp1 += z4; + tmp2 = z2 + z5; + tmp3 += z4; + } else { + /* d1 == 0, d3 == 0, d5 != 0, d7 == 0 */ + tmp0 = MULTIPLY(d5, FIX_1_175875602); + tmp1 = MULTIPLY(d5, FIX_0_275899380); + tmp2 = MULTIPLY(-d5, FIX_1_387039845); + tmp3 = MULTIPLY(d5, FIX_0_785694958); + } + } + } else { + if (d3) { + if (d1) { + /* d1 != 0, d3 != 0, d5 == 0, d7 == 0 */ + z5 = d1 + d3; + tmp3 = MULTIPLY(d1, FIX_0_211164243); + tmp2 = MULTIPLY(-d3, FIX_1_451774981); + z1 = MULTIPLY(d1, FIX_1_061594337); + z2 = MULTIPLY(-d3, FIX_2_172734803); + z4 = MULTIPLY(z5, FIX_0_785694958); + z5 = MULTIPLY(z5, FIX_1_175875602); + + tmp0 = z1 - z4; + tmp1 = z2 + z4; + tmp2 += z5; + tmp3 += z5; + } else { + /* d1 == 0, d3 != 0, d5 == 0, d7 == 0 */ + tmp0 = MULTIPLY(-d3, FIX_0_785694958); + tmp1 = MULTIPLY(-d3, FIX_1_387039845); + tmp2 = MULTIPLY(-d3, FIX_0_275899380); + tmp3 = MULTIPLY(d3, FIX_1_175875602); + } + } else { + if (d1) { + /* d1 != 0, d3 == 0, d5 == 0, d7 == 0 */ + tmp0 = MULTIPLY(d1, FIX_0_275899380); + tmp1 = MULTIPLY(d1, FIX_0_785694958); + tmp2 = MULTIPLY(d1, FIX_1_175875602); + tmp3 = MULTIPLY(d1, FIX_1_387039845); + } else { + /* d1 == 0, d3 == 0, d5 == 0, d7 == 0 */ + tmp0 = tmp1 = tmp2 = tmp3 = 0; + } + } + } + } +} + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + dataptr[0] = (DCTELEM) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS); + dataptr[7] = (DCTELEM) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS); + dataptr[1] = (DCTELEM) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS); + dataptr[6] = (DCTELEM) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS); + dataptr[2] = (DCTELEM) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS); + dataptr[5] = (DCTELEM) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS); + dataptr[3] = (DCTELEM) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS); + dataptr[4] = (DCTELEM) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS); + + dataptr += DCTSIZE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + dataptr = data; + for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) { + /* Columns of zeroes can be exploited in the same way as we did with rows. + * However, the row calculation has created many nonzero AC terms, so the + * simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + + d0 = dataptr[DCTSIZE*0]; + d1 = dataptr[DCTSIZE*1]; + d2 = dataptr[DCTSIZE*2]; + d3 = dataptr[DCTSIZE*3]; + d4 = dataptr[DCTSIZE*4]; + d5 = dataptr[DCTSIZE*5]; + d6 = dataptr[DCTSIZE*6]; + d7 = dataptr[DCTSIZE*7]; + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + if (d6) { + if (d2) { + /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */ + z1 = MULTIPLY(d2 + d6, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065); + tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } else { + /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */ + tmp2 = MULTIPLY(-d6, FIX_1_306562965); + tmp3 = MULTIPLY(d6, FIX_0_541196100); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } + } else { + if (d2) { + /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */ + tmp2 = MULTIPLY(d2, FIX_0_541196100); + tmp3 = MULTIPLY(d2, FIX_1_306562965); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } else { + /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */ + tmp10 = tmp13 = (d0 + d4) << CONST_BITS; + tmp11 = tmp12 = (d0 - d4) << CONST_BITS; + } + } + + /* Odd part per figure 8; the matrix is unitary and hence its + * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. + */ + if (d7) { + if (d5) { + if (d3) { + if (d1) { + /* d1 != 0, d3 != 0, d5 != 0, d7 != 0 */ + z1 = d7 + d1; + z2 = d5 + d3; + z3 = d7 + d3; + z4 = d5 + d1; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); + + tmp0 = MULTIPLY(d7, FIX_0_298631336); + tmp1 = MULTIPLY(d5, FIX_2_053119869); + tmp2 = MULTIPLY(d3, FIX_3_072711026); + tmp3 = MULTIPLY(d1, FIX_1_501321110); + z1 = MULTIPLY(-z1, FIX_0_899976223); + z2 = MULTIPLY(-z2, FIX_2_562915447); + z3 = MULTIPLY(-z3, FIX_1_961570560); + z4 = MULTIPLY(-z4, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + } else { + /* d1 == 0, d3 != 0, d5 != 0, d7 != 0 */ + z1 = d7; + z2 = d5 + d3; + z3 = d7 + d3; + z5 = MULTIPLY(z3 + d5, FIX_1_175875602); + + tmp0 = MULTIPLY(d7, FIX_0_298631336); + tmp1 = MULTIPLY(d5, FIX_2_053119869); + tmp2 = MULTIPLY(d3, FIX_3_072711026); + z1 = MULTIPLY(-d7, FIX_0_899976223); + z2 = MULTIPLY(-z2, FIX_2_562915447); + z3 = MULTIPLY(-z3, FIX_1_961570560); + z4 = MULTIPLY(-d5, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 = z1 + z4; + } + } else { + if (d1) { + /* d1 != 0, d3 == 0, d5 != 0, d7 != 0 */ + z1 = d7 + d1; + z2 = d5; + z3 = d7; + z4 = d5 + d1; + z5 = MULTIPLY(z3 + z4, FIX_1_175875602); + + tmp0 = MULTIPLY(d7, FIX_0_298631336); + tmp1 = MULTIPLY(d5, FIX_2_053119869); + tmp3 = MULTIPLY(d1, FIX_1_501321110); + z1 = MULTIPLY(-z1, FIX_0_899976223); + z2 = MULTIPLY(-d5, FIX_2_562915447); + z3 = MULTIPLY(-d7, FIX_1_961570560); + z4 = MULTIPLY(-z4, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 += z2 + z4; + tmp2 = z2 + z3; + tmp3 += z1 + z4; + } else { + /* d1 == 0, d3 == 0, d5 != 0, d7 != 0 */ + tmp0 = MULTIPLY(-d7, FIX_0_601344887); + z1 = MULTIPLY(-d7, FIX_0_899976223); + z3 = MULTIPLY(-d7, FIX_1_961570560); + tmp1 = MULTIPLY(-d5, FIX_0_509795579); + z2 = MULTIPLY(-d5, FIX_2_562915447); + z4 = MULTIPLY(-d5, FIX_0_390180644); + z5 = MULTIPLY(d5 + d7, FIX_1_175875602); + + z3 += z5; + z4 += z5; + + tmp0 += z3; + tmp1 += z4; + tmp2 = z2 + z3; + tmp3 = z1 + z4; + } + } + } else { + if (d3) { + if (d1) { + /* d1 != 0, d3 != 0, d5 == 0, d7 != 0 */ + z1 = d7 + d1; + z3 = d7 + d3; + z5 = MULTIPLY(z3 + d1, FIX_1_175875602); + + tmp0 = MULTIPLY(d7, FIX_0_298631336); + tmp2 = MULTIPLY(d3, FIX_3_072711026); + tmp3 = MULTIPLY(d1, FIX_1_501321110); + z1 = MULTIPLY(-z1, FIX_0_899976223); + z2 = MULTIPLY(-d3, FIX_2_562915447); + z3 = MULTIPLY(-z3, FIX_1_961570560); + z4 = MULTIPLY(-d1, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 += z1 + z3; + tmp1 = z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + } else { + /* d1 == 0, d3 != 0, d5 == 0, d7 != 0 */ + z3 = d7 + d3; + + tmp0 = MULTIPLY(-d7, FIX_0_601344887); + z1 = MULTIPLY(-d7, FIX_0_899976223); + tmp2 = MULTIPLY(d3, FIX_0_509795579); + z2 = MULTIPLY(-d3, FIX_2_562915447); + z5 = MULTIPLY(z3, FIX_1_175875602); + z3 = MULTIPLY(-z3, FIX_0_785694958); + + tmp0 += z3; + tmp1 = z2 + z5; + tmp2 += z3; + tmp3 = z1 + z5; + } + } else { + if (d1) { + /* d1 != 0, d3 == 0, d5 == 0, d7 != 0 */ + z1 = d7 + d1; + z5 = MULTIPLY(z1, FIX_1_175875602); + + z1 = MULTIPLY(z1, FIX_0_275899380); + z3 = MULTIPLY(-d7, FIX_1_961570560); + tmp0 = MULTIPLY(-d7, FIX_1_662939225); + z4 = MULTIPLY(-d1, FIX_0_390180644); + tmp3 = MULTIPLY(d1, FIX_1_111140466); + + tmp0 += z1; + tmp1 = z4 + z5; + tmp2 = z3 + z5; + tmp3 += z1; + } else { + /* d1 == 0, d3 == 0, d5 == 0, d7 != 0 */ + tmp0 = MULTIPLY(-d7, FIX_1_387039845); + tmp1 = MULTIPLY(d7, FIX_1_175875602); + tmp2 = MULTIPLY(-d7, FIX_0_785694958); + tmp3 = MULTIPLY(d7, FIX_0_275899380); + } + } + } + } else { + if (d5) { + if (d3) { + if (d1) { + /* d1 != 0, d3 != 0, d5 != 0, d7 == 0 */ + z2 = d5 + d3; + z4 = d5 + d1; + z5 = MULTIPLY(d3 + z4, FIX_1_175875602); + + tmp1 = MULTIPLY(d5, FIX_2_053119869); + tmp2 = MULTIPLY(d3, FIX_3_072711026); + tmp3 = MULTIPLY(d1, FIX_1_501321110); + z1 = MULTIPLY(-d1, FIX_0_899976223); + z2 = MULTIPLY(-z2, FIX_2_562915447); + z3 = MULTIPLY(-d3, FIX_1_961570560); + z4 = MULTIPLY(-z4, FIX_0_390180644); + + z3 += z5; + z4 += z5; + + tmp0 = z1 + z3; + tmp1 += z2 + z4; + tmp2 += z2 + z3; + tmp3 += z1 + z4; + } else { + /* d1 == 0, d3 != 0, d5 != 0, d7 == 0 */ + z2 = d5 + d3; + + z5 = MULTIPLY(z2, FIX_1_175875602); + tmp1 = MULTIPLY(d5, FIX_1_662939225); + z4 = MULTIPLY(-d5, FIX_0_390180644); + z2 = MULTIPLY(-z2, FIX_1_387039845); + tmp2 = MULTIPLY(d3, FIX_1_111140466); + z3 = MULTIPLY(-d3, FIX_1_961570560); + + tmp0 = z3 + z5; + tmp1 += z2; + tmp2 += z2; + tmp3 = z4 + z5; + } + } else { + if (d1) { + /* d1 != 0, d3 == 0, d5 != 0, d7 == 0 */ + z4 = d5 + d1; + + z5 = MULTIPLY(z4, FIX_1_175875602); + z1 = MULTIPLY(-d1, FIX_0_899976223); + tmp3 = MULTIPLY(d1, FIX_0_601344887); + tmp1 = MULTIPLY(-d5, FIX_0_509795579); + z2 = MULTIPLY(-d5, FIX_2_562915447); + z4 = MULTIPLY(z4, FIX_0_785694958); + + tmp0 = z1 + z5; + tmp1 += z4; + tmp2 = z2 + z5; + tmp3 += z4; + } else { + /* d1 == 0, d3 == 0, d5 != 0, d7 == 0 */ + tmp0 = MULTIPLY(d5, FIX_1_175875602); + tmp1 = MULTIPLY(d5, FIX_0_275899380); + tmp2 = MULTIPLY(-d5, FIX_1_387039845); + tmp3 = MULTIPLY(d5, FIX_0_785694958); + } + } + } else { + if (d3) { + if (d1) { + /* d1 != 0, d3 != 0, d5 == 0, d7 == 0 */ + z5 = d1 + d3; + tmp3 = MULTIPLY(d1, FIX_0_211164243); + tmp2 = MULTIPLY(-d3, FIX_1_451774981); + z1 = MULTIPLY(d1, FIX_1_061594337); + z2 = MULTIPLY(-d3, FIX_2_172734803); + z4 = MULTIPLY(z5, FIX_0_785694958); + z5 = MULTIPLY(z5, FIX_1_175875602); + + tmp0 = z1 - z4; + tmp1 = z2 + z4; + tmp2 += z5; + tmp3 += z5; + } else { + /* d1 == 0, d3 != 0, d5 == 0, d7 == 0 */ + tmp0 = MULTIPLY(-d3, FIX_0_785694958); + tmp1 = MULTIPLY(-d3, FIX_1_387039845); + tmp2 = MULTIPLY(-d3, FIX_0_275899380); + tmp3 = MULTIPLY(d3, FIX_1_175875602); + } + } else { + if (d1) { + /* d1 != 0, d3 == 0, d5 == 0, d7 == 0 */ + tmp0 = MULTIPLY(d1, FIX_0_275899380); + tmp1 = MULTIPLY(d1, FIX_0_785694958); + tmp2 = MULTIPLY(d1, FIX_1_175875602); + tmp3 = MULTIPLY(d1, FIX_1_387039845); + } else { + /* d1 == 0, d3 == 0, d5 == 0, d7 == 0 */ + tmp0 = tmp1 = tmp2 = tmp3 = 0; + } + } + } + } + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp3, + CONST_BITS+PASS1_BITS+3); + dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp10 - tmp3, + CONST_BITS+PASS1_BITS+3); + dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp11 + tmp2, + CONST_BITS+PASS1_BITS+3); + dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(tmp11 - tmp2, + CONST_BITS+PASS1_BITS+3); + dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(tmp12 + tmp1, + CONST_BITS+PASS1_BITS+3); + dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp12 - tmp1, + CONST_BITS+PASS1_BITS+3); + dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp13 + tmp0, + CONST_BITS+PASS1_BITS+3); + dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp13 - tmp0, + CONST_BITS+PASS1_BITS+3); + + dataptr++; /* advance pointer to next column */ + } +} + +#undef DCTSIZE +#define DCTSIZE 4 +#define DCTSTRIDE 8 + +void j_rev_dct4(DCTBLOCK data) +{ + int32_t tmp0, tmp1, tmp2, tmp3; + int32_t tmp10, tmp11, tmp12, tmp13; + int32_t z1; + int32_t d0, d2, d4, d6; + register DCTELEM *dataptr; + int rowctr; + + /* Pass 1: process rows. */ + /* Note results are scaled up by sqrt(8) compared to a true IDCT; */ + /* furthermore, we scale the results by 2**PASS1_BITS. */ + + data[0] += 4; + + dataptr = data; + + for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) { + /* Due to quantization, we will usually find that many of the input + * coefficients are zero, especially the AC terms. We can exploit this + * by short-circuiting the IDCT calculation for any row in which all + * the AC terms are zero. In that case each output is equal to the + * DC coefficient (with scale factor as needed). + * With typical images and quantization tables, half or more of the + * row DCT calculations can be simplified this way. + */ + + register int *idataptr = (int*)dataptr; + + d0 = dataptr[0]; + d2 = dataptr[1]; + d4 = dataptr[2]; + d6 = dataptr[3]; + + if ((d2 | d4 | d6) == 0) { + /* AC terms all zero */ + if (d0) { + /* Compute a 32 bit value to assign. */ + DCTELEM dcval = (DCTELEM) (d0 << PASS1_BITS); + register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000); + + idataptr[0] = v; + idataptr[1] = v; + } + + dataptr += DCTSTRIDE; /* advance pointer to next row */ + continue; + } + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + if (d6) { + if (d2) { + /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */ + z1 = MULTIPLY(d2 + d6, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065); + tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } else { + /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */ + tmp2 = MULTIPLY(-d6, FIX_1_306562965); + tmp3 = MULTIPLY(d6, FIX_0_541196100); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } + } else { + if (d2) { + /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */ + tmp2 = MULTIPLY(d2, FIX_0_541196100); + tmp3 = MULTIPLY(d2, FIX_1_306562965); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } else { + /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */ + tmp10 = tmp13 = (d0 + d4) << CONST_BITS; + tmp11 = tmp12 = (d0 - d4) << CONST_BITS; + } + } + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + dataptr[0] = (DCTELEM) DESCALE(tmp10, CONST_BITS-PASS1_BITS); + dataptr[1] = (DCTELEM) DESCALE(tmp11, CONST_BITS-PASS1_BITS); + dataptr[2] = (DCTELEM) DESCALE(tmp12, CONST_BITS-PASS1_BITS); + dataptr[3] = (DCTELEM) DESCALE(tmp13, CONST_BITS-PASS1_BITS); + + dataptr += DCTSTRIDE; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + /* Note that we must descale the results by a factor of 8 == 2**3, */ + /* and also undo the PASS1_BITS scaling. */ + + dataptr = data; + for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) { + /* Columns of zeroes can be exploited in the same way as we did with rows. + * However, the row calculation has created many nonzero AC terms, so the + * simplification applies less often (typically 5% to 10% of the time). + * On machines with very fast multiplication, it's possible that the + * test takes more time than it's worth. In that case this section + * may be commented out. + */ + + d0 = dataptr[DCTSTRIDE*0]; + d2 = dataptr[DCTSTRIDE*1]; + d4 = dataptr[DCTSTRIDE*2]; + d6 = dataptr[DCTSTRIDE*3]; + + /* Even part: reverse the even part of the forward DCT. */ + /* The rotator is sqrt(2)*c(-6). */ + if (d6) { + if (d2) { + /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */ + z1 = MULTIPLY(d2 + d6, FIX_0_541196100); + tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065); + tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } else { + /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */ + tmp2 = MULTIPLY(-d6, FIX_1_306562965); + tmp3 = MULTIPLY(d6, FIX_0_541196100); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } + } else { + if (d2) { + /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */ + tmp2 = MULTIPLY(d2, FIX_0_541196100); + tmp3 = MULTIPLY(d2, FIX_1_306562965); + + tmp0 = (d0 + d4) << CONST_BITS; + tmp1 = (d0 - d4) << CONST_BITS; + + tmp10 = tmp0 + tmp3; + tmp13 = tmp0 - tmp3; + tmp11 = tmp1 + tmp2; + tmp12 = tmp1 - tmp2; + } else { + /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */ + tmp10 = tmp13 = (d0 + d4) << CONST_BITS; + tmp11 = tmp12 = (d0 - d4) << CONST_BITS; + } + } + + /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ + + dataptr[DCTSTRIDE*0] = tmp10 >> (CONST_BITS+PASS1_BITS+3); + dataptr[DCTSTRIDE*1] = tmp11 >> (CONST_BITS+PASS1_BITS+3); + dataptr[DCTSTRIDE*2] = tmp12 >> (CONST_BITS+PASS1_BITS+3); + dataptr[DCTSTRIDE*3] = tmp13 >> (CONST_BITS+PASS1_BITS+3); + + dataptr++; /* advance pointer to next column */ + } +} + +void j_rev_dct2(DCTBLOCK data){ + int d00, d01, d10, d11; + + data[0] += 4; + d00 = data[0+0*DCTSTRIDE] + data[1+0*DCTSTRIDE]; + d01 = data[0+0*DCTSTRIDE] - data[1+0*DCTSTRIDE]; + d10 = data[0+1*DCTSTRIDE] + data[1+1*DCTSTRIDE]; + d11 = data[0+1*DCTSTRIDE] - data[1+1*DCTSTRIDE]; + + data[0+0*DCTSTRIDE]= (d00 + d10)>>3; + data[1+0*DCTSTRIDE]= (d01 + d11)>>3; + data[0+1*DCTSTRIDE]= (d00 - d10)>>3; + data[1+1*DCTSTRIDE]= (d01 - d11)>>3; +} + +void j_rev_dct1(DCTBLOCK data){ + data[0] = (data[0] + 4)>>3; +} + +#undef FIX +#undef CONST_BITS diff --git a/mpeg4/src/libavcodec/kmvc.c b/mpeg4/src/libavcodec/kmvc.c new file mode 100644 index 00000000..333c909a --- /dev/null +++ b/mpeg4/src/libavcodec/kmvc.c @@ -0,0 +1,394 @@ +/* + * KMVC decoder + * Copyright (c) 2006 Konstantin Shishkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file kmvc.c + * Karl Morton's Video Codec decoder + */ + +#include +#include + +#include "common.h" +#include "avcodec.h" + +#define KMVC_KEYFRAME 0x80 +#define KMVC_PALETTE 0x40 +#define KMVC_METHOD 0x0F + +/* + * Decoder context + */ +typedef struct KmvcContext { + AVCodecContext *avctx; + AVFrame pic; + + int setpal; + int palsize; + uint32_t pal[256]; + uint8_t *cur, *prev; + uint8_t *frm0, *frm1; +} KmvcContext; + +typedef struct BitBuf { + int bits; + int bitbuf; +} BitBuf; + +#define BLK(data, x, y) data[(x) + (y) * 320] + +#define kmvc_init_getbits(bb, src) bb.bits = 7; bb.bitbuf = *src++; + +#define kmvc_getbit(bb, src, res) {\ + res = 0; \ + if (bb.bitbuf & (1 << bb.bits)) res = 1; \ + bb.bits--; \ + if(bb.bits == -1) { \ + bb.bitbuf = *src++; \ + bb.bits = 7; \ + } \ +} + +static void kmvc_decode_intra_8x8(KmvcContext * ctx, uint8_t * src, int w, int h) +{ + BitBuf bb; + int res, val; + int i, j; + int bx, by; + int l0x, l1x, l0y, l1y; + int mx, my; + + kmvc_init_getbits(bb, src); + + for (by = 0; by < h; by += 8) + for (bx = 0; bx < w; bx += 8) { + kmvc_getbit(bb, src, res); + if (!res) { // fill whole 8x8 block + val = *src++; + for (i = 0; i < 64; i++) + BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val; + } else { // handle four 4x4 subblocks + for (i = 0; i < 4; i++) { + l0x = bx + (i & 1) * 4; + l0y = by + (i & 2) * 2; + kmvc_getbit(bb, src, res); + if (!res) { + kmvc_getbit(bb, src, res); + if (!res) { // fill whole 4x4 block + val = *src++; + for (j = 0; j < 16; j++) + BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val; + } else { // copy block from already decoded place + val = *src++; + mx = val & 0xF; + my = val >> 4; + for (j = 0; j < 16; j++) + BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = + BLK(ctx->cur, l0x + (j & 3) - mx, l0y + (j >> 2) - my); + } + } else { // descend to 2x2 sub-sub-blocks + for (j = 0; j < 4; j++) { + l1x = l0x + (j & 1) * 2; + l1y = l0y + (j & 2); + kmvc_getbit(bb, src, res); + if (!res) { + kmvc_getbit(bb, src, res); + if (!res) { // fill whole 2x2 block + val = *src++; + BLK(ctx->cur, l1x, l1y) = val; + BLK(ctx->cur, l1x + 1, l1y) = val; + BLK(ctx->cur, l1x, l1y + 1) = val; + BLK(ctx->cur, l1x + 1, l1y + 1) = val; + } else { // copy block from already decoded place + val = *src++; + mx = val & 0xF; + my = val >> 4; + BLK(ctx->cur, l1x, l1y) = BLK(ctx->cur, l1x - mx, l1y - my); + BLK(ctx->cur, l1x + 1, l1y) = + BLK(ctx->cur, l1x + 1 - mx, l1y - my); + BLK(ctx->cur, l1x, l1y + 1) = + BLK(ctx->cur, l1x - mx, l1y + 1 - my); + BLK(ctx->cur, l1x + 1, l1y + 1) = + BLK(ctx->cur, l1x + 1 - mx, l1y + 1 - my); + } + } else { // read values for block + BLK(ctx->cur, l1x, l1y) = *src++; + BLK(ctx->cur, l1x + 1, l1y) = *src++; + BLK(ctx->cur, l1x, l1y + 1) = *src++; + BLK(ctx->cur, l1x + 1, l1y + 1) = *src++; + } + } + } + } + } + } +} + +static void kmvc_decode_inter_8x8(KmvcContext * ctx, uint8_t * src, int w, int h) +{ + BitBuf bb; + int res, val; + int i, j; + int bx, by; + int l0x, l1x, l0y, l1y; + int mx, my; + + kmvc_init_getbits(bb, src); + + for (by = 0; by < h; by += 8) + for (bx = 0; bx < w; bx += 8) { + kmvc_getbit(bb, src, res); + if (!res) { + kmvc_getbit(bb, src, res); + if (!res) { // fill whole 8x8 block + val = *src++; + for (i = 0; i < 64; i++) + BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val; + } else { // copy block from previous frame + for (i = 0; i < 64; i++) + BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = + BLK(ctx->prev, bx + (i & 0x7), by + (i >> 3)); + } + } else { // handle four 4x4 subblocks + for (i = 0; i < 4; i++) { + l0x = bx + (i & 1) * 4; + l0y = by + (i & 2) * 2; + kmvc_getbit(bb, src, res); + if (!res) { + kmvc_getbit(bb, src, res); + if (!res) { // fill whole 4x4 block + val = *src++; + for (j = 0; j < 16; j++) + BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val; + } else { // copy block + val = *src++; + mx = (val & 0xF) - 8; + my = (val >> 4) - 8; + for (j = 0; j < 16; j++) + BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = + BLK(ctx->prev, l0x + (j & 3) + mx, l0y + (j >> 2) + my); + } + } else { // descend to 2x2 sub-sub-blocks + for (j = 0; j < 4; j++) { + l1x = l0x + (j & 1) * 2; + l1y = l0y + (j & 2); + kmvc_getbit(bb, src, res); + if (!res) { + kmvc_getbit(bb, src, res); + if (!res) { // fill whole 2x2 block + val = *src++; + BLK(ctx->cur, l1x, l1y) = val; + BLK(ctx->cur, l1x + 1, l1y) = val; + BLK(ctx->cur, l1x, l1y + 1) = val; + BLK(ctx->cur, l1x + 1, l1y + 1) = val; + } else { // copy block + val = *src++; + mx = (val & 0xF) - 8; + my = (val >> 4) - 8; + BLK(ctx->cur, l1x, l1y) = BLK(ctx->prev, l1x + mx, l1y + my); + BLK(ctx->cur, l1x + 1, l1y) = + BLK(ctx->prev, l1x + 1 + mx, l1y + my); + BLK(ctx->cur, l1x, l1y + 1) = + BLK(ctx->prev, l1x + mx, l1y + 1 + my); + BLK(ctx->cur, l1x + 1, l1y + 1) = + BLK(ctx->prev, l1x + 1 + mx, l1y + 1 + my); + } + } else { // read values for block + BLK(ctx->cur, l1x, l1y) = *src++; + BLK(ctx->cur, l1x + 1, l1y) = *src++; + BLK(ctx->cur, l1x, l1y + 1) = *src++; + BLK(ctx->cur, l1x + 1, l1y + 1) = *src++; + } + } + } + } + } + } +} + +static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t * buf, + int buf_size) +{ + KmvcContext *const ctx = (KmvcContext *) avctx->priv_data; + uint8_t *out, *src; + int i; + int header; + int blocksize; + + if (ctx->pic.data[0]) + avctx->release_buffer(avctx, &ctx->pic); + + ctx->pic.reference = 1; + ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID; + if (avctx->get_buffer(avctx, &ctx->pic) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + header = buf[0]; + buf++; + + if (header & KMVC_KEYFRAME) { + ctx->pic.key_frame = 1; + ctx->pic.pict_type = FF_I_TYPE; + } else { + ctx->pic.key_frame = 0; + ctx->pic.pict_type = FF_P_TYPE; + } + + if (header & KMVC_PALETTE) { + ctx->pic.palette_has_changed = 1; + // palette starts from index 1 and has 127 entries + for (i = 1; i <= ctx->palsize; i++) { + ctx->pal[i] = (buf[0] << 16) | (buf[1] << 8) | buf[2]; + buf += 3; + } + } + + if (ctx->setpal) { + ctx->setpal = 0; + ctx->pic.palette_has_changed = 1; + } + + /* make the palette available on the way out */ + memcpy(ctx->pic.data[1], ctx->pal, 1024); + + blocksize = *buf++; + + if (blocksize != 8) { + av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize); + return -1; + } + memset(ctx->cur, 0, 320 * 200); + switch (header & KMVC_METHOD) { + case 3: + kmvc_decode_intra_8x8(ctx, buf, avctx->width, avctx->height); + break; + case 4: + kmvc_decode_inter_8x8(ctx, buf, avctx->width, avctx->height); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD); + return -1; + } + + out = ctx->pic.data[0]; + src = ctx->cur; + for (i = 0; i < avctx->height; i++) { + memcpy(out, src, avctx->width); + src += 320; + out += ctx->pic.linesize[0]; + } + + /* flip buffers */ + if (ctx->cur == ctx->frm0) { + ctx->cur = ctx->frm1; + ctx->prev = ctx->frm0; + } else { + ctx->cur = ctx->frm0; + ctx->prev = ctx->frm1; + } + + *data_size = sizeof(AVFrame); + *(AVFrame *) data = ctx->pic; + + /* always report that the buffer was completely consumed */ + return buf_size; +} + + + +/* + * Init kmvc decoder + */ +static int decode_init(AVCodecContext * avctx) +{ + KmvcContext *const c = (KmvcContext *) avctx->priv_data; + int i; + + c->avctx = avctx; + avctx->has_b_frames = 0; + + c->pic.data[0] = NULL; + + if (avctx->width > 320 || avctx->height > 200) { + av_log(avctx, AV_LOG_ERROR, "KMVC supports frames <= 320x200\n"); + return -1; + } + + c->frm0 = av_mallocz(320 * 200); + c->frm1 = av_mallocz(320 * 200); + c->cur = c->frm0; + c->prev = c->frm1; + + for (i = 0; i < 256; i++) { + c->pal[i] = i * 0x10101; + } + + if (avctx->extradata_size < 12) { + av_log(NULL, 0, "Extradata missing, decoding may not work properly...\n"); + c->palsize = 127; + } else { + c->palsize = LE_16(avctx->extradata + 10); + } + + if (avctx->extradata_size == 1036) { // palette in extradata + uint8_t *src = avctx->extradata + 12; + for (i = 0; i < c->palsize; i++) { + c->pal[i] = LE_32(src); + src += 4; + } + c->setpal = 1; + } + + avctx->pix_fmt = PIX_FMT_PAL8; + + return 0; +} + + + +/* + * Uninit kmvc decoder + */ +static int decode_end(AVCodecContext * avctx) +{ + KmvcContext *const c = (KmvcContext *) avctx->priv_data; + + if (c->frm0) + av_free(c->frm0); + if (c->frm1) + av_free(c->frm1); + if (c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + + return 0; +} + +AVCodec kmvc_decoder = { + "kmvc", + CODEC_TYPE_VIDEO, + CODEC_ID_KMVC, + sizeof(KmvcContext), + decode_init, + NULL, + decode_end, + decode_frame +}; diff --git a/mpeg4/src/libavcodec/lcl.c b/mpeg4/src/libavcodec/lcl.c new file mode 100644 index 00000000..0bc118af --- /dev/null +++ b/mpeg4/src/libavcodec/lcl.c @@ -0,0 +1,922 @@ +/* + * LCL (LossLess Codec Library) Codec + * Copyright (c) 2002-2004 Roberto Togni + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/** + * @file lcl.c + * LCL (LossLess Codec Library) Video Codec + * Decoder for MSZH and ZLIB codecs + * Experimental encoder for ZLIB RGB24 + * + * Fourcc: MSZH, ZLIB + * + * Original Win32 dll: + * Ver2.23 By Kenji Oshima 2000.09.20 + * avimszh.dll, avizlib.dll + * + * A description of the decoding algorithm can be found here: + * http://www.pcisys.net/~melanson/codecs + * + * Supports: BGR24 (RGB 24bpp) + * + */ + +#include +#include + +#include "common.h" +#include "bitstream.h" +#include "avcodec.h" + +#ifdef CONFIG_ZLIB +#include +#endif + + +#define BMPTYPE_YUV 1 +#define BMPTYPE_RGB 2 + +#define IMGTYPE_YUV111 0 +#define IMGTYPE_YUV422 1 +#define IMGTYPE_RGB24 2 +#define IMGTYPE_YUV411 3 +#define IMGTYPE_YUV211 4 +#define IMGTYPE_YUV420 5 + +#define COMP_MSZH 0 +#define COMP_MSZH_NOCOMP 1 +#define COMP_ZLIB_HISPEED 1 +#define COMP_ZLIB_HICOMP 9 +#define COMP_ZLIB_NORMAL -1 + +#define FLAG_MULTITHREAD 1 +#define FLAG_NULLFRAME 2 +#define FLAG_PNGFILTER 4 +#define FLAGMASK_UNUSED 0xf8 + +#define CODEC_MSZH 1 +#define CODEC_ZLIB 3 + +#define FOURCC_MSZH mmioFOURCC('M','S','Z','H') +#define FOURCC_ZLIB mmioFOURCC('Z','L','I','B') + +/* + * Decoder context + */ +typedef struct LclContext { + + AVCodecContext *avctx; + AVFrame pic; + PutBitContext pb; + + // Image type + int imgtype; + // Compression type + int compression; + // Flags + int flags; + // Decompressed data size + unsigned int decomp_size; + // Decompression buffer + unsigned char* decomp_buf; + // Maximum compressed data size + unsigned int max_comp_size; + // Compression buffer + unsigned char* comp_buf; +#ifdef CONFIG_ZLIB + z_stream zstream; +#endif +} LclContext; + + +/* + * + * Helper functions + * + */ +static inline unsigned char fix (int pix14) +{ + int tmp; + + tmp = (pix14 + 0x80000) >> 20; + if (tmp < 0) + return 0; + if (tmp > 255) + return 255; + return tmp; +} + + + +static inline unsigned char get_b (unsigned char yq, signed char bq) +{ + return fix((yq << 20) + bq * 1858076); +} + + + +static inline unsigned char get_g (unsigned char yq, signed char bq, signed char rq) +{ + return fix((yq << 20) - bq * 360857 - rq * 748830); +} + + + +static inline unsigned char get_r (unsigned char yq, signed char rq) +{ + return fix((yq << 20) + rq * 1470103); +} + + + +static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) +{ + unsigned char *destptr_bak = destptr; + unsigned char *destptr_end = destptr + destsize; + unsigned char mask = 0; + unsigned char maskbit = 0; + unsigned int ofs, cnt; + + while ((srclen > 0) && (destptr < destptr_end)) { + if (maskbit == 0) { + mask = *(srcptr++); + maskbit = 8; + srclen--; + continue; + } + if ((mask & (1 << (--maskbit))) == 0) { + if (destptr + 4 > destptr_end) + break; + *(int*)destptr = *(int*)srcptr; + srclen -= 4; + destptr += 4; + srcptr += 4; + } else { + ofs = *(srcptr++); + cnt = *(srcptr++); + ofs += cnt * 256;; + cnt = ((cnt >> 3) & 0x1f) + 1; + ofs &= 0x7ff; + srclen -= 2; + cnt *= 4; + if (destptr + cnt > destptr_end) { + cnt = destptr_end - destptr; + } + for (; cnt > 0; cnt--) { + *(destptr) = *(destptr - ofs); + destptr++; + } + } + } + + return (destptr - destptr_bak); +} + + + + +/* + * + * Decode a frame + * + */ +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) +{ + LclContext * const c = (LclContext *)avctx->priv_data; + unsigned char *encoded = (unsigned char *)buf; + unsigned int pixel_ptr; + int row, col; + unsigned char *outptr; + unsigned int width = avctx->width; // Real image width + unsigned int height = avctx->height; // Real image height + unsigned int mszh_dlen; + unsigned char yq, y1q, uq, vq; + int uqvq; + unsigned int mthread_inlen, mthread_outlen; +#ifdef CONFIG_ZLIB + int zret; // Zlib return code +#endif + unsigned int len = buf_size; + + if(c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); + + c->pic.reference = 0; + c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; + if(avctx->get_buffer(avctx, &c->pic) < 0){ + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return -1; + } + + outptr = c->pic.data[0]; // Output image pointer + + /* Decompress frame */ + switch (avctx->codec_id) { + case CODEC_ID_MSZH: + switch (c->compression) { + case COMP_MSZH: + if (c->flags & FLAG_MULTITHREAD) { + mthread_inlen = *((unsigned int*)encoded); + mthread_outlen = *((unsigned int*)(encoded+4)); + if (mthread_outlen > c->decomp_size) // this should not happen + mthread_outlen = c->decomp_size; + mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size); + if (mthread_outlen != mszh_dlen) { + av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", + mthread_outlen, mszh_dlen); + return -1; + } + mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen, + c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); + if (mthread_outlen != mszh_dlen) { + av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", + mthread_outlen, mszh_dlen); + return -1; + } + encoded = c->decomp_buf; + len = c->decomp_size; + } else { + mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); + if (c->decomp_size != mszh_dlen) { + av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", + c->decomp_size, mszh_dlen); + return -1; + } + encoded = c->decomp_buf; + len = mszh_dlen; + } + break; + case COMP_MSZH_NOCOMP: + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); + return -1; + } + break; + case CODEC_ID_ZLIB: +#ifdef CONFIG_ZLIB + /* Using the original dll with normal compression (-1) and RGB format + * gives a file with ZLIB fourcc, but frame is really uncompressed. + * To be sure that's true check also frame size */ + if ((c->compression == COMP_ZLIB_NORMAL) && (c->imgtype == IMGTYPE_RGB24) && + (len == width * height * 3)) + break; + zret = inflateReset(&(c->zstream)); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); + return -1; + } + if (c->flags & FLAG_MULTITHREAD) { + mthread_inlen = *((unsigned int*)encoded); + mthread_outlen = *((unsigned int*)(encoded+4)); + if (mthread_outlen > c->decomp_size) + mthread_outlen = c->decomp_size; + c->zstream.next_in = encoded + 8; + c->zstream.avail_in = mthread_inlen; + c->zstream.next_out = c->decomp_buf; + c->zstream.avail_out = c->decomp_size; + zret = inflate(&(c->zstream), Z_FINISH); + if ((zret != Z_OK) && (zret != Z_STREAM_END)) { + av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret); + return -1; + } + if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { + av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n", + mthread_outlen, c->zstream.total_out); + return -1; + } + zret = inflateReset(&(c->zstream)); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret); + return -1; + } + c->zstream.next_in = encoded + 8 + mthread_inlen; + c->zstream.avail_in = len - mthread_inlen; + c->zstream.next_out = c->decomp_buf + mthread_outlen; + c->zstream.avail_out = c->decomp_size - mthread_outlen; + zret = inflate(&(c->zstream), Z_FINISH); + if ((zret != Z_OK) && (zret != Z_STREAM_END)) { + av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret); + return -1; + } + if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { + av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n", + mthread_outlen, c->zstream.total_out); + return -1; + } + } else { + c->zstream.next_in = encoded; + c->zstream.avail_in = len; + c->zstream.next_out = c->decomp_buf; + c->zstream.avail_out = c->decomp_size; + zret = inflate(&(c->zstream), Z_FINISH); + if ((zret != Z_OK) && (zret != Z_STREAM_END)) { + av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); + return -1; + } + if (c->decomp_size != (unsigned int)(c->zstream.total_out)) { + av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", + c->decomp_size, c->zstream.total_out); + return -1; + } + } + encoded = c->decomp_buf; + len = c->decomp_size;; +#else + av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); + return -1; +#endif + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n"); + return -1; + } + + + /* Apply PNG filter */ + if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) { + switch (c->imgtype) { + case IMGTYPE_YUV111: + case IMGTYPE_RGB24: + for (row = 0; row < height; row++) { + pixel_ptr = row * width * 3; + yq = encoded[pixel_ptr++]; + uqvq = encoded[pixel_ptr++]; + uqvq+=(encoded[pixel_ptr++] << 8); + for (col = 1; col < width; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + uqvq -= (encoded[pixel_ptr+1] | (encoded[pixel_ptr+2]<<8)); + encoded[pixel_ptr+1] = (uqvq) & 0xff; + encoded[pixel_ptr+2] = ((uqvq)>>8) & 0xff; + pixel_ptr += 3; + } + } + break; + case IMGTYPE_YUV422: + for (row = 0; row < height; row++) { + pixel_ptr = row * width * 2; + yq = uq = vq =0; + for (col = 0; col < width/4; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; + encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; + encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; + encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; + encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; + encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; + encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; + pixel_ptr += 8; + } + } + break; + case IMGTYPE_YUV411: + for (row = 0; row < height; row++) { + pixel_ptr = row * width / 2 * 3; + yq = uq = vq =0; + for (col = 0; col < width/4; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; + encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; + encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; + encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; + encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; + pixel_ptr += 6; + } + } + break; + case IMGTYPE_YUV211: + for (row = 0; row < height; row++) { + pixel_ptr = row * width * 2; + yq = uq = vq =0; + for (col = 0; col < width/2; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; + encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; + encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; + pixel_ptr += 4; + } + } + break; + case IMGTYPE_YUV420: + for (row = 0; row < height/2; row++) { + pixel_ptr = row * width * 3; + yq = y1q = uq = vq =0; + for (col = 0; col < width/2; col++) { + encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; + encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; + encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; + encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; + encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; + encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; + pixel_ptr += 6; + } + } + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n"); + return -1; + } + } + + /* Convert colorspace */ + switch (c->imgtype) { + case IMGTYPE_YUV111: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width; col++) { + outptr[pixel_ptr++] = get_b(encoded[0], encoded[1]); + outptr[pixel_ptr++] = get_g(encoded[0], encoded[1], encoded[2]); + outptr[pixel_ptr++] = get_r(encoded[0], encoded[2]); + encoded += 3; + } + } + break; + case IMGTYPE_YUV422: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width/4; col++) { + outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[6]); + outptr[pixel_ptr++] = get_r(encoded[0], encoded[6]); + outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[6]); + outptr[pixel_ptr++] = get_r(encoded[1], encoded[6]); + outptr[pixel_ptr++] = get_b(encoded[2], encoded[5]); + outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]); + outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]); + outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]); + outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]); + outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]); + encoded += 8; + } + } + break; + case IMGTYPE_RGB24: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width; col++) { + outptr[pixel_ptr++] = encoded[0]; + outptr[pixel_ptr++] = encoded[1]; + outptr[pixel_ptr++] = encoded[2]; + encoded += 3; + } + } + break; + case IMGTYPE_YUV411: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width/4; col++) { + outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]); + outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]); + outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]); + outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]); + outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]); + outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]); + outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]); + outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]); + outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]); + encoded += 6; + } + } + break; + case IMGTYPE_YUV211: + for (row = height - 1; row >= 0; row--) { + pixel_ptr = row * c->pic.linesize[0]; + for (col = 0; col < width/2; col++) { + outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]); + outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]); + outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]); + outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]); + outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]); + outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]); + encoded += 4; + } + } + break; + case IMGTYPE_YUV420: + for (row = height / 2 - 1; row >= 0; row--) { + pixel_ptr = 2 * row * c->pic.linesize[0]; + for (col = 0; col < width/2; col++) { + outptr[pixel_ptr] = get_b(encoded[0], encoded[4]); + outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]); + outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]); + outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]); + outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]); + outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]); + outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]); + outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]); + outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]); + outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]); + outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]); + outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]); + pixel_ptr += 6; + encoded += 6; + } + } + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); + return -1; + } + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = c->pic; + + /* always report that the buffer was completely consumed */ + return buf_size; +} + + + +/* + * + * Encode a frame + * + */ +static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ + LclContext *c = avctx->priv_data; + AVFrame *pict = data; + AVFrame * const p = &c->pic; + int i; + int zret; // Zlib return code + +#ifndef CONFIG_ZLIB + av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled in.\n"); + return -1; +#else + + init_put_bits(&c->pb, buf, buf_size); + + *p = *pict; + p->pict_type= FF_I_TYPE; + p->key_frame= 1; + + if(avctx->pix_fmt != PIX_FMT_BGR24){ + av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); + return -1; + } + + zret = deflateReset(&(c->zstream)); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret); + return -1; + } + c->zstream.next_out = c->comp_buf; + c->zstream.avail_out = c->max_comp_size; + + for(i = avctx->height - 1; i >= 0; i--) { + c->zstream.next_in = p->data[0]+p->linesize[0]*i; + c->zstream.avail_in = avctx->width*3; + zret = deflate(&(c->zstream), Z_NO_FLUSH); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); + return -1; + } + } + zret = deflate(&(c->zstream), Z_FINISH); + if (zret != Z_STREAM_END) { + av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); + return -1; + } + + for (i = 0; i < c->zstream.total_out; i++) + put_bits(&c->pb, 8, c->comp_buf[i]); + flush_put_bits(&c->pb); + + return c->zstream.total_out; +#endif +} + + + +/* + * + * Init lcl decoder + * + */ +static int decode_init(AVCodecContext *avctx) +{ + LclContext * const c = (LclContext *)avctx->priv_data; + unsigned int basesize = avctx->width * avctx->height; + unsigned int max_basesize = ((avctx->width + 3) & ~3) * ((avctx->height + 3) & ~3); + unsigned int max_decomp_size; + int zret; // Zlib return code + + c->avctx = avctx; + avctx->has_b_frames = 0; + + c->pic.data[0] = NULL; + +#ifdef CONFIG_ZLIB + // Needed if zlib unused or init aborted before inflateInit + memset(&(c->zstream), 0, sizeof(z_stream)); +#endif + + if (avctx->extradata_size < 8) { + av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); + return 1; + } + + if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { + return 1; + } + + /* Check codec type */ + if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) || + ((avctx->codec_id == CODEC_ID_ZLIB) && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) { + av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); + } + + /* Detect image type */ + switch (c->imgtype = *((char *)avctx->extradata + 4)) { + case IMGTYPE_YUV111: + c->decomp_size = basesize * 3; + max_decomp_size = max_basesize * 3; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); + break; + case IMGTYPE_YUV422: + c->decomp_size = basesize * 2; + max_decomp_size = max_basesize * 2; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); + break; + case IMGTYPE_RGB24: + c->decomp_size = basesize * 3; + max_decomp_size = max_basesize * 3; + av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); + break; + case IMGTYPE_YUV411: + c->decomp_size = basesize / 2 * 3; + max_decomp_size = max_basesize / 2 * 3; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); + break; + case IMGTYPE_YUV211: + c->decomp_size = basesize * 2; + max_decomp_size = max_basesize * 2; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); + break; + case IMGTYPE_YUV420: + c->decomp_size = basesize / 2 * 3; + max_decomp_size = max_basesize / 2 * 3; + av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); + return 1; + } + + /* Detect compression method */ + c->compression = *((char *)avctx->extradata + 5); + switch (avctx->codec_id) { + case CODEC_ID_MSZH: + switch (c->compression) { + case COMP_MSZH: + av_log(avctx, AV_LOG_INFO, "Compression enabled.\n"); + break; + case COMP_MSZH_NOCOMP: + c->decomp_size = 0; + av_log(avctx, AV_LOG_INFO, "No compression.\n"); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); + return 1; + } + break; + case CODEC_ID_ZLIB: +#ifdef CONFIG_ZLIB + switch (c->compression) { + case COMP_ZLIB_HISPEED: + av_log(avctx, AV_LOG_INFO, "High speed compression.\n"); + break; + case COMP_ZLIB_HICOMP: + av_log(avctx, AV_LOG_INFO, "High compression.\n"); + break; + case COMP_ZLIB_NORMAL: + av_log(avctx, AV_LOG_INFO, "Normal compression.\n"); + break; + default: + if ((c->compression < Z_NO_COMPRESSION) || (c->compression > Z_BEST_COMPRESSION)) { + av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); + return 1; + } + av_log(avctx, AV_LOG_INFO, "Compression level for ZLIB: (%d).\n", c->compression); + } +#else + av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); + return 1; +#endif + break; + default: + av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); + return 1; + } + + /* Allocate decompression buffer */ + if (c->decomp_size) { + if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { + av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); + return 1; + } + } + + /* Detect flags */ + c->flags = *((char *)avctx->extradata + 6); + if (c->flags & FLAG_MULTITHREAD) + av_log(avctx, AV_LOG_INFO, "Multithread encoder flag set.\n"); + if (c->flags & FLAG_NULLFRAME) + av_log(avctx, AV_LOG_INFO, "Nullframe insertion flag set.\n"); + if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) + av_log(avctx, AV_LOG_INFO, "PNG filter flag set.\n"); + if (c->flags & FLAGMASK_UNUSED) + av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); + + /* If needed init zlib */ + if (avctx->codec_id == CODEC_ID_ZLIB) { +#ifdef CONFIG_ZLIB + c->zstream.zalloc = Z_NULL; + c->zstream.zfree = Z_NULL; + c->zstream.opaque = Z_NULL; + zret = inflateInit(&(c->zstream)); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); + return 1; + } +#else + av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); + return 1; +#endif + } + + avctx->pix_fmt = PIX_FMT_BGR24; + + return 0; +} + + + +/* + * + * Init lcl encoder + * + */ +static int encode_init(AVCodecContext *avctx) +{ + LclContext *c = avctx->priv_data; + int zret; // Zlib return code + +#ifndef CONFIG_ZLIB + av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); + return 1; +#else + + c->avctx= avctx; + + assert(avctx->width && avctx->height); + + avctx->extradata= av_mallocz(8); + avctx->coded_frame= &c->pic; + + // Will be user settable someday + c->compression = 6; + c->flags = 0; + + switch(avctx->pix_fmt){ + case PIX_FMT_BGR24: + c->imgtype = IMGTYPE_RGB24; + c->decomp_size = avctx->width * avctx->height * 3; + avctx->bits_per_sample= 24; + break; + default: + av_log(avctx, AV_LOG_ERROR, "Format %d not supported\n", avctx->pix_fmt); + return -1; + } + + ((uint8_t*)avctx->extradata)[0]= 4; + ((uint8_t*)avctx->extradata)[1]= 0; + ((uint8_t*)avctx->extradata)[2]= 0; + ((uint8_t*)avctx->extradata)[3]= 0; + ((uint8_t*)avctx->extradata)[4]= c->imgtype; + ((uint8_t*)avctx->extradata)[5]= c->compression; + ((uint8_t*)avctx->extradata)[6]= c->flags; + ((uint8_t*)avctx->extradata)[7]= CODEC_ZLIB; + c->avctx->extradata_size= 8; + + c->zstream.zalloc = Z_NULL; + c->zstream.zfree = Z_NULL; + c->zstream.opaque = Z_NULL; + zret = deflateInit(&(c->zstream), c->compression); + if (zret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); + return 1; + } + + /* Conservative upper bound taken from zlib v1.2.1 source */ + c->max_comp_size = c->decomp_size + ((c->decomp_size + 7) >> 3) + + ((c->decomp_size + 63) >> 6) + 11; + if ((c->comp_buf = av_malloc(c->max_comp_size)) == NULL) { + av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n"); + return 1; + } + + return 0; +#endif +} + + + + + +/* + * + * Uninit lcl decoder + * + */ +static int decode_end(AVCodecContext *avctx) +{ + LclContext * const c = (LclContext *)avctx->priv_data; + + if (c->pic.data[0]) + avctx->release_buffer(avctx, &c->pic); +#ifdef CONFIG_ZLIB + inflateEnd(&(c->zstream)); +#endif + + return 0; +} + + + +/* + * + * Uninit lcl encoder + * + */ +static int encode_end(AVCodecContext *avctx) +{ + LclContext *c = avctx->priv_data; + + av_freep(&avctx->extradata); + av_freep(&c->comp_buf); +#ifdef CONFIG_ZLIB + deflateEnd(&(c->zstream)); +#endif + + return 0; +} + +AVCodec mszh_decoder = { + "mszh", + CODEC_TYPE_VIDEO, + CODEC_ID_MSZH, + sizeof(LclContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; + + +AVCodec zlib_decoder = { + "zlib", + CODEC_TYPE_VIDEO, + CODEC_ID_ZLIB, + sizeof(LclContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1, +}; + +#ifdef CONFIG_ENCODERS + +AVCodec zlib_encoder = { + "zlib", + CODEC_TYPE_VIDEO, + CODEC_ID_ZLIB, + sizeof(LclContext), + encode_init, + encode_frame, + encode_end, +}; + +#endif //CONFIG_ENCODERS diff --git a/mpeg4/src/libavcodec/liba52/a52.h b/mpeg4/src/libavcodec/liba52/a52.h new file mode 100644 index 00000000..f2ea5f83 --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/a52.h @@ -0,0 +1,73 @@ +/* + * a52.h + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef A52_H +#define A52_H + +#include "../avcodec.h" + +#undef malloc +#undef free +#undef realloc + +#if defined(LIBA52_FIXED) +typedef int32_t sample_t; +typedef int32_t level_t; +#elif defined(LIBA52_DOUBLE) +typedef double sample_t; +typedef double level_t; +#else +typedef float sample_t; +typedef float level_t; +#endif + +typedef struct a52_state_s a52_state_t; + +#define A52_CHANNEL 0 +#define A52_MONO 1 +#define A52_STEREO 2 +#define A52_3F 3 +#define A52_2F1R 4 +#define A52_3F1R 5 +#define A52_2F2R 6 +#define A52_3F2R 7 +#define A52_CHANNEL1 8 +#define A52_CHANNEL2 9 +#define A52_DOLBY 10 +#define A52_CHANNEL_MASK 15 + +#define A52_LFE 16 +#define A52_ADJUST_LEVEL 32 + +a52_state_t * a52_init (uint32_t mm_accel); +sample_t * a52_samples (a52_state_t * state); +int a52_syncinfo (uint8_t * buf, int * flags, + int * sample_rate, int * bit_rate); +int a52_frame (a52_state_t * state, uint8_t * buf, int * flags, + level_t * level, sample_t bias); +void a52_dynrng (a52_state_t * state, + level_t (* call) (level_t, void *), void * data); +int a52_block (a52_state_t * state); +void a52_free (a52_state_t * state); + +#endif /* A52_H */ diff --git a/mpeg4/src/libavcodec/liba52/a52_internal.h b/mpeg4/src/libavcodec/liba52/a52_internal.h new file mode 100644 index 00000000..49fd4ef9 --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/a52_internal.h @@ -0,0 +1,162 @@ +/* + * a52_internal.h + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +typedef struct { + uint8_t bai; /* fine SNR offset, fast gain */ + uint8_t deltbae; /* delta bit allocation exists */ + int8_t deltba[50]; /* per-band delta bit allocation */ +} ba_t; + +typedef struct { + uint8_t exp[256]; /* decoded channel exponents */ + int8_t bap[256]; /* derived channel bit allocation */ +} expbap_t; + +struct a52_state_s { + uint8_t fscod; /* sample rate */ + uint8_t halfrate; /* halfrate factor */ + uint8_t acmod; /* coded channels */ + uint8_t lfeon; /* coded lfe channel */ + level_t clev; /* centre channel mix level */ + level_t slev; /* surround channels mix level */ + + int output; /* type of output */ + level_t level; /* output level */ + sample_t bias; /* output bias */ + + int dynrnge; /* apply dynamic range */ + level_t dynrng; /* dynamic range */ + void * dynrngdata; /* dynamic range callback funtion and data */ + level_t (* dynrngcall) (level_t range, void * dynrngdata); + + uint8_t chincpl; /* channel coupled */ + uint8_t phsflginu; /* phase flags in use (stereo only) */ + uint8_t cplstrtmant; /* coupling channel start mantissa */ + uint8_t cplendmant; /* coupling channel end mantissa */ + uint32_t cplbndstrc; /* coupling band structure */ + level_t cplco[5][18]; /* coupling coordinates */ + + /* derived information */ + uint8_t cplstrtbnd; /* coupling start band (for bit allocation) */ + uint8_t ncplbnd; /* number of coupling bands */ + + uint8_t rematflg; /* stereo rematrixing */ + + uint8_t endmant[5]; /* channel end mantissa */ + + uint16_t bai; /* bit allocation information */ + + uint32_t * buffer_start; + uint16_t lfsr_state; /* dither state */ + uint32_t bits_left; + uint32_t current_word; + + uint8_t csnroffst; /* coarse SNR offset */ + ba_t cplba; /* coupling bit allocation parameters */ + ba_t ba[5]; /* channel bit allocation parameters */ + ba_t lfeba; /* lfe bit allocation parameters */ + + uint8_t cplfleak; /* coupling fast leak init */ + uint8_t cplsleak; /* coupling slow leak init */ + + expbap_t cpl_expbap; + expbap_t fbw_expbap[5]; + expbap_t lfe_expbap; + + sample_t * samples; + int downmixed; +}; + +#define LEVEL_PLUS6DB 2.0 +#define LEVEL_PLUS3DB 1.4142135623730951 +#define LEVEL_3DB 0.7071067811865476 +#define LEVEL_45DB 0.5946035575013605 +#define LEVEL_6DB 0.5 + +#define EXP_REUSE (0) +#define EXP_D15 (1) +#define EXP_D25 (2) +#define EXP_D45 (3) + +#define DELTA_BIT_REUSE (0) +#define DELTA_BIT_NEW (1) +#define DELTA_BIT_NONE (2) +#define DELTA_BIT_RESERVED (3) + +void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart, + int start, int end, int fastleak, int slowleak, + expbap_t * expbap); + +int a52_downmix_init (int input, int flags, level_t * level, + level_t clev, level_t slev); +int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level, + level_t clev, level_t slev); +void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias, + level_t clev, level_t slev); +void a52_upmix (sample_t * samples, int acmod, int output); + +void a52_imdct_init (uint32_t mm_accel); +void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias); +void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias); +//extern void (* a52_imdct_256) (sample_t data[], sample_t delay[], sample_t bias); +//extern void (* a52_imdct_512) (sample_t data[], sample_t delay[], sample_t bias); + +#define ROUND(x) ((int)((x) + ((x) > 0 ? 0.5 : -0.5))) + +#ifndef LIBA52_FIXED + +typedef sample_t quantizer_t; +#define SAMPLE(x) (x) +#define LEVEL(x) (x) +#define MUL(a,b) ((a) * (b)) +#define MUL_L(a,b) ((a) * (b)) +#define MUL_C(a,b) ((a) * (b)) +#define DIV(a,b) ((a) / (b)) +#define BIAS(x) ((x) + bias) + +#else /* LIBA52_FIXED */ + +typedef int16_t quantizer_t; +#define SAMPLE(x) (sample_t)((x) * (1 << 30)) +#define LEVEL(x) (level_t)((x) * (1 << 26)) + +#if 0 +#define MUL(a,b) ((int)(((int64_t)(a) * (b) + (1 << 29)) >> 30)) +#define MUL_L(a,b) ((int)(((int64_t)(a) * (b) + (1 << 25)) >> 26)) +#elif 1 +#define MUL(a,b) \ +({ int32_t _ta=(a), _tb=(b), _tc; \ + _tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)(((_tc >> 14))+ (((_ta >> 16)*(_tb >> 16)) << 2 )); }) +#define MUL_L(a,b) \ +({ int32_t _ta=(a), _tb=(b), _tc; \ + _tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)((_tc >> 10) + (((_ta >> 16)*(_tb >> 16)) << 6)); }) +#else +#define MUL(a,b) (((a) >> 15) * ((b) >> 15)) +#define MUL_L(a,b) (((a) >> 13) * ((b) >> 13)) +#endif + +#define MUL_C(a,b) MUL_L (a, LEVEL (b)) +#define DIV(a,b) ((((int64_t)LEVEL (a)) << 26) / (b)) +#define BIAS(x) (x) + +#endif diff --git a/mpeg4/src/libavcodec/liba52/a52_util.h b/mpeg4/src/libavcodec/liba52/a52_util.h new file mode 100644 index 00000000..8ef2cece --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/a52_util.h @@ -0,0 +1,32 @@ +/* + * a52_util.h + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef A52_UTIL_H +#define A52_UTIL_H + +uint16_t a52_crc16_block(uint8_t *data,uint32_t num_bytes); + +void* a52_resample_init(uint32_t mm_accel,int flags,int chans); +extern int (* a52_resample) (float * _f, int16_t * s16); + +#endif /* A52_H */ diff --git a/mpeg4/src/libavcodec/liba52/bit_allocate.c b/mpeg4/src/libavcodec/liba52/bit_allocate.c new file mode 100644 index 00000000..415a08d2 --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/bit_allocate.c @@ -0,0 +1,260 @@ +/* + * bit_allocate.c + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "a52.h" +#include "a52_internal.h" + +static int hthtab[3][50] = { + {0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x890, 0x890, + 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, + 0x910, 0x910, 0x910, 0x910, 0x900, 0x8f0, 0x8c0, 0x870, 0x820, 0x7e0, + 0x7a0, 0x770, 0x760, 0x7a0, 0x7c0, 0x7c0, 0x6e0, 0x400, 0x3c0, 0x3c0}, + {0x710, 0x710, 0x7a0, 0x7f0, 0x820, 0x830, 0x840, 0x850, 0x850, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, + 0x890, 0x890, 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8e0, 0x8f0, + 0x900, 0x910, 0x910, 0x910, 0x910, 0x900, 0x8e0, 0x8b0, 0x870, 0x820, + 0x7e0, 0x7b0, 0x760, 0x770, 0x7a0, 0x7c0, 0x780, 0x5d0, 0x3c0, 0x3c0}, + {0x680, 0x680, 0x750, 0x7b0, 0x7e0, 0x810, 0x820, 0x830, 0x840, 0x850, + 0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x870, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, 0x890, 0x8a0, 0x8b0, + 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x900, 0x8f0, + 0x8d0, 0x8b0, 0x840, 0x7f0, 0x790, 0x760, 0x7a0, 0x7c0, 0x7b0, 0x720} +}; + +static int8_t baptab[305] = { + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, /* 93 padding elems */ + + 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 14, 14, 14, 14, + 14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, + 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, + 5, 4, 4, -3, -3, 3, 3, 3, -2, -2, -1, -1, -1, -1, -1, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 /* 148 padding elems */ +}; + +static int bndtab[30] = {21, 22, 23, 24, 25, 26, 27, 28, 31, 34, + 37, 40, 43, 46, 49, 55, 61, 67, 73, 79, + 85, 97, 109, 121, 133, 157, 181, 205, 229, 253}; + +static int8_t latab[256] = { + -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, + -52, -52, -51, -50, -49, -48, -47, -47, -46, -45, -44, -44, + -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35, + -35, -34, -33, -33, -32, -32, -31, -30, -30, -29, -29, -28, + -28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22, + -22, -21, -21, -21, -20, -20, -19, -19, -19, -18, -18, -18, + -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14, + -13, -13, -13, -13, -12, -12, -12, -12, -11, -11, -11, -11, + -10, -10, -10, -10, -10, -9, -9, -9, -9, -9, -8, -8, + -8, -8, -8, -8, -7, -7, -7, -7, -7, -7, -6, -6, + -6, -6, -6, -6, -6, -6, -5, -5, -5, -5, -5, -5, + -5, -5, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, + -4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +#define UPDATE_LEAK() \ +do { \ + fastleak += fdecay; \ + if (fastleak > psd + fgain) \ + fastleak = psd + fgain; \ + slowleak += sdecay; \ + if (slowleak > psd + sgain) \ + slowleak = psd + sgain; \ +} while (0) + +#define COMPUTE_MASK() \ +do { \ + if (psd > dbknee) \ + mask -= (psd - dbknee) >> 2; \ + if (mask > hth [i >> halfrate]) \ + mask = hth [i >> halfrate]; \ + mask -= snroffset + 128 * deltba[i]; \ + mask = (mask > 0) ? 0 : ((-mask) >> 5); \ + mask -= floor; \ +} while (0) + +void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart, + int start, int end, int fastleak, int slowleak, + expbap_t * expbap) +{ + static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410}; + static int dbpbtab[4] = {0xc00, 0x500, 0x300, 0x100}; + static int floortab[8] = {0x910, 0x950, 0x990, 0x9d0, + 0xa10, 0xa90, 0xb10, 0x1400}; + + int i, j; + uint8_t * exp; + int8_t * bap; + int fdecay, fgain, sdecay, sgain, dbknee, floor, snroffset; + int psd, mask; + int8_t * deltba; + int * hth; + int halfrate; + + halfrate = state->halfrate; + fdecay = (63 + 20 * ((state->bai >> 7) & 3)) >> halfrate; /* fdcycod */ + fgain = 128 + 128 * (ba->bai & 7); /* fgaincod */ + sdecay = (15 + 2 * (state->bai >> 9)) >> halfrate; /* sdcycod */ + sgain = slowgain[(state->bai >> 5) & 3]; /* sgaincod */ + dbknee = dbpbtab[(state->bai >> 3) & 3]; /* dbpbcod */ + hth = hthtab[state->fscod]; + /* + * if there is no delta bit allocation, make deltba point to an area + * known to contain zeroes. baptab+156 here. + */ + deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba; + floor = floortab[state->bai & 7]; /* floorcod */ + snroffset = 960 - 64 * state->csnroffst - 4 * (ba->bai >> 3) + floor; + floor >>= 5; + + exp = expbap->exp; + bap = expbap->bap; + + i = bndstart; + j = start; + if (start == 0) { /* not the coupling channel */ + int lowcomp; + + lowcomp = 0; + j = end - 1; + do { + if (i < j) { + if (exp[i+1] == exp[i] - 2) + lowcomp = 384; + else if (lowcomp && (exp[i+1] > exp[i])) + lowcomp -= 64; + } + psd = 128 * exp[i]; + mask = psd + fgain + lowcomp; + COMPUTE_MASK (); + bap[i] = (baptab+156)[mask + 4 * exp[i]]; + i++; + } while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1]))); + fastleak = psd + fgain; + slowleak = psd + sgain; + + while (i < 7) { + if (i < j) { + if (exp[i+1] == exp[i] - 2) + lowcomp = 384; + else if (lowcomp && (exp[i+1] > exp[i])) + lowcomp -= 64; + } + psd = 128 * exp[i]; + UPDATE_LEAK (); + mask = ((fastleak + lowcomp < slowleak) ? + fastleak + lowcomp : slowleak); + COMPUTE_MASK (); + bap[i] = (baptab+156)[mask + 4 * exp[i]]; + i++; + } + + if (end == 7) /* lfe channel */ + return; + + do { + if (exp[i+1] == exp[i] - 2) + lowcomp = 320; + else if (lowcomp && (exp[i+1] > exp[i])) + lowcomp -= 64; + psd = 128 * exp[i]; + UPDATE_LEAK (); + mask = ((fastleak + lowcomp < slowleak) ? + fastleak + lowcomp : slowleak); + COMPUTE_MASK (); + bap[i] = (baptab+156)[mask + 4 * exp[i]]; + i++; + } while (i < 20); + + while (lowcomp > 128) { /* two iterations maximum */ + lowcomp -= 128; + psd = 128 * exp[i]; + UPDATE_LEAK (); + mask = ((fastleak + lowcomp < slowleak) ? + fastleak + lowcomp : slowleak); + COMPUTE_MASK (); + bap[i] = (baptab+156)[mask + 4 * exp[i]]; + i++; + } + j = i; + } + + do { + int startband, endband; + + startband = j; + endband = (bndtab[i-20] < end) ? bndtab[i-20] : end; + psd = 128 * exp[j++]; + while (j < endband) { + int next, delta; + + next = 128 * exp[j++]; + delta = next - psd; + switch (delta >> 9) { + case -6: case -5: case -4: case -3: case -2: + psd = next; + break; + case -1: + psd = next + latab[(-delta) >> 1]; + break; + case 0: + psd += latab[delta >> 1]; + break; + } + } + /* minpsd = -289 */ + UPDATE_LEAK (); + mask = (fastleak < slowleak) ? fastleak : slowleak; + COMPUTE_MASK (); + i++; + j = startband; + do { + /* max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp */ + /* min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5 */ + bap[j] = (baptab+156)[mask + 4 * exp[j]]; + } while (++j < endband); + } while (j < end); +} diff --git a/mpeg4/src/libavcodec/liba52/bitstream.c b/mpeg4/src/libavcodec/liba52/bitstream.c new file mode 100644 index 00000000..f6b05c5e --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/bitstream.c @@ -0,0 +1,91 @@ +/* + * bitstream.c + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "a52.h" +#include "a52_internal.h" +#include "bitstream.h" + +#define BUFFER_SIZE 4096 + +void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf) +{ + int align; + + align = (long)buf & 3; + state->buffer_start = (uint32_t *) (buf - align); + state->bits_left = 0; + state->current_word = 0; + bitstream_get (state, align * 8); +} + +static inline void bitstream_fill_current (a52_state_t * state) +{ + uint32_t tmp; + + tmp = *(state->buffer_start++); + state->current_word = swab32 (tmp); +} + +/* + * The fast paths for _get is in the + * bitstream.h header file so it can be inlined. + * + * The "bottom half" of this routine is suffixed _bh + * + * -ah + */ + +uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits) +{ + uint32_t result; + + num_bits -= state->bits_left; + result = ((state->current_word << (32 - state->bits_left)) >> + (32 - state->bits_left)); + + bitstream_fill_current (state); + + if (num_bits != 0) + result = (result << num_bits) | (state->current_word >> (32 - num_bits)); + + state->bits_left = 32 - num_bits; + + return result; +} + +int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits) +{ + int32_t result; + + num_bits -= state->bits_left; + result = ((((int32_t)state->current_word) << (32 - state->bits_left)) >> + (32 - state->bits_left)); + + bitstream_fill_current(state); + + if (num_bits != 0) + result = (result << num_bits) | (state->current_word >> (32 - num_bits)); + + state->bits_left = 32 - num_bits; + + return result; +} diff --git a/mpeg4/src/libavcodec/liba52/bitstream.h b/mpeg4/src/libavcodec/liba52/bitstream.h new file mode 100644 index 00000000..4a64bf3d --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/bitstream.h @@ -0,0 +1,77 @@ +/* + * bitstream.h + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* (stolen from the kernel) */ +#ifdef WORDS_BIGENDIAN + +# define swab32(x) (x) + +#else + +# if 0 && defined (__i386__) + +# define swab32(x) __i386_swab32(x) + static inline const uint32_t __i386_swab32(uint32_t x) + { + __asm__("bswap %0" : "=r" (x) : "0" (x)); + return x; + } + +# else + +# define swab32(x)\ +((((uint8_t*)&x)[0] << 24) | (((uint8_t*)&x)[1] << 16) | \ + (((uint8_t*)&x)[2] << 8) | (((uint8_t*)&x)[3])) + +# endif +#endif + +void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf); +uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits); +int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits); + +static inline uint32_t bitstream_get (a52_state_t * state, uint32_t num_bits) +{ + uint32_t result; + + if (num_bits < state->bits_left) { + result = (state->current_word << (32 - state->bits_left)) >> (32 - num_bits); + state->bits_left -= num_bits; + return result; + } + + return a52_bitstream_get_bh (state, num_bits); +} + +static inline int32_t bitstream_get_2 (a52_state_t * state, uint32_t num_bits) +{ + int32_t result; + + if (num_bits < state->bits_left) { + result = (((int32_t)state->current_word) << (32 - state->bits_left)) >> (32 - num_bits); + state->bits_left -= num_bits; + return result; + } + + return a52_bitstream_get_bh_2 (state, num_bits); +} diff --git a/mpeg4/src/libavcodec/liba52/crc.c b/mpeg4/src/libavcodec/liba52/crc.c new file mode 100644 index 00000000..1ec4b085 --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/crc.c @@ -0,0 +1,73 @@ +/* + * crc.c + * + * Copyright (C) Aaron Holtzman - May 1999 + * + * This file is part of ac3dec, a free Dolby AC-3 stream decoder. + * + * ac3dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ac3dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include + +static const uint16_t crc_lut[256] = +{ + 0x0000,0x8005,0x800f,0x000a,0x801b,0x001e,0x0014,0x8011, + 0x8033,0x0036,0x003c,0x8039,0x0028,0x802d,0x8027,0x0022, + 0x8063,0x0066,0x006c,0x8069,0x0078,0x807d,0x8077,0x0072, + 0x0050,0x8055,0x805f,0x005a,0x804b,0x004e,0x0044,0x8041, + 0x80c3,0x00c6,0x00cc,0x80c9,0x00d8,0x80dd,0x80d7,0x00d2, + 0x00f0,0x80f5,0x80ff,0x00fa,0x80eb,0x00ee,0x00e4,0x80e1, + 0x00a0,0x80a5,0x80af,0x00aa,0x80bb,0x00be,0x00b4,0x80b1, + 0x8093,0x0096,0x009c,0x8099,0x0088,0x808d,0x8087,0x0082, + 0x8183,0x0186,0x018c,0x8189,0x0198,0x819d,0x8197,0x0192, + 0x01b0,0x81b5,0x81bf,0x01ba,0x81ab,0x01ae,0x01a4,0x81a1, + 0x01e0,0x81e5,0x81ef,0x01ea,0x81fb,0x01fe,0x01f4,0x81f1, + 0x81d3,0x01d6,0x01dc,0x81d9,0x01c8,0x81cd,0x81c7,0x01c2, + 0x0140,0x8145,0x814f,0x014a,0x815b,0x015e,0x0154,0x8151, + 0x8173,0x0176,0x017c,0x8179,0x0168,0x816d,0x8167,0x0162, + 0x8123,0x0126,0x012c,0x8129,0x0138,0x813d,0x8137,0x0132, + 0x0110,0x8115,0x811f,0x011a,0x810b,0x010e,0x0104,0x8101, + 0x8303,0x0306,0x030c,0x8309,0x0318,0x831d,0x8317,0x0312, + 0x0330,0x8335,0x833f,0x033a,0x832b,0x032e,0x0324,0x8321, + 0x0360,0x8365,0x836f,0x036a,0x837b,0x037e,0x0374,0x8371, + 0x8353,0x0356,0x035c,0x8359,0x0348,0x834d,0x8347,0x0342, + 0x03c0,0x83c5,0x83cf,0x03ca,0x83db,0x03de,0x03d4,0x83d1, + 0x83f3,0x03f6,0x03fc,0x83f9,0x03e8,0x83ed,0x83e7,0x03e2, + 0x83a3,0x03a6,0x03ac,0x83a9,0x03b8,0x83bd,0x83b7,0x03b2, + 0x0390,0x8395,0x839f,0x039a,0x838b,0x038e,0x0384,0x8381, + 0x0280,0x8285,0x828f,0x028a,0x829b,0x029e,0x0294,0x8291, + 0x82b3,0x02b6,0x02bc,0x82b9,0x02a8,0x82ad,0x82a7,0x02a2, + 0x82e3,0x02e6,0x02ec,0x82e9,0x02f8,0x82fd,0x82f7,0x02f2, + 0x02d0,0x82d5,0x82df,0x02da,0x82cb,0x02ce,0x02c4,0x82c1, + 0x8243,0x0246,0x024c,0x8249,0x0258,0x825d,0x8257,0x0252, + 0x0270,0x8275,0x827f,0x027a,0x826b,0x026e,0x0264,0x8261, + 0x0220,0x8225,0x822f,0x022a,0x823b,0x023e,0x0234,0x8231, + 0x8213,0x0216,0x021c,0x8219,0x0208,0x820d,0x8207,0x0202 +}; + +uint16_t a52_crc16_block(uint8_t *data,uint32_t num_bytes) +{ + uint32_t i; + uint16_t state=0; + + for(i=0;i>8)] ^ (state<<8); + + return state; +} diff --git a/mpeg4/src/libavcodec/liba52/downmix.c b/mpeg4/src/libavcodec/liba52/downmix.c new file mode 100644 index 00000000..7999b7db --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/downmix.c @@ -0,0 +1,679 @@ +/* + * downmix.c + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "a52.h" +#include "a52_internal.h" + +#define CONVERT(acmod,output) (((output) << 3) + (acmod)) + +int a52_downmix_init (int input, int flags, level_t * level, + level_t clev, level_t slev) +{ + static uint8_t table[11][8] = { + {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, + A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO}, + {A52_MONO, A52_MONO, A52_MONO, A52_MONO, + A52_MONO, A52_MONO, A52_MONO, A52_MONO}, + {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, + A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO}, + {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F, + A52_STEREO, A52_3F, A52_STEREO, A52_3F}, + {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, + A52_2F1R, A52_2F1R, A52_2F1R, A52_2F1R}, + {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, + A52_2F1R, A52_3F1R, A52_2F1R, A52_3F1R}, + {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F, + A52_2F2R, A52_2F2R, A52_2F2R, A52_2F2R}, + {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F, + A52_2F2R, A52_3F2R, A52_2F2R, A52_3F2R}, + {A52_CHANNEL1, A52_MONO, A52_MONO, A52_MONO, + A52_MONO, A52_MONO, A52_MONO, A52_MONO}, + {A52_CHANNEL2, A52_MONO, A52_MONO, A52_MONO, + A52_MONO, A52_MONO, A52_MONO, A52_MONO}, + {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_DOLBY, + A52_DOLBY, A52_DOLBY, A52_DOLBY, A52_DOLBY} + }; + int output; + + output = flags & A52_CHANNEL_MASK; + if (output > A52_DOLBY) + return -1; + + output = table[output][input & 7]; + + if (output == A52_STEREO && + (input == A52_DOLBY || (input == A52_3F && clev == LEVEL (LEVEL_3DB)))) + output = A52_DOLBY; + + if (flags & A52_ADJUST_LEVEL) { + level_t adjust; + + switch (CONVERT (input & 7, output)) { + + case CONVERT (A52_3F, A52_MONO): + adjust = DIV (LEVEL_3DB, LEVEL (1) + clev); + break; + + case CONVERT (A52_STEREO, A52_MONO): + case CONVERT (A52_2F2R, A52_2F1R): + case CONVERT (A52_3F2R, A52_3F1R): + level_3db: + adjust = LEVEL (LEVEL_3DB); + break; + + case CONVERT (A52_3F2R, A52_2F1R): + if (clev < LEVEL (LEVEL_PLUS3DB - 1)) + goto level_3db; + /* break thru */ + case CONVERT (A52_3F, A52_STEREO): + case CONVERT (A52_3F1R, A52_2F1R): + case CONVERT (A52_3F1R, A52_2F2R): + case CONVERT (A52_3F2R, A52_2F2R): + adjust = DIV (1, LEVEL (1) + clev); + break; + + case CONVERT (A52_2F1R, A52_MONO): + adjust = DIV (LEVEL_PLUS3DB, LEVEL (2) + slev); + break; + + case CONVERT (A52_2F1R, A52_STEREO): + case CONVERT (A52_3F1R, A52_3F): + adjust = DIV (1, LEVEL (1) + MUL_C (slev, LEVEL_3DB)); + break; + + case CONVERT (A52_3F1R, A52_MONO): + adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + MUL_C (slev, 0.5)); + break; + + case CONVERT (A52_3F1R, A52_STEREO): + adjust = DIV (1, LEVEL (1) + clev + MUL_C (slev, LEVEL_3DB)); + break; + + case CONVERT (A52_2F2R, A52_MONO): + adjust = DIV (LEVEL_3DB, LEVEL (1) + slev); + break; + + case CONVERT (A52_2F2R, A52_STEREO): + case CONVERT (A52_3F2R, A52_3F): + adjust = DIV (1, LEVEL (1) + slev); + break; + + case CONVERT (A52_3F2R, A52_MONO): + adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + slev); + break; + + case CONVERT (A52_3F2R, A52_STEREO): + adjust = DIV (1, LEVEL (1) + clev + slev); + break; + + case CONVERT (A52_MONO, A52_DOLBY): + adjust = LEVEL (LEVEL_PLUS3DB); + break; + + case CONVERT (A52_3F, A52_DOLBY): + case CONVERT (A52_2F1R, A52_DOLBY): + adjust = LEVEL (1 / (1 + LEVEL_3DB)); + break; + + case CONVERT (A52_3F1R, A52_DOLBY): + case CONVERT (A52_2F2R, A52_DOLBY): + adjust = LEVEL (1 / (1 + 2 * LEVEL_3DB)); + break; + + case CONVERT (A52_3F2R, A52_DOLBY): + adjust = LEVEL (1 / (1 + 3 * LEVEL_3DB)); + break; + + default: + return output; + } + + *level = MUL_L (*level, adjust); + } + + return output; +} + +int a52_downmix_coeff (level_t * coeff, int acmod, int output, level_t level, + level_t clev, level_t slev) +{ + level_t level_3db; + + level_3db = MUL_C (level, LEVEL_3DB); + + switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) { + + case CONVERT (A52_CHANNEL, A52_CHANNEL): + case CONVERT (A52_MONO, A52_MONO): + case CONVERT (A52_STEREO, A52_STEREO): + case CONVERT (A52_3F, A52_3F): + case CONVERT (A52_2F1R, A52_2F1R): + case CONVERT (A52_3F1R, A52_3F1R): + case CONVERT (A52_2F2R, A52_2F2R): + case CONVERT (A52_3F2R, A52_3F2R): + case CONVERT (A52_STEREO, A52_DOLBY): + coeff[0] = coeff[1] = coeff[2] = coeff[3] = coeff[4] = level; + return 0; + + case CONVERT (A52_CHANNEL, A52_MONO): + coeff[0] = coeff[1] = MUL_C (level, LEVEL_6DB); + return 3; + + case CONVERT (A52_STEREO, A52_MONO): + coeff[0] = coeff[1] = level_3db; + return 3; + + case CONVERT (A52_3F, A52_MONO): + coeff[0] = coeff[2] = level_3db; + coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB); + return 7; + + case CONVERT (A52_2F1R, A52_MONO): + coeff[0] = coeff[1] = level_3db; + coeff[2] = MUL_L (level_3db, slev); + return 7; + + case CONVERT (A52_2F2R, A52_MONO): + coeff[0] = coeff[1] = level_3db; + coeff[2] = coeff[3] = MUL_L (level_3db, slev); + return 15; + + case CONVERT (A52_3F1R, A52_MONO): + coeff[0] = coeff[2] = level_3db; + coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB); + coeff[3] = MUL_L (level_3db, slev); + return 15; + + case CONVERT (A52_3F2R, A52_MONO): + coeff[0] = coeff[2] = level_3db; + coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB); + coeff[3] = coeff[4] = MUL_L (level_3db, slev); + return 31; + + case CONVERT (A52_MONO, A52_DOLBY): + coeff[0] = level_3db; + return 0; + + case CONVERT (A52_3F, A52_DOLBY): + coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; + coeff[1] = level_3db; + return 7; + + case CONVERT (A52_3F, A52_STEREO): + case CONVERT (A52_3F1R, A52_2F1R): + case CONVERT (A52_3F2R, A52_2F2R): + coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; + coeff[1] = MUL_L (level, clev); + return 7; + + case CONVERT (A52_2F1R, A52_DOLBY): + coeff[0] = coeff[1] = level; + coeff[2] = level_3db; + return 7; + + case CONVERT (A52_2F1R, A52_STEREO): + coeff[0] = coeff[1] = level; + coeff[2] = MUL_L (level_3db, slev); + return 7; + + case CONVERT (A52_3F1R, A52_DOLBY): + coeff[0] = coeff[2] = level; + coeff[1] = coeff[3] = level_3db; + return 15; + + case CONVERT (A52_3F1R, A52_STEREO): + coeff[0] = coeff[2] = level; + coeff[1] = MUL_L (level, clev); + coeff[3] = MUL_L (level_3db, slev); + return 15; + + case CONVERT (A52_2F2R, A52_DOLBY): + coeff[0] = coeff[1] = level; + coeff[2] = coeff[3] = level_3db; + return 15; + + case CONVERT (A52_2F2R, A52_STEREO): + coeff[0] = coeff[1] = level; + coeff[2] = coeff[3] = MUL_L (level, slev); + return 15; + + case CONVERT (A52_3F2R, A52_DOLBY): + coeff[0] = coeff[2] = level; + coeff[1] = coeff[3] = coeff[4] = level_3db; + return 31; + + case CONVERT (A52_3F2R, A52_2F1R): + coeff[0] = coeff[2] = level; + coeff[1] = MUL_L (level, clev); + coeff[3] = coeff[4] = level_3db; + return 31; + + case CONVERT (A52_3F2R, A52_STEREO): + coeff[0] = coeff[2] = level; + coeff[1] = MUL_L (level, clev); + coeff[3] = coeff[4] = MUL_L (level, slev); + return 31; + + case CONVERT (A52_3F1R, A52_3F): + coeff[0] = coeff[1] = coeff[2] = level; + coeff[3] = MUL_L (level_3db, slev); + return 13; + + case CONVERT (A52_3F2R, A52_3F): + coeff[0] = coeff[1] = coeff[2] = level; + coeff[3] = coeff[4] = MUL_L (level, slev); + return 29; + + case CONVERT (A52_2F2R, A52_2F1R): + coeff[0] = coeff[1] = level; + coeff[2] = coeff[3] = level_3db; + return 12; + + case CONVERT (A52_3F2R, A52_3F1R): + coeff[0] = coeff[1] = coeff[2] = level; + coeff[3] = coeff[4] = level_3db; + return 24; + + case CONVERT (A52_2F1R, A52_2F2R): + coeff[0] = coeff[1] = level; + coeff[2] = level_3db; + return 0; + + case CONVERT (A52_3F1R, A52_2F2R): + coeff[0] = coeff[2] = level; + coeff[1] = MUL_L (level, clev); + coeff[3] = level_3db; + return 7; + + case CONVERT (A52_3F1R, A52_3F2R): + coeff[0] = coeff[1] = coeff[2] = level; + coeff[3] = level_3db; + return 0; + + case CONVERT (A52_CHANNEL, A52_CHANNEL1): + coeff[0] = level; + coeff[1] = 0; + return 0; + + case CONVERT (A52_CHANNEL, A52_CHANNEL2): + coeff[0] = 0; + coeff[1] = level; + return 0; + } + + return -1; /* NOTREACHED */ +} + +static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias) +{ + int i; + + for (i = 0; i < 256; i++) + dest[i] += BIAS (src[i]); +} + +static void mix3to1 (sample_t * samples, sample_t bias) +{ + int i; + + for (i = 0; i < 256; i++) + samples[i] += BIAS (samples[i + 256] + samples[i + 512]); +} + +static void mix4to1 (sample_t * samples, sample_t bias) +{ + int i; + + for (i = 0; i < 256; i++) + samples[i] += BIAS (samples[i + 256] + samples[i + 512] + + samples[i + 768]); +} + +static void mix5to1 (sample_t * samples, sample_t bias) +{ + int i; + + for (i = 0; i < 256; i++) + samples[i] += BIAS (samples[i + 256] + samples[i + 512] + + samples[i + 768] + samples[i + 1024]); +} + +static void mix3to2 (sample_t * samples, sample_t bias) +{ + int i; + sample_t common; + + for (i = 0; i < 256; i++) { + common = BIAS (samples[i + 256]); + samples[i] += common; + samples[i + 256] = samples[i + 512] + common; + } +} + +static void mix21to2 (sample_t * left, sample_t * right, sample_t bias) +{ + int i; + sample_t common; + + for (i = 0; i < 256; i++) { + common = BIAS (right[i + 256]); + left[i] += common; + right[i] += common; + } +} + +static void mix21toS (sample_t * samples, sample_t bias) +{ + int i; + sample_t surround; + + for (i = 0; i < 256; i++) { + surround = samples[i + 512]; + samples[i] += BIAS (-surround); + samples[i + 256] += BIAS (surround); + } +} + +static void mix31to2 (sample_t * samples, sample_t bias) +{ + int i; + sample_t common; + + for (i = 0; i < 256; i++) { + common = BIAS (samples[i + 256] + samples[i + 768]); + samples[i] += common; + samples[i + 256] = samples[i + 512] + common; + } +} + +static void mix31toS (sample_t * samples, sample_t bias) +{ + int i; + sample_t common, surround; + + for (i = 0; i < 256; i++) { + common = BIAS (samples[i + 256]); + surround = samples[i + 768]; + samples[i] += common - surround; + samples[i + 256] = samples[i + 512] + common + surround; + } +} + +static void mix22toS (sample_t * samples, sample_t bias) +{ + int i; + sample_t surround; + + for (i = 0; i < 256; i++) { + surround = samples[i + 512] + samples[i + 768]; + samples[i] += BIAS (-surround); + samples[i + 256] += BIAS (surround); + } +} + +static void mix32to2 (sample_t * samples, sample_t bias) +{ + int i; + sample_t common; + + for (i = 0; i < 256; i++) { + common = BIAS (samples[i + 256]); + samples[i] += common + samples[i + 768]; + samples[i + 256] = common + samples[i + 512] + samples[i + 1024]; + } +} + +static void mix32toS (sample_t * samples, sample_t bias) +{ + int i; + sample_t common, surround; + + for (i = 0; i < 256; i++) { + common = BIAS (samples[i + 256]); + surround = samples[i + 768] + samples[i + 1024]; + samples[i] += common - surround; + samples[i + 256] = samples[i + 512] + common + surround; + } +} + +static void move2to1 (sample_t * src, sample_t * dest, sample_t bias) +{ + int i; + + for (i = 0; i < 256; i++) + dest[i] = BIAS (src[i] + src[i + 256]); +} + +static void zero (sample_t * samples) +{ + int i; + + for (i = 0; i < 256; i++) + samples[i] = 0; +} + +void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias, + level_t clev, level_t slev) +{ + switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) { + + case CONVERT (A52_CHANNEL, A52_CHANNEL2): + memcpy (samples, samples + 256, 256 * sizeof (sample_t)); + break; + + case CONVERT (A52_CHANNEL, A52_MONO): + case CONVERT (A52_STEREO, A52_MONO): + mix_2to1: + mix2to1 (samples, samples + 256, bias); + break; + + case CONVERT (A52_2F1R, A52_MONO): + if (slev == 0) + goto mix_2to1; + case CONVERT (A52_3F, A52_MONO): + mix_3to1: + mix3to1 (samples, bias); + break; + + case CONVERT (A52_3F1R, A52_MONO): + if (slev == 0) + goto mix_3to1; + case CONVERT (A52_2F2R, A52_MONO): + if (slev == 0) + goto mix_2to1; + mix4to1 (samples, bias); + break; + + case CONVERT (A52_3F2R, A52_MONO): + if (slev == 0) + goto mix_3to1; + mix5to1 (samples, bias); + break; + + case CONVERT (A52_MONO, A52_DOLBY): + memcpy (samples + 256, samples, 256 * sizeof (sample_t)); + break; + + case CONVERT (A52_3F, A52_STEREO): + case CONVERT (A52_3F, A52_DOLBY): + mix_3to2: + mix3to2 (samples, bias); + break; + + case CONVERT (A52_2F1R, A52_STEREO): + if (slev == 0) + break; + mix21to2 (samples, samples + 256, bias); + break; + + case CONVERT (A52_2F1R, A52_DOLBY): + mix21toS (samples, bias); + break; + + case CONVERT (A52_3F1R, A52_STEREO): + if (slev == 0) + goto mix_3to2; + mix31to2 (samples, bias); + break; + + case CONVERT (A52_3F1R, A52_DOLBY): + mix31toS (samples, bias); + break; + + case CONVERT (A52_2F2R, A52_STEREO): + if (slev == 0) + break; + mix2to1 (samples, samples + 512, bias); + mix2to1 (samples + 256, samples + 768, bias); + break; + + case CONVERT (A52_2F2R, A52_DOLBY): + mix22toS (samples, bias); + break; + + case CONVERT (A52_3F2R, A52_STEREO): + if (slev == 0) + goto mix_3to2; + mix32to2 (samples, bias); + break; + + case CONVERT (A52_3F2R, A52_DOLBY): + mix32toS (samples, bias); + break; + + case CONVERT (A52_3F1R, A52_3F): + if (slev == 0) + break; + mix21to2 (samples, samples + 512, bias); + break; + + case CONVERT (A52_3F2R, A52_3F): + if (slev == 0) + break; + mix2to1 (samples, samples + 768, bias); + mix2to1 (samples + 512, samples + 1024, bias); + break; + + case CONVERT (A52_3F1R, A52_2F1R): + mix3to2 (samples, bias); + memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); + break; + + case CONVERT (A52_2F2R, A52_2F1R): + mix2to1 (samples + 512, samples + 768, bias); + break; + + case CONVERT (A52_3F2R, A52_2F1R): + mix3to2 (samples, bias); + move2to1 (samples + 768, samples + 512, bias); + break; + + case CONVERT (A52_3F2R, A52_3F1R): + mix2to1 (samples + 768, samples + 1024, bias); + break; + + case CONVERT (A52_2F1R, A52_2F2R): + memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t)); + break; + + case CONVERT (A52_3F1R, A52_2F2R): + mix3to2 (samples, bias); + memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); + break; + + case CONVERT (A52_3F2R, A52_2F2R): + mix3to2 (samples, bias); + memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); + memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t)); + break; + + case CONVERT (A52_3F1R, A52_3F2R): + memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t)); + break; + } +} + +void a52_upmix (sample_t * samples, int acmod, int output) +{ + switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) { + + case CONVERT (A52_CHANNEL, A52_CHANNEL2): + memcpy (samples + 256, samples, 256 * sizeof (sample_t)); + break; + + case CONVERT (A52_3F2R, A52_MONO): + zero (samples + 1024); + case CONVERT (A52_3F1R, A52_MONO): + case CONVERT (A52_2F2R, A52_MONO): + zero (samples + 768); + case CONVERT (A52_3F, A52_MONO): + case CONVERT (A52_2F1R, A52_MONO): + zero (samples + 512); + case CONVERT (A52_CHANNEL, A52_MONO): + case CONVERT (A52_STEREO, A52_MONO): + zero (samples + 256); + break; + + case CONVERT (A52_3F2R, A52_STEREO): + case CONVERT (A52_3F2R, A52_DOLBY): + zero (samples + 1024); + case CONVERT (A52_3F1R, A52_STEREO): + case CONVERT (A52_3F1R, A52_DOLBY): + zero (samples + 768); + case CONVERT (A52_3F, A52_STEREO): + case CONVERT (A52_3F, A52_DOLBY): + mix_3to2: + memcpy (samples + 512, samples + 256, 256 * sizeof (sample_t)); + zero (samples + 256); + break; + + case CONVERT (A52_2F2R, A52_STEREO): + case CONVERT (A52_2F2R, A52_DOLBY): + zero (samples + 768); + case CONVERT (A52_2F1R, A52_STEREO): + case CONVERT (A52_2F1R, A52_DOLBY): + zero (samples + 512); + break; + + case CONVERT (A52_3F2R, A52_3F): + zero (samples + 1024); + case CONVERT (A52_3F1R, A52_3F): + case CONVERT (A52_2F2R, A52_2F1R): + zero (samples + 768); + break; + + case CONVERT (A52_3F2R, A52_3F1R): + zero (samples + 1024); + break; + + case CONVERT (A52_3F2R, A52_2F1R): + zero (samples + 1024); + case CONVERT (A52_3F1R, A52_2F1R): + mix_31to21: + memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t)); + goto mix_3to2; + + case CONVERT (A52_3F2R, A52_2F2R): + memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t)); + goto mix_31to21; + } +} diff --git a/mpeg4/src/libavcodec/liba52/imdct.c b/mpeg4/src/libavcodec/liba52/imdct.c new file mode 100644 index 00000000..21a2a656 --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/imdct.c @@ -0,0 +1,411 @@ +/* + * imdct.c + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * The ifft algorithms in this file have been largely inspired by Dan + * Bernstein's work, djbfft, available at http://cr.yp.to/djbfft.html + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "a52.h" +#include "a52_internal.h" +#include "mm_accel.h" + +typedef struct complex_s { + sample_t real; + sample_t imag; +} complex_t; + +static uint8_t fftorder[] = { + 0,128, 64,192, 32,160,224, 96, 16,144, 80,208,240,112, 48,176, + 8,136, 72,200, 40,168,232,104,248,120, 56,184, 24,152,216, 88, + 4,132, 68,196, 36,164,228,100, 20,148, 84,212,244,116, 52,180, + 252,124, 60,188, 28,156,220, 92, 12,140, 76,204,236,108, 44,172, + 2,130, 66,194, 34,162,226, 98, 18,146, 82,210,242,114, 50,178, + 10,138, 74,202, 42,170,234,106,250,122, 58,186, 26,154,218, 90, + 254,126, 62,190, 30,158,222, 94, 14,142, 78,206,238,110, 46,174, + 6,134, 70,198, 38,166,230,102,246,118, 54,182, 22,150,214, 86 +}; + +/* Root values for IFFT */ +static sample_t roots16[3]; +static sample_t roots32[7]; +static sample_t roots64[15]; +static sample_t roots128[31]; + +/* Twiddle factors for IMDCT */ +static complex_t pre1[128]; +static complex_t post1[64]; +static complex_t pre2[64]; +static complex_t post2[32]; + +static sample_t a52_imdct_window[256]; + +static void (* ifft128) (complex_t * buf); +static void (* ifft64) (complex_t * buf); + +static inline void ifft2 (complex_t * buf) +{ + sample_t r, i; + + r = buf[0].real; + i = buf[0].imag; + buf[0].real += buf[1].real; + buf[0].imag += buf[1].imag; + buf[1].real = r - buf[1].real; + buf[1].imag = i - buf[1].imag; +} + +static inline void ifft4 (complex_t * buf) +{ + sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; + + tmp1 = buf[0].real + buf[1].real; + tmp2 = buf[3].real + buf[2].real; + tmp3 = buf[0].imag + buf[1].imag; + tmp4 = buf[2].imag + buf[3].imag; + tmp5 = buf[0].real - buf[1].real; + tmp6 = buf[0].imag - buf[1].imag; + tmp7 = buf[2].imag - buf[3].imag; + tmp8 = buf[3].real - buf[2].real; + + buf[0].real = tmp1 + tmp2; + buf[0].imag = tmp3 + tmp4; + buf[2].real = tmp1 - tmp2; + buf[2].imag = tmp3 - tmp4; + buf[1].real = tmp5 + tmp7; + buf[1].imag = tmp6 + tmp8; + buf[3].real = tmp5 - tmp7; + buf[3].imag = tmp6 - tmp8; +} + +/* basic radix-2 ifft butterfly */ + +#define BUTTERFLY_0(t0,t1,W0,W1,d0,d1) do { \ + t0 = MUL (W1, d1) + MUL (W0, d0); \ + t1 = MUL (W0, d1) - MUL (W1, d0); \ +} while (0) + +/* radix-2 ifft butterfly with bias */ + +#define BUTTERFLY_B(t0,t1,W0,W1,d0,d1) do { \ + t0 = BIAS (MUL (d1, W1) + MUL (d0, W0)); \ + t1 = BIAS (MUL (d1, W0) - MUL (d0, W1)); \ +} while (0) + +/* the basic split-radix ifft butterfly */ + +#define BUTTERFLY(a0,a1,a2,a3,wr,wi) do { \ + BUTTERFLY_0 (tmp5, tmp6, wr, wi, a2.real, a2.imag); \ + BUTTERFLY_0 (tmp8, tmp7, wr, wi, a3.imag, a3.real); \ + tmp1 = tmp5 + tmp7; \ + tmp2 = tmp6 + tmp8; \ + tmp3 = tmp6 - tmp8; \ + tmp4 = tmp7 - tmp5; \ + a2.real = a0.real - tmp1; \ + a2.imag = a0.imag - tmp2; \ + a3.real = a1.real - tmp3; \ + a3.imag = a1.imag - tmp4; \ + a0.real += tmp1; \ + a0.imag += tmp2; \ + a1.real += tmp3; \ + a1.imag += tmp4; \ +} while (0) + +/* split-radix ifft butterfly, specialized for wr=1 wi=0 */ + +#define BUTTERFLY_ZERO(a0,a1,a2,a3) do { \ + tmp1 = a2.real + a3.real; \ + tmp2 = a2.imag + a3.imag; \ + tmp3 = a2.imag - a3.imag; \ + tmp4 = a3.real - a2.real; \ + a2.real = a0.real - tmp1; \ + a2.imag = a0.imag - tmp2; \ + a3.real = a1.real - tmp3; \ + a3.imag = a1.imag - tmp4; \ + a0.real += tmp1; \ + a0.imag += tmp2; \ + a1.real += tmp3; \ + a1.imag += tmp4; \ +} while (0) + +/* split-radix ifft butterfly, specialized for wr=wi */ + +#define BUTTERFLY_HALF(a0,a1,a2,a3,w) do { \ + tmp5 = MUL (a2.real + a2.imag, w); \ + tmp6 = MUL (a2.imag - a2.real, w); \ + tmp7 = MUL (a3.real - a3.imag, w); \ + tmp8 = MUL (a3.imag + a3.real, w); \ + tmp1 = tmp5 + tmp7; \ + tmp2 = tmp6 + tmp8; \ + tmp3 = tmp6 - tmp8; \ + tmp4 = tmp7 - tmp5; \ + a2.real = a0.real - tmp1; \ + a2.imag = a0.imag - tmp2; \ + a3.real = a1.real - tmp3; \ + a3.imag = a1.imag - tmp4; \ + a0.real += tmp1; \ + a0.imag += tmp2; \ + a1.real += tmp3; \ + a1.imag += tmp4; \ +} while (0) + +static inline void ifft8 (complex_t * buf) +{ + sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; + + ifft4 (buf); + ifft2 (buf + 4); + ifft2 (buf + 6); + BUTTERFLY_ZERO (buf[0], buf[2], buf[4], buf[6]); + BUTTERFLY_HALF (buf[1], buf[3], buf[5], buf[7], roots16[1]); +} + +static void ifft_pass (complex_t * buf, sample_t * weight, int n) +{ + complex_t * buf1; + complex_t * buf2; + complex_t * buf3; + sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; + int i; + + buf++; + buf1 = buf + n; + buf2 = buf + 2 * n; + buf3 = buf + 3 * n; + + BUTTERFLY_ZERO (buf[-1], buf1[-1], buf2[-1], buf3[-1]); + + i = n - 1; + + do { + BUTTERFLY (buf[0], buf1[0], buf2[0], buf3[0], + weight[0], weight[2*i-n]); + buf++; + buf1++; + buf2++; + buf3++; + weight++; + } while (--i); +} + +static void ifft16 (complex_t * buf) +{ + ifft8 (buf); + ifft4 (buf + 8); + ifft4 (buf + 12); + ifft_pass (buf, roots16, 4); +} + +static void ifft32 (complex_t * buf) +{ + ifft16 (buf); + ifft8 (buf + 16); + ifft8 (buf + 24); + ifft_pass (buf, roots32, 8); +} + +static void ifft64_c (complex_t * buf) +{ + ifft32 (buf); + ifft16 (buf + 32); + ifft16 (buf + 48); + ifft_pass (buf, roots64, 16); +} + +static void ifft128_c (complex_t * buf) +{ + ifft32 (buf); + ifft16 (buf + 32); + ifft16 (buf + 48); + ifft_pass (buf, roots64, 16); + + ifft32 (buf + 64); + ifft32 (buf + 96); + ifft_pass (buf, roots128, 32); +} + +void a52_imdct_512 (sample_t * data, sample_t * delay, sample_t bias) +{ + int i, k; + sample_t t_r, t_i, a_r, a_i, b_r, b_i, w_1, w_2; + const sample_t * window = a52_imdct_window; + complex_t buf[128]; + + for (i = 0; i < 128; i++) { + k = fftorder[i]; + t_r = pre1[i].real; + t_i = pre1[i].imag; + BUTTERFLY_0 (buf[i].real, buf[i].imag, t_r, t_i, data[k], data[255-k]); + } + + ifft128 (buf); + + /* Post IFFT complex multiply plus IFFT complex conjugate*/ + /* Window and convert to real valued signal */ + for (i = 0; i < 64; i++) { + /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */ + t_r = post1[i].real; + t_i = post1[i].imag; + BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf[i].imag, buf[i].real); + BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf[127-i].imag, buf[127-i].real); + + w_1 = window[2*i]; + w_2 = window[255-2*i]; + BUTTERFLY_B (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i]); + delay[2*i] = a_i; + + w_1 = window[2*i+1]; + w_2 = window[254-2*i]; + BUTTERFLY_B (data[2*i+1], data[254-2*i], w_1, w_2, b_r, delay[2*i+1]); + delay[2*i+1] = b_i; + } +} + +void a52_imdct_256 (sample_t * data, sample_t * delay, sample_t bias) +{ + int i, k; + sample_t t_r, t_i, a_r, a_i, b_r, b_i, c_r, c_i, d_r, d_i, w_1, w_2; + const sample_t * window = a52_imdct_window; + complex_t buf1[64], buf2[64]; + + /* Pre IFFT complex multiply plus IFFT cmplx conjugate */ + for (i = 0; i < 64; i++) { + k = fftorder[i]; + t_r = pre2[i].real; + t_i = pre2[i].imag; + BUTTERFLY_0 (buf1[i].real, buf1[i].imag, t_r, t_i, data[k], data[254-k]); + BUTTERFLY_0 (buf2[i].real, buf2[i].imag, t_r, t_i, data[k+1], data[255-k]); + } + + ifft64 (buf1); + ifft64 (buf2); + + /* Post IFFT complex multiply */ + /* Window and convert to real valued signal */ + for (i = 0; i < 32; i++) { + /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */ + t_r = post2[i].real; + t_i = post2[i].imag; + BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf1[i].imag, buf1[i].real); + BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf1[63-i].imag, buf1[63-i].real); + BUTTERFLY_0 (c_r, c_i, t_i, t_r, buf2[i].imag, buf2[i].real); + BUTTERFLY_0 (d_r, d_i, t_r, t_i, buf2[63-i].imag, buf2[63-i].real); + + w_1 = window[2*i]; + w_2 = window[255-2*i]; + BUTTERFLY_B (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i]); + delay[2*i] = c_i; + + w_1 = window[128+2*i]; + w_2 = window[127-2*i]; + BUTTERFLY_B (data[128+2*i], data[127-2*i], w_1, w_2, a_i, delay[127-2*i]); + delay[127-2*i] = c_r; + + w_1 = window[2*i+1]; + w_2 = window[254-2*i]; + BUTTERFLY_B (data[254-2*i], data[2*i+1], w_2, w_1, b_i, delay[2*i+1]); + delay[2*i+1] = d_r; + + w_1 = window[129+2*i]; + w_2 = window[126-2*i]; + BUTTERFLY_B (data[129+2*i], data[126-2*i], w_1, w_2, b_r, delay[126-2*i]); + delay[126-2*i] = d_i; + } +} + +static double besselI0 (double x) +{ + double bessel = 1; + int i = 100; + + do + bessel = bessel * x / (i * i) + 1; + while (--i); + return bessel; +} + +void a52_imdct_init (uint32_t mm_accel) +{ + int i, k; + double sum; + double local_imdct_window[256]; + + /* compute imdct window - kaiser-bessel derived window, alpha = 5.0 */ + sum = 0; + for (i = 0; i < 256; i++) { + sum += besselI0 (i * (256 - i) * (5 * M_PI / 256) * (5 * M_PI / 256)); + local_imdct_window[i] = sum; + } + sum++; + for (i = 0; i < 256; i++) + a52_imdct_window[i] = SAMPLE (sqrt (local_imdct_window[i] / sum)); + + for (i = 0; i < 3; i++) + roots16[i] = SAMPLE (cos ((M_PI / 8) * (i + 1))); + + for (i = 0; i < 7; i++) + roots32[i] = SAMPLE (cos ((M_PI / 16) * (i + 1))); + + for (i = 0; i < 15; i++) + roots64[i] = SAMPLE (cos ((M_PI / 32) * (i + 1))); + + for (i = 0; i < 31; i++) + roots128[i] = SAMPLE (cos ((M_PI / 64) * (i + 1))); + + for (i = 0; i < 64; i++) { + k = fftorder[i] / 2 + 64; + pre1[i].real = SAMPLE (cos ((M_PI / 256) * (k - 0.25))); + pre1[i].imag = SAMPLE (sin ((M_PI / 256) * (k - 0.25))); + } + + for (i = 64; i < 128; i++) { + k = fftorder[i] / 2 + 64; + pre1[i].real = SAMPLE (-cos ((M_PI / 256) * (k - 0.25))); + pre1[i].imag = SAMPLE (-sin ((M_PI / 256) * (k - 0.25))); + } + + for (i = 0; i < 64; i++) { + post1[i].real = SAMPLE (cos ((M_PI / 256) * (i + 0.5))); + post1[i].imag = SAMPLE (sin ((M_PI / 256) * (i + 0.5))); + } + + for (i = 0; i < 64; i++) { + k = fftorder[i] / 4; + pre2[i].real = SAMPLE (cos ((M_PI / 128) * (k - 0.25))); + pre2[i].imag = SAMPLE (sin ((M_PI / 128) * (k - 0.25))); + } + + for (i = 0; i < 32; i++) { + post2[i].real = SAMPLE (cos ((M_PI / 128) * (i + 0.5))); + post2[i].imag = SAMPLE (sin ((M_PI / 128) * (i + 0.5))); + } + +#ifdef LIBA52_DJBFFT + if (mm_accel & MM_ACCEL_DJBFFT) { + ifft128 = (void (*) (complex_t *)) fftc4_un128; + ifft64 = (void (*) (complex_t *)) fftc4_un64; + } else +#endif + { + ifft128 = ifft128_c; + ifft64 = ifft64_c; + } +} diff --git a/mpeg4/src/libavcodec/liba52/mm_accel.h b/mpeg4/src/libavcodec/liba52/mm_accel.h new file mode 100644 index 00000000..9a475f5a --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/mm_accel.h @@ -0,0 +1,42 @@ +/* + * mm_accel.h + * Copyright (C) 2000-2002 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MM_ACCEL_H +#define MM_ACCEL_H + +/* generic accelerations */ +#define MM_ACCEL_DJBFFT 0x00000001 + +/* x86 accelerations */ +#define MM_ACCEL_X86_MMX 0x80000000 +#define MM_ACCEL_X86_3DNOW 0x40000000 +#define MM_ACCEL_X86_MMXEXT 0x20000000 +#define MM_ACCEL_X86_SSE 0x10000000 +#define MM_ACCEL_X86_3DNOWEXT 0x08000000 + +/* PPC accelerations */ +#define MM_ACCEL_PPC_ALTIVEC 0x00010000 + +uint32_t mm_accel (void); + +#endif /* MM_ACCEL_H */ diff --git a/mpeg4/src/libavcodec/liba52/parse.c b/mpeg4/src/libavcodec/liba52/parse.c new file mode 100644 index 00000000..5a070156 --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/parse.c @@ -0,0 +1,939 @@ +/* + * parse.c + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "a52.h" +#include "a52_internal.h" +#include "bitstream.h" +#include "tables.h" + +#if defined(HAVE_MEMALIGN) && !defined(__cplusplus) +/* some systems have memalign() but no declaration for it */ +void * memalign (size_t align, size_t size); +#else +/* assume malloc alignment is sufficient */ +#define memalign(align,size) malloc (size) +#endif + +typedef struct { + quantizer_t q1[2]; + quantizer_t q2[2]; + quantizer_t q4; + int q1_ptr; + int q2_ptr; + int q4_ptr; +} quantizer_set_t; + +static uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3}; + +a52_state_t * a52_init (uint32_t mm_accel) +{ + a52_state_t * state; + int i; + + state = (a52_state_t *) malloc (sizeof (a52_state_t)); + if (state == NULL) + return NULL; + + state->samples = (sample_t *) memalign (16, 256 * 12 * sizeof (sample_t)); + if (state->samples == NULL) { + free (state); + return NULL; + } + + for (i = 0; i < 256 * 12; i++) + state->samples[i] = 0; + + state->downmixed = 1; + + state->lfsr_state = 1; + + a52_imdct_init (mm_accel); + + return state; +} + +sample_t * a52_samples (a52_state_t * state) +{ + return state->samples; +} + +int a52_syncinfo (uint8_t * buf, int * flags, + int * sample_rate, int * bit_rate) +{ + static int rate[] = { 32, 40, 48, 56, 64, 80, 96, 112, + 128, 160, 192, 224, 256, 320, 384, 448, + 512, 576, 640}; + static uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01}; + int frmsizecod; + int bitrate; + int half; + int acmod; + + if ((buf[0] != 0x0b) || (buf[1] != 0x77)) /* syncword */ + return 0; + + if (buf[5] >= 0x60) /* bsid >= 12 */ + return 0; + half = halfrate[buf[5] >> 3]; + + /* acmod, dsurmod and lfeon */ + acmod = buf[6] >> 5; + *flags = ((((buf[6] & 0xf8) == 0x50) ? A52_DOLBY : acmod) | + ((buf[6] & lfeon[acmod]) ? A52_LFE : 0)); + + frmsizecod = buf[4] & 63; + if (frmsizecod >= 38) + return 0; + bitrate = rate [frmsizecod >> 1]; + *bit_rate = (bitrate * 1000) >> half; + + switch (buf[4] & 0xc0) { + case 0: + *sample_rate = 48000 >> half; + return 4 * bitrate; + case 0x40: + *sample_rate = 44100 >> half; + return 2 * (320 * bitrate / 147 + (frmsizecod & 1)); + case 0x80: + *sample_rate = 32000 >> half; + return 6 * bitrate; + default: + return 0; + } +} + +int a52_frame (a52_state_t * state, uint8_t * buf, int * flags, + level_t * level, sample_t bias) +{ + static level_t clev[4] = { LEVEL (LEVEL_3DB), LEVEL (LEVEL_45DB), + LEVEL (LEVEL_6DB), LEVEL (LEVEL_45DB) }; + static level_t slev[4] = { LEVEL (LEVEL_3DB), LEVEL (LEVEL_6DB), + 0, LEVEL (LEVEL_6DB) }; + int chaninfo; + int acmod; + + state->fscod = buf[4] >> 6; + state->halfrate = halfrate[buf[5] >> 3]; + state->acmod = acmod = buf[6] >> 5; + + a52_bitstream_set_ptr (state, buf + 6); + bitstream_get (state, 3); /* skip acmod we already parsed */ + + if ((acmod == 2) && (bitstream_get (state, 2) == 2)) /* dsurmod */ + acmod = A52_DOLBY; + + state->clev = state->slev = 0; + + if ((acmod & 1) && (acmod != 1)) + state->clev = clev[bitstream_get (state, 2)]; /* cmixlev */ + + if (acmod & 4) + state->slev = slev[bitstream_get (state, 2)]; /* surmixlev */ + + state->lfeon = bitstream_get (state, 1); + + state->output = a52_downmix_init (acmod, *flags, level, + state->clev, state->slev); + if (state->output < 0) + return 1; + if (state->lfeon && (*flags & A52_LFE)) + state->output |= A52_LFE; + *flags = state->output; + /* the 2* compensates for differences in imdct */ + state->dynrng = state->level = MUL_C (*level, 2); + state->bias = bias; + state->dynrnge = 1; + state->dynrngcall = NULL; + state->cplba.deltbae = DELTA_BIT_NONE; + state->ba[0].deltbae = state->ba[1].deltbae = state->ba[2].deltbae = + state->ba[3].deltbae = state->ba[4].deltbae = DELTA_BIT_NONE; + + chaninfo = !acmod; + do { + bitstream_get (state, 5); /* dialnorm */ + if (bitstream_get (state, 1)) /* compre */ + bitstream_get (state, 8); /* compr */ + if (bitstream_get (state, 1)) /* langcode */ + bitstream_get (state, 8); /* langcod */ + if (bitstream_get (state, 1)) /* audprodie */ + bitstream_get (state, 7); /* mixlevel + roomtyp */ + } while (chaninfo--); + + bitstream_get (state, 2); /* copyrightb + origbs */ + + if (bitstream_get (state, 1)) /* timecod1e */ + bitstream_get (state, 14); /* timecod1 */ + if (bitstream_get (state, 1)) /* timecod2e */ + bitstream_get (state, 14); /* timecod2 */ + + if (bitstream_get (state, 1)) { /* addbsie */ + int addbsil; + + addbsil = bitstream_get (state, 6); + do { + bitstream_get (state, 8); /* addbsi */ + } while (addbsil--); + } + + return 0; +} + +void a52_dynrng (a52_state_t * state, + level_t (* call) (level_t, void *), void * data) +{ + state->dynrnge = 0; + if (call) { + state->dynrnge = 1; + state->dynrngcall = call; + state->dynrngdata = data; + } +} + +static int parse_exponents (a52_state_t * state, int expstr, int ngrps, + uint8_t exponent, uint8_t * dest) +{ + int exps; + + while (ngrps--) { + exps = bitstream_get (state, 7); + + exponent += exp_1[exps]; + if (exponent > 24) + return 1; + + switch (expstr) { + case EXP_D45: + *(dest++) = exponent; + *(dest++) = exponent; + case EXP_D25: + *(dest++) = exponent; + case EXP_D15: + *(dest++) = exponent; + } + + exponent += exp_2[exps]; + if (exponent > 24) + return 1; + + switch (expstr) { + case EXP_D45: + *(dest++) = exponent; + *(dest++) = exponent; + case EXP_D25: + *(dest++) = exponent; + case EXP_D15: + *(dest++) = exponent; + } + + exponent += exp_3[exps]; + if (exponent > 24) + return 1; + + switch (expstr) { + case EXP_D45: + *(dest++) = exponent; + *(dest++) = exponent; + case EXP_D25: + *(dest++) = exponent; + case EXP_D15: + *(dest++) = exponent; + } + } + + return 0; +} + +static int parse_deltba (a52_state_t * state, int8_t * deltba) +{ + int deltnseg, deltlen, delta, j; + + memset (deltba, 0, 50); + + deltnseg = bitstream_get (state, 3); + j = 0; + do { + j += bitstream_get (state, 5); + deltlen = bitstream_get (state, 4); + delta = bitstream_get (state, 3); + delta -= (delta >= 4) ? 3 : 4; + if (!deltlen) + continue; + if (j + deltlen >= 50) + return 1; + while (deltlen--) + deltba[j++] = delta; + } while (deltnseg--); + + return 0; +} + +static inline int zero_snr_offsets (int nfchans, a52_state_t * state) +{ + int i; + + if ((state->csnroffst) || + (state->chincpl && state->cplba.bai >> 3) || /* cplinu, fsnroffst */ + (state->lfeon && state->lfeba.bai >> 3)) /* fsnroffst */ + return 0; + for (i = 0; i < nfchans; i++) + if (state->ba[i].bai >> 3) /* fsnroffst */ + return 0; + return 1; +} + +static inline int16_t dither_gen (a52_state_t * state) +{ + int16_t nstate; + + nstate = dither_lut[state->lfsr_state >> 8] ^ (state->lfsr_state << 8); + + state->lfsr_state = (uint16_t) nstate; + + return (3 * nstate) >> 2; +} + +#ifndef LIBA52_FIXED +#define COEFF(c,t,l,s,e) (c) = (t) * (s)[e] +#else +#define COEFF(c,_t,_l,s,e) do { \ + quantizer_t t = (_t); \ + level_t l = (_l); \ + int shift = e - 5; \ + sample_t tmp = t * (l >> 16) + ((t * (l & 0xffff)) >> 16); \ + if (shift >= 0) \ + (c) = tmp >> shift; \ + else \ + (c) = tmp << -shift; \ +} while (0) +#endif + +static void coeff_get (a52_state_t * state, sample_t * coeff, + expbap_t * expbap, quantizer_set_t * quant, + level_t level, int dither, int end) +{ + int i; + uint8_t * exp; + int8_t * bap; + +#ifndef LIBA52_FIXED + sample_t factor[25]; + + for (i = 0; i <= 24; i++) + factor[i] = scale_factor[i] * level; +#endif + + exp = expbap->exp; + bap = expbap->bap; + + for (i = 0; i < end; i++) { + int bapi; + + bapi = bap[i]; + switch (bapi) { + case 0: + if (dither) { + COEFF (coeff[i], dither_gen (state), level, factor, exp[i]); + continue; + } else { + coeff[i] = 0; + continue; + } + + case -1: + if (quant->q1_ptr >= 0) { + COEFF (coeff[i], quant->q1[quant->q1_ptr--], level, + factor, exp[i]); + continue; + } else { + int code; + + code = bitstream_get (state, 5); + + quant->q1_ptr = 1; + quant->q1[0] = q_1_2[code]; + quant->q1[1] = q_1_1[code]; + COEFF (coeff[i], q_1_0[code], level, factor, exp[i]); + continue; + } + + case -2: + if (quant->q2_ptr >= 0) { + COEFF (coeff[i], quant->q2[quant->q2_ptr--], level, + factor, exp[i]); + continue; + } else { + int code; + + code = bitstream_get (state, 7); + + quant->q2_ptr = 1; + quant->q2[0] = q_2_2[code]; + quant->q2[1] = q_2_1[code]; + COEFF (coeff[i], q_2_0[code], level, factor, exp[i]); + continue; + } + + case 3: + COEFF (coeff[i], q_3[bitstream_get (state, 3)], level, + factor, exp[i]); + continue; + + case -3: + if (quant->q4_ptr == 0) { + quant->q4_ptr = -1; + COEFF (coeff[i], quant->q4, level, factor, exp[i]); + continue; + } else { + int code; + + code = bitstream_get (state, 7); + + quant->q4_ptr = 0; + quant->q4 = q_4_1[code]; + COEFF (coeff[i], q_4_0[code], level, factor, exp[i]); + continue; + } + + case 4: + COEFF (coeff[i], q_5[bitstream_get (state, 4)], level, + factor, exp[i]); + continue; + + default: + COEFF (coeff[i], bitstream_get_2 (state, bapi) << (16 - bapi), + level, factor, exp[i]); + } + } +} + +static void coeff_get_coupling (a52_state_t * state, int nfchans, + level_t * coeff, sample_t (* samples)[256], + quantizer_set_t * quant, uint8_t dithflag[5]) +{ + int cplbndstrc, bnd, i, i_end, ch; + uint8_t * exp; + int8_t * bap; + level_t cplco[5]; + + exp = state->cpl_expbap.exp; + bap = state->cpl_expbap.bap; + bnd = 0; + cplbndstrc = state->cplbndstrc; + i = state->cplstrtmant; + while (i < state->cplendmant) { + i_end = i + 12; + while (cplbndstrc & 1) { + cplbndstrc >>= 1; + i_end += 12; + } + cplbndstrc >>= 1; + for (ch = 0; ch < nfchans; ch++) + cplco[ch] = MUL_L (state->cplco[ch][bnd], coeff[ch]); + bnd++; + + while (i < i_end) { + quantizer_t cplcoeff; + int bapi; + + bapi = bap[i]; + switch (bapi) { + case 0: + for (ch = 0; ch < nfchans; ch++) + if ((state->chincpl >> ch) & 1) { + if (dithflag[ch]) +#ifndef LIBA52_FIXED + samples[ch][i] = (scale_factor[exp[i]] * + cplco[ch] * dither_gen (state)); +#else + COEFF (samples[ch][i], dither_gen (state), + cplco[ch], scale_factor, exp[i]); +#endif + else + samples[ch][i] = 0; + } + i++; + continue; + + case -1: + if (quant->q1_ptr >= 0) { + cplcoeff = quant->q1[quant->q1_ptr--]; + break; + } else { + int code; + + code = bitstream_get (state, 5); + + quant->q1_ptr = 1; + quant->q1[0] = q_1_2[code]; + quant->q1[1] = q_1_1[code]; + cplcoeff = q_1_0[code]; + break; + } + + case -2: + if (quant->q2_ptr >= 0) { + cplcoeff = quant->q2[quant->q2_ptr--]; + break; + } else { + int code; + + code = bitstream_get (state, 7); + + quant->q2_ptr = 1; + quant->q2[0] = q_2_2[code]; + quant->q2[1] = q_2_1[code]; + cplcoeff = q_2_0[code]; + break; + } + + case 3: + cplcoeff = q_3[bitstream_get (state, 3)]; + break; + + case -3: + if (quant->q4_ptr == 0) { + quant->q4_ptr = -1; + cplcoeff = quant->q4; + break; + } else { + int code; + + code = bitstream_get (state, 7); + + quant->q4_ptr = 0; + quant->q4 = q_4_1[code]; + cplcoeff = q_4_0[code]; + break; + } + + case 4: + cplcoeff = q_5[bitstream_get (state, 4)]; + break; + + default: + cplcoeff = bitstream_get_2 (state, bapi) << (16 - bapi); + } +#ifndef LIBA52_FIXED + cplcoeff *= scale_factor[exp[i]]; +#endif + for (ch = 0; ch < nfchans; ch++) + if ((state->chincpl >> ch) & 1) +#ifndef LIBA52_FIXED + samples[ch][i] = cplcoeff * cplco[ch]; +#else + COEFF (samples[ch][i], cplcoeff, cplco[ch], + scale_factor, exp[i]); +#endif + i++; + } + } +} + +int a52_block (a52_state_t * state) +{ + static const uint8_t nfchans_tbl[] = {2, 1, 2, 3, 3, 4, 4, 5, 1, 1, 2}; + static int rematrix_band[4] = {25, 37, 61, 253}; + int i, nfchans, chaninfo; + uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc, done_cpl; + uint8_t blksw[5], dithflag[5]; + level_t coeff[5]; + int chanbias; + quantizer_set_t quant; + sample_t * samples; + + nfchans = nfchans_tbl[state->acmod]; + + for (i = 0; i < nfchans; i++) + blksw[i] = bitstream_get (state, 1); + + for (i = 0; i < nfchans; i++) + dithflag[i] = bitstream_get (state, 1); + + chaninfo = !state->acmod; + do { + if (bitstream_get (state, 1)) { /* dynrnge */ + int dynrng; + + dynrng = bitstream_get_2 (state, 8); + if (state->dynrnge) { + level_t range; + +#if !defined(LIBA52_FIXED) + range = ((((dynrng & 0x1f) | 0x20) << 13) * + scale_factor[3 - (dynrng >> 5)]); +#else + range = ((dynrng & 0x1f) | 0x20) << (21 + (dynrng >> 5)); +#endif + if (state->dynrngcall) + range = state->dynrngcall (range, state->dynrngdata); + state->dynrng = MUL_L (state->level, range); + } + } + } while (chaninfo--); + + if (bitstream_get (state, 1)) { /* cplstre */ + state->chincpl = 0; + if (bitstream_get (state, 1)) { /* cplinu */ + static uint8_t bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44, + 45, 45, 46, 46, 47, 47, 48, 48}; + int cplbegf; + int cplendf; + int ncplsubnd; + + for (i = 0; i < nfchans; i++) + state->chincpl |= bitstream_get (state, 1) << i; + switch (state->acmod) { + case 0: case 1: + return 1; + case 2: + state->phsflginu = bitstream_get (state, 1); + } + cplbegf = bitstream_get (state, 4); + cplendf = bitstream_get (state, 4); + + if (cplendf + 3 - cplbegf < 0) + return 1; + state->ncplbnd = ncplsubnd = cplendf + 3 - cplbegf; + state->cplstrtbnd = bndtab[cplbegf]; + state->cplstrtmant = cplbegf * 12 + 37; + state->cplendmant = cplendf * 12 + 73; + + state->cplbndstrc = 0; + for (i = 0; i < ncplsubnd - 1; i++) + if (bitstream_get (state, 1)) { + state->cplbndstrc |= 1 << i; + state->ncplbnd--; + } + } + } + + if (state->chincpl) { /* cplinu */ + int j, cplcoe; + + cplcoe = 0; + for (i = 0; i < nfchans; i++) + if ((state->chincpl) >> i & 1) + if (bitstream_get (state, 1)) { /* cplcoe */ + int mstrcplco, cplcoexp, cplcomant; + + cplcoe = 1; + mstrcplco = 3 * bitstream_get (state, 2); + for (j = 0; j < state->ncplbnd; j++) { + cplcoexp = bitstream_get (state, 4); + cplcomant = bitstream_get (state, 4); + if (cplcoexp == 15) + cplcomant <<= 14; + else + cplcomant = (cplcomant | 0x10) << 13; +#ifndef LIBA52_FIXED + state->cplco[i][j] = + cplcomant * scale_factor[cplcoexp + mstrcplco]; +#else + state->cplco[i][j] = (cplcomant << 11) >> (cplcoexp + mstrcplco); +#endif + + } + } + if ((state->acmod == 2) && state->phsflginu && cplcoe) + for (j = 0; j < state->ncplbnd; j++) + if (bitstream_get (state, 1)) /* phsflg */ + state->cplco[1][j] = -state->cplco[1][j]; + } + + if ((state->acmod == 2) && (bitstream_get (state, 1))) { /* rematstr */ + int end; + + state->rematflg = 0; + end = (state->chincpl) ? state->cplstrtmant : 253; /* cplinu */ + i = 0; + do + state->rematflg |= bitstream_get (state, 1) << i; + while (rematrix_band[i++] < end); + } + + cplexpstr = EXP_REUSE; + lfeexpstr = EXP_REUSE; + if (state->chincpl) /* cplinu */ + cplexpstr = bitstream_get (state, 2); + for (i = 0; i < nfchans; i++) + chexpstr[i] = bitstream_get (state, 2); + if (state->lfeon) + lfeexpstr = bitstream_get (state, 1); + + for (i = 0; i < nfchans; i++) + if (chexpstr[i] != EXP_REUSE) { + if ((state->chincpl >> i) & 1) + state->endmant[i] = state->cplstrtmant; + else { + int chbwcod; + + chbwcod = bitstream_get (state, 6); + if (chbwcod > 60) + return 1; + state->endmant[i] = chbwcod * 3 + 73; + } + } + + do_bit_alloc = 0; + + if (cplexpstr != EXP_REUSE) { + int cplabsexp, ncplgrps; + + do_bit_alloc = 64; + ncplgrps = ((state->cplendmant - state->cplstrtmant) / + (3 << (cplexpstr - 1))); + cplabsexp = bitstream_get (state, 4) << 1; + if (parse_exponents (state, cplexpstr, ncplgrps, cplabsexp, + state->cpl_expbap.exp + state->cplstrtmant)) + return 1; + } + for (i = 0; i < nfchans; i++) + if (chexpstr[i] != EXP_REUSE) { + int grp_size, nchgrps; + + do_bit_alloc |= 1 << i; + grp_size = 3 << (chexpstr[i] - 1); + nchgrps = (state->endmant[i] + grp_size - 4) / grp_size; + state->fbw_expbap[i].exp[0] = bitstream_get (state, 4); + if (parse_exponents (state, chexpstr[i], nchgrps, + state->fbw_expbap[i].exp[0], + state->fbw_expbap[i].exp + 1)) + return 1; + bitstream_get (state, 2); /* gainrng */ + } + if (lfeexpstr != EXP_REUSE) { + do_bit_alloc |= 32; + state->lfe_expbap.exp[0] = bitstream_get (state, 4); + if (parse_exponents (state, lfeexpstr, 2, state->lfe_expbap.exp[0], + state->lfe_expbap.exp + 1)) + return 1; + } + + if (bitstream_get (state, 1)) { /* baie */ + do_bit_alloc = 127; + state->bai = bitstream_get (state, 11); + } + if (bitstream_get (state, 1)) { /* snroffste */ + do_bit_alloc = 127; + state->csnroffst = bitstream_get (state, 6); + if (state->chincpl) /* cplinu */ + state->cplba.bai = bitstream_get (state, 7); + for (i = 0; i < nfchans; i++) + state->ba[i].bai = bitstream_get (state, 7); + if (state->lfeon) + state->lfeba.bai = bitstream_get (state, 7); + } + if ((state->chincpl) && (bitstream_get (state, 1))) { /* cplleake */ + do_bit_alloc |= 64; + state->cplfleak = 9 - bitstream_get (state, 3); + state->cplsleak = 9 - bitstream_get (state, 3); + } + + if (bitstream_get (state, 1)) { /* deltbaie */ + do_bit_alloc = 127; + if (state->chincpl) /* cplinu */ + state->cplba.deltbae = bitstream_get (state, 2); + for (i = 0; i < nfchans; i++) + state->ba[i].deltbae = bitstream_get (state, 2); + if (state->chincpl && /* cplinu */ + (state->cplba.deltbae == DELTA_BIT_NEW) && + parse_deltba (state, state->cplba.deltba)) + return 1; + for (i = 0; i < nfchans; i++) + if ((state->ba[i].deltbae == DELTA_BIT_NEW) && + parse_deltba (state, state->ba[i].deltba)) + return 1; + } + + if (do_bit_alloc) { + if (zero_snr_offsets (nfchans, state)) { + memset (state->cpl_expbap.bap, 0, sizeof (state->cpl_expbap.bap)); + for (i = 0; i < nfchans; i++) + memset (state->fbw_expbap[i].bap, 0, + sizeof (state->fbw_expbap[i].bap)); + memset (state->lfe_expbap.bap, 0, sizeof (state->lfe_expbap.bap)); + } else { + if (state->chincpl && (do_bit_alloc & 64)) /* cplinu */ + a52_bit_allocate (state, &state->cplba, state->cplstrtbnd, + state->cplstrtmant, state->cplendmant, + state->cplfleak << 8, state->cplsleak << 8, + &state->cpl_expbap); + for (i = 0; i < nfchans; i++) + if (do_bit_alloc & (1 << i)) + a52_bit_allocate (state, state->ba + i, 0, 0, + state->endmant[i], 0, 0, + state->fbw_expbap +i); + if (state->lfeon && (do_bit_alloc & 32)) { + state->lfeba.deltbae = DELTA_BIT_NONE; + a52_bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0, + &state->lfe_expbap); + } + } + } + + if (bitstream_get (state, 1)) { /* skiple */ + i = bitstream_get (state, 9); /* skipl */ + while (i--) + bitstream_get (state, 8); + } + + samples = state->samples; + if (state->output & A52_LFE) + samples += 256; /* shift for LFE channel */ + + chanbias = a52_downmix_coeff (coeff, state->acmod, state->output, + state->dynrng, state->clev, state->slev); + + quant.q1_ptr = quant.q2_ptr = quant.q4_ptr = -1; + done_cpl = 0; + + for (i = 0; i < nfchans; i++) { + int j; + + coeff_get (state, samples + 256 * i, state->fbw_expbap +i, &quant, + coeff[i], dithflag[i], state->endmant[i]); + + if ((state->chincpl >> i) & 1) { + if (!done_cpl) { + done_cpl = 1; + coeff_get_coupling (state, nfchans, coeff, + (sample_t (*)[256])samples, &quant, + dithflag); + } + j = state->cplendmant; + } else + j = state->endmant[i]; + do + (samples + 256 * i)[j] = 0; + while (++j < 256); + } + + if (state->acmod == 2) { + int j, end, band, rematflg; + + end = ((state->endmant[0] < state->endmant[1]) ? + state->endmant[0] : state->endmant[1]); + + i = 0; + j = 13; + rematflg = state->rematflg; + do { + if (! (rematflg & 1)) { + rematflg >>= 1; + j = rematrix_band[i++]; + continue; + } + rematflg >>= 1; + band = rematrix_band[i++]; + if (band > end) + band = end; + do { + sample_t tmp0, tmp1; + + tmp0 = samples[j]; + tmp1 = (samples+256)[j]; + samples[j] = tmp0 + tmp1; + (samples+256)[j] = tmp0 - tmp1; + } while (++j < band); + } while (j < end); + } + + if (state->lfeon) { + if (state->output & A52_LFE) { + coeff_get (state, samples - 256, &state->lfe_expbap, &quant, + state->dynrng, 0, 7); + for (i = 7; i < 256; i++) + (samples-256)[i] = 0; + a52_imdct_512 (samples - 256, samples + 1536 - 256, state->bias); + } else { + /* just skip the LFE coefficients */ + coeff_get (state, samples + 1280, &state->lfe_expbap, &quant, + 0, 0, 7); + } + } + + i = 0; + if (nfchans_tbl[state->output & A52_CHANNEL_MASK] < nfchans) + for (i = 1; i < nfchans; i++) + if (blksw[i] != blksw[0]) + break; + + if (i < nfchans) { + if (state->downmixed) { + state->downmixed = 0; + a52_upmix (samples + 1536, state->acmod, state->output); + } + + for (i = 0; i < nfchans; i++) { + sample_t bias; + + bias = 0; + if (!(chanbias & (1 << i))) + bias = state->bias; + + if (coeff[i]) { + if (blksw[i]) + a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i, + bias); + else + a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i, + bias); + } else { + int j; + + for (j = 0; j < 256; j++) + (samples + 256 * i)[j] = bias; + } + } + + a52_downmix (samples, state->acmod, state->output, state->bias, + state->clev, state->slev); + } else { + nfchans = nfchans_tbl[state->output & A52_CHANNEL_MASK]; + + a52_downmix (samples, state->acmod, state->output, 0, + state->clev, state->slev); + + if (!state->downmixed) { + state->downmixed = 1; + a52_downmix (samples + 1536, state->acmod, state->output, 0, + state->clev, state->slev); + } + + if (blksw[0]) + for (i = 0; i < nfchans; i++) + a52_imdct_256 (samples + 256 * i, samples + 1536 + 256 * i, + state->bias); + else + for (i = 0; i < nfchans; i++) + a52_imdct_512 (samples + 256 * i, samples + 1536 + 256 * i, + state->bias); + } + + return 0; +} + +void a52_free (a52_state_t * state) +{ + free (state->samples); + free (state); +} diff --git a/mpeg4/src/libavcodec/liba52/resample.c b/mpeg4/src/libavcodec/liba52/resample.c new file mode 100644 index 00000000..faa6877f --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/resample.c @@ -0,0 +1,43 @@ + +// a52_resample_init should find the requested converter (from type flags -> +// given number of channels) and set up some function pointers... + +// a52_resample() should do the conversion. + +#include "a52.h" +#include "mm_accel.h" +#include "config.h" +#include "../libpostproc/mangle.h" + +int (* a52_resample) (float * _f, int16_t * s16)=NULL; + +#include "resample_c.c" + +#ifdef ARCH_X86 +#include "resample_mmx.c" +#endif + +void* a52_resample_init(uint32_t mm_accel,int flags,int chans){ +void* tmp; + +#ifdef ARCH_X86 + if(mm_accel&MM_ACCEL_X86_MMX){ + tmp=a52_resample_MMX(flags,chans); + if(tmp){ + if(a52_resample==NULL) av_log(NULL, AV_LOG_INFO, "Using MMX optimized resampler\n"); + a52_resample=tmp; + return tmp; + } + } +#endif + + tmp=a52_resample_C(flags,chans); + if(tmp){ + if(a52_resample==NULL) av_log(NULL, AV_LOG_INFO, "No accelerated resampler found\n"); + a52_resample=tmp; + return tmp; + } + + av_log(NULL, AV_LOG_ERROR, "Unimplemented resampler for mode 0x%X -> %d channels conversion - Contact MPlayer developers!\n", flags, chans); + return NULL; +} diff --git a/mpeg4/src/libavcodec/liba52/resample_c.c b/mpeg4/src/libavcodec/liba52/resample_c.c new file mode 100644 index 00000000..a618ec6e --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/resample_c.c @@ -0,0 +1,183 @@ +// this code is based on a52dec/libao/audio_out_oss.c + +static inline int16_t convert (int32_t i) +{ + if (i > 0x43c07fff) + return 32767; + else if (i < 0x43bf8000) + return -32768; + else + return i - 0x43c00000; +} + +static int a52_resample_MONO_to_5_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[5*i] = s16[5*i+1] = s16[5*i+2] = s16[5*i+3] = 0; + s16[5*i+4] = convert (f[i]); + } + return 5*256; +} + +static int a52_resample_MONO_to_1_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[i] = convert (f[i]); + } + return 1*256; +} + +static int a52_resample_STEREO_to_2_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[2*i] = convert (f[i]); + s16[2*i+1] = convert (f[i+256]); + } + return 2*256; +} + +static int a52_resample_3F_to_5_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[5*i] = convert (f[i]); + s16[5*i+1] = convert (f[i+512]); + s16[5*i+2] = s16[5*i+3] = 0; + s16[5*i+4] = convert (f[i+256]); + } + return 5*256; +} + +static int a52_resample_2F_2R_to_4_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[4*i] = convert (f[i]); + s16[4*i+1] = convert (f[i+256]); + s16[4*i+2] = convert (f[i+512]); + s16[4*i+3] = convert (f[i+768]); + } + return 4*256; +} + +static int a52_resample_3F_2R_to_5_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[5*i] = convert (f[i]); + s16[5*i+1] = convert (f[i+512]); + s16[5*i+2] = convert (f[i+768]); + s16[5*i+3] = convert (f[i+1024]); + s16[5*i+4] = convert (f[i+256]); + } + return 5*256; +} + +static int a52_resample_MONO_LFE_to_6_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[6*i] = s16[6*i+1] = s16[6*i+2] = s16[6*i+3] = 0; + s16[6*i+4] = convert (f[i+256]); + s16[6*i+5] = convert (f[i]); + } + return 6*256; +} + +static int a52_resample_STEREO_LFE_to_6_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+512]); + s16[6*i+2] = s16[6*i+3] = s16[6*i+4] = 0; + s16[6*i+5] = convert (f[i]); + } + return 6*256; +} + +static int a52_resample_3F_LFE_to_6_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+768]); + s16[6*i+2] = s16[6*i+3] = 0; + s16[6*i+4] = convert (f[i+512]); + s16[6*i+5] = convert (f[i]); + } + return 6*256; +} + +static int a52_resample_2F_2R_LFE_to_6_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+512]); + s16[6*i+2] = convert (f[i+768]); + s16[6*i+3] = convert (f[i+1024]); + s16[6*i+4] = 0; + s16[6*i+5] = convert (f[i]); + } + return 6*256; +} + +static int a52_resample_3F_2R_LFE_to_6_C(float * _f, int16_t * s16){ + int i; + int32_t * f = (int32_t *) _f; + for (i = 0; i < 256; i++) { + s16[6*i] = convert (f[i+256]); + s16[6*i+1] = convert (f[i+768]); + s16[6*i+2] = convert (f[i+1024]); + s16[6*i+3] = convert (f[i+1280]); + s16[6*i+4] = convert (f[i+512]); + s16[6*i+5] = convert (f[i]); + } + return 6*256; +} + + +static void* a52_resample_C(int flags, int ch){ + switch (flags) { + case A52_MONO: + if(ch==5) return a52_resample_MONO_to_5_C; + if(ch==1) return a52_resample_MONO_to_1_C; + break; + case A52_CHANNEL: + case A52_STEREO: + case A52_DOLBY: + if(ch==2) return a52_resample_STEREO_to_2_C; + break; + case A52_3F: + if(ch==5) return a52_resample_3F_to_5_C; + break; + case A52_2F2R: + if(ch==4) return a52_resample_2F_2R_to_4_C; + break; + case A52_3F2R: + if(ch==5) return a52_resample_3F_2R_to_5_C; + break; + case A52_MONO | A52_LFE: + if(ch==6) return a52_resample_MONO_LFE_to_6_C; + break; + case A52_CHANNEL | A52_LFE: + case A52_STEREO | A52_LFE: + case A52_DOLBY | A52_LFE: + if(ch==6) return a52_resample_STEREO_LFE_to_6_C; + break; + case A52_3F | A52_LFE: + if(ch==6) return a52_resample_3F_LFE_to_6_C; + break; + case A52_2F2R | A52_LFE: + if(ch==6) return a52_resample_2F_2R_LFE_to_6_C; + break; + case A52_3F2R | A52_LFE: + if(ch==6) return a52_resample_3F_2R_LFE_to_6_C; + break; + } + return NULL; +} diff --git a/mpeg4/src/libavcodec/liba52/resample_mmx.c b/mpeg4/src/libavcodec/liba52/resample_mmx.c new file mode 100644 index 00000000..a4e313c6 --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/resample_mmx.c @@ -0,0 +1,518 @@ + +// MMX optimizations from Michael Niedermayer (michaelni@gmx.at) (under GPL) + +/* optimization TODO / NOTES + movntq is slightly faster (0.5% with the current test.c benchmark) + (but thats just test.c so that needs to be testd in reallity) + and it would mean (C / MMX2 / MMX / 3DNOW) versions +*/ + +static uint64_t __attribute__((aligned(8))) attribute_used magicF2W= 0x43c0000043c00000LL; +static uint64_t __attribute__((aligned(8))) attribute_used wm1010= 0xFFFF0000FFFF0000LL; +static uint64_t __attribute__((aligned(8))) attribute_used wm0101= 0x0000FFFF0000FFFFLL; +static uint64_t __attribute__((aligned(8))) attribute_used wm1100= 0xFFFFFFFF00000000LL; + +static int a52_resample_MONO_to_5_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; + asm volatile( + "movl $-512, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" + "movq "MANGLE(wm1100)", %%mm3 \n\t" + "movq "MANGLE(wm0101)", %%mm4 \n\t" + "movq "MANGLE(wm1010)", %%mm5 \n\t" + "pxor %%mm6, %%mm6 \n\t" + "1: \n\t" + "movq (%1, %%esi, 2), %%mm0 \n\t" + "movq 8(%1, %%esi, 2), %%mm1 \n\t" + "leal (%%esi, %%esi, 4), %%edi \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "packssdw %%mm1, %%mm0 \n\t" + "movq %%mm0, %%mm1 \n\t" + "pand %%mm4, %%mm0 \n\t" + "pand %%mm5, %%mm1 \n\t" + "movq %%mm6, (%0, %%edi) \n\t" // 0 0 0 0 + "movd %%mm0, 8(%0, %%edi) \n\t" // A 0 + "pand %%mm3, %%mm0 \n\t" + "movd %%mm6, 12(%0, %%edi) \n\t" // 0 0 + "movd %%mm1, 16(%0, %%edi) \n\t" // 0 B + "pand %%mm3, %%mm1 \n\t" + "movd %%mm6, 20(%0, %%edi) \n\t" // 0 0 + "movq %%mm0, 24(%0, %%edi) \n\t" // 0 0 C 0 + "movq %%mm1, 32(%0, %%edi) \n\t" // 0 0 0 B + "addl $8, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+1280), "r" (f+256) + :"%esi", "%edi", "memory" + ); + return 5*256; +} + +static int a52_resample_STEREO_to_2_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; +/* benchmark scores are 0.3% better with SSE but we would need to set bias=0 and premultiply it +#ifdef HAVE_SSE + asm volatile( + "movl $-1024, %%esi \n\t" + "1: \n\t" + "cvtps2pi (%1, %%esi), %%mm0 \n\t" + "cvtps2pi 1024(%1, %%esi), %%mm2\n\t" + "movq %%mm0, %%mm1 \n\t" + "punpcklwd %%mm2, %%mm0 \n\t" + "punpckhwd %%mm2, %%mm1 \n\t" + "movq %%mm0, (%0, %%esi) \n\t" + "movq %%mm1, 8(%0, %%esi) \n\t" + "addl $16, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+512), "r" (f+256) + :"%esi", "memory" + );*/ + asm volatile( + "movl $-1024, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" + "1: \n\t" + "movq (%1, %%esi), %%mm0 \n\t" + "movq 8(%1, %%esi), %%mm1 \n\t" + "movq 1024(%1, %%esi), %%mm2 \n\t" + "movq 1032(%1, %%esi), %%mm3 \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm7, %%mm2 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "packssdw %%mm1, %%mm0 \n\t" + "packssdw %%mm3, %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "punpcklwd %%mm2, %%mm0 \n\t" + "punpckhwd %%mm2, %%mm1 \n\t" + "movq %%mm0, (%0, %%esi) \n\t" + "movq %%mm1, 8(%0, %%esi) \n\t" + "addl $16, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+512), "r" (f+256) + :"%esi", "memory" + ); + return 2*256; +} + +static int a52_resample_3F_to_5_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; + asm volatile( + "movl $-1024, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" + "pxor %%mm6, %%mm6 \n\t" + "movq %%mm7, %%mm5 \n\t" + "punpckldq %%mm6, %%mm5 \n\t" + "1: \n\t" + "movd (%1, %%esi), %%mm0 \n\t" + "punpckldq 2048(%1, %%esi), %%mm0\n\t" + "movd 1024(%1, %%esi), %%mm1 \n\t" + "punpckldq 4(%1, %%esi), %%mm1 \n\t" + "movd 2052(%1, %%esi), %%mm2 \n\t" + "movq %%mm7, %%mm3 \n\t" + "punpckldq 1028(%1, %%esi), %%mm3\n\t" + "movd 8(%1, %%esi), %%mm4 \n\t" + "punpckldq 2056(%1, %%esi), %%mm4\n\t" + "leal (%%esi, %%esi, 4), %%edi \n\t" + "sarl $1, %%edi \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm5, %%mm2 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "psubd %%mm7, %%mm4 \n\t" + "packssdw %%mm6, %%mm0 \n\t" + "packssdw %%mm2, %%mm1 \n\t" + "packssdw %%mm4, %%mm3 \n\t" + "movq %%mm0, (%0, %%edi) \n\t" + "movq %%mm1, 8(%0, %%edi) \n\t" + "movq %%mm3, 16(%0, %%edi) \n\t" + + "movd 1032(%1, %%esi), %%mm1 \n\t" + "punpckldq 12(%1, %%esi), %%mm1\n\t" + "movd 2060(%1, %%esi), %%mm2 \n\t" + "movq %%mm7, %%mm3 \n\t" + "punpckldq 1036(%1, %%esi), %%mm3\n\t" + "pxor %%mm0, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm5, %%mm2 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "packssdw %%mm1, %%mm0 \n\t" + "packssdw %%mm3, %%mm2 \n\t" + "movq %%mm0, 24(%0, %%edi) \n\t" + "movq %%mm2, 32(%0, %%edi) \n\t" + + "addl $16, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+1280), "r" (f+256) + :"%esi", "%edi", "memory" + ); + return 5*256; +} + +static int a52_resample_2F_2R_to_4_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; + asm volatile( + "movl $-1024, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" + "1: \n\t" + "movq (%1, %%esi), %%mm0 \n\t" + "movq 8(%1, %%esi), %%mm1 \n\t" + "movq 1024(%1, %%esi), %%mm2 \n\t" + "movq 1032(%1, %%esi), %%mm3 \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm7, %%mm2 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "packssdw %%mm1, %%mm0 \n\t" + "packssdw %%mm3, %%mm2 \n\t" + "movq 2048(%1, %%esi), %%mm3 \n\t" + "movq 2056(%1, %%esi), %%mm4 \n\t" + "movq 3072(%1, %%esi), %%mm5 \n\t" + "movq 3080(%1, %%esi), %%mm6 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "psubd %%mm7, %%mm4 \n\t" + "psubd %%mm7, %%mm5 \n\t" + "psubd %%mm7, %%mm6 \n\t" + "packssdw %%mm4, %%mm3 \n\t" + "packssdw %%mm6, %%mm5 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm3, %%mm4 \n\t" + "punpcklwd %%mm2, %%mm0 \n\t" + "punpckhwd %%mm2, %%mm1 \n\t" + "punpcklwd %%mm5, %%mm3 \n\t" + "punpckhwd %%mm5, %%mm4 \n\t" + "movq %%mm0, %%mm2 \n\t" + "movq %%mm1, %%mm5 \n\t" + "punpckldq %%mm3, %%mm0 \n\t" + "punpckhdq %%mm3, %%mm2 \n\t" + "punpckldq %%mm4, %%mm1 \n\t" + "punpckhdq %%mm4, %%mm5 \n\t" + "movq %%mm0, (%0, %%esi,2) \n\t" + "movq %%mm2, 8(%0, %%esi,2) \n\t" + "movq %%mm1, 16(%0, %%esi,2) \n\t" + "movq %%mm5, 24(%0, %%esi,2) \n\t" + "addl $16, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+1024), "r" (f+256) + :"%esi", "memory" + ); + return 4*256; +} + +static int a52_resample_3F_2R_to_5_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; + asm volatile( + "movl $-1024, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" + "1: \n\t" + "movd (%1, %%esi), %%mm0 \n\t" + "punpckldq 2048(%1, %%esi), %%mm0\n\t" + "movd 3072(%1, %%esi), %%mm1 \n\t" + "punpckldq 4096(%1, %%esi), %%mm1\n\t" + "movd 1024(%1, %%esi), %%mm2 \n\t" + "punpckldq 4(%1, %%esi), %%mm2 \n\t" + "movd 2052(%1, %%esi), %%mm3 \n\t" + "punpckldq 3076(%1, %%esi), %%mm3\n\t" + "movd 4100(%1, %%esi), %%mm4 \n\t" + "punpckldq 1028(%1, %%esi), %%mm4\n\t" + "movd 8(%1, %%esi), %%mm5 \n\t" + "punpckldq 2056(%1, %%esi), %%mm5\n\t" + "leal (%%esi, %%esi, 4), %%edi \n\t" + "sarl $1, %%edi \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm7, %%mm2 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "psubd %%mm7, %%mm4 \n\t" + "psubd %%mm7, %%mm5 \n\t" + "packssdw %%mm1, %%mm0 \n\t" + "packssdw %%mm3, %%mm2 \n\t" + "packssdw %%mm5, %%mm4 \n\t" + "movq %%mm0, (%0, %%edi) \n\t" + "movq %%mm2, 8(%0, %%edi) \n\t" + "movq %%mm4, 16(%0, %%edi) \n\t" + + "movd 3080(%1, %%esi), %%mm0 \n\t" + "punpckldq 4104(%1, %%esi), %%mm0\n\t" + "movd 1032(%1, %%esi), %%mm1 \n\t" + "punpckldq 12(%1, %%esi), %%mm1\n\t" + "movd 2060(%1, %%esi), %%mm2 \n\t" + "punpckldq 3084(%1, %%esi), %%mm2\n\t" + "movd 4108(%1, %%esi), %%mm3 \n\t" + "punpckldq 1036(%1, %%esi), %%mm3\n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm7, %%mm2 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "packssdw %%mm1, %%mm0 \n\t" + "packssdw %%mm3, %%mm2 \n\t" + "movq %%mm0, 24(%0, %%edi) \n\t" + "movq %%mm2, 32(%0, %%edi) \n\t" + + "addl $16, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+1280), "r" (f+256) + :"%esi", "%edi", "memory" + ); + return 5*256; +} + +static int a52_resample_MONO_LFE_to_6_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; + asm volatile( + "movl $-1024, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" + "pxor %%mm6, %%mm6 \n\t" + "1: \n\t" + "movq 1024(%1, %%esi), %%mm0 \n\t" + "movq 1032(%1, %%esi), %%mm1 \n\t" + "movq (%1, %%esi), %%mm2 \n\t" + "movq 8(%1, %%esi), %%mm3 \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm7, %%mm2 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "packssdw %%mm1, %%mm0 \n\t" + "packssdw %%mm3, %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "punpcklwd %%mm2, %%mm0 \n\t" + "punpckhwd %%mm2, %%mm1 \n\t" + "leal (%%esi, %%esi, 2), %%edi \n\t" + "movq %%mm6, (%0, %%edi) \n\t" + "movd %%mm0, 8(%0, %%edi) \n\t" + "punpckhdq %%mm0, %%mm0 \n\t" + "movq %%mm6, 12(%0, %%edi) \n\t" + "movd %%mm0, 20(%0, %%edi) \n\t" + "movq %%mm6, 24(%0, %%edi) \n\t" + "movd %%mm1, 32(%0, %%edi) \n\t" + "punpckhdq %%mm1, %%mm1 \n\t" + "movq %%mm6, 36(%0, %%edi) \n\t" + "movd %%mm1, 44(%0, %%edi) \n\t" + "addl $16, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+1536), "r" (f+256) + :"%esi", "%edi", "memory" + ); + return 6*256; +} + +static int a52_resample_STEREO_LFE_to_6_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; + asm volatile( + "movl $-1024, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" + "pxor %%mm6, %%mm6 \n\t" + "1: \n\t" + "movq 1024(%1, %%esi), %%mm0 \n\t" + "movq 2048(%1, %%esi), %%mm1 \n\t" + "movq (%1, %%esi), %%mm5 \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm7, %%mm5 \n\t" + "leal (%%esi, %%esi, 2), %%edi \n\t" + + "pxor %%mm4, %%mm4 \n\t" + "packssdw %%mm5, %%mm0 \n\t" // FfAa + "packssdw %%mm4, %%mm1 \n\t" // 00Bb + "punpckhwd %%mm0, %%mm4 \n\t" // F0f0 + "punpcklwd %%mm1, %%mm0 \n\t" // BAba + "movq %%mm0, %%mm1 \n\t" // BAba + "punpckldq %%mm4, %%mm3 \n\t" // f0XX + "punpckldq %%mm6, %%mm0 \n\t" // 00ba + "punpckhdq %%mm1, %%mm3 \n\t" // BAf0 + + "movq %%mm0, (%0, %%edi) \n\t" // 00ba + "punpckhdq %%mm4, %%mm0 \n\t" // F000 + "movq %%mm3, 8(%0, %%edi) \n\t" // BAf0 + "movq %%mm0, 16(%0, %%edi) \n\t" // F000 + "addl $8, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+1536), "r" (f+256) + :"%esi", "%edi", "memory" + ); + return 6*256; +} + +static int a52_resample_3F_LFE_to_6_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; + asm volatile( + "movl $-1024, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" + "pxor %%mm6, %%mm6 \n\t" + "1: \n\t" + "movq 1024(%1, %%esi), %%mm0 \n\t" + "movq 3072(%1, %%esi), %%mm1 \n\t" + "movq 2048(%1, %%esi), %%mm4 \n\t" + "movq (%1, %%esi), %%mm5 \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm7, %%mm4 \n\t" + "psubd %%mm7, %%mm5 \n\t" + "leal (%%esi, %%esi, 2), %%edi \n\t" + + "packssdw %%mm4, %%mm0 \n\t" // EeAa + "packssdw %%mm5, %%mm1 \n\t" // FfBb + "movq %%mm0, %%mm2 \n\t" // EeAa + "punpcklwd %%mm1, %%mm0 \n\t" // BAba + "punpckhwd %%mm1, %%mm2 \n\t" // FEfe + "movq %%mm0, %%mm1 \n\t" // BAba + "punpckldq %%mm6, %%mm0 \n\t" // 00ba + "punpckhdq %%mm1, %%mm1 \n\t" // BABA + + "movq %%mm0, (%0, %%edi) \n\t" + "punpckhdq %%mm2, %%mm0 \n\t" // FE00 + "punpckldq %%mm1, %%mm2 \n\t" // BAfe + "movq %%mm2, 8(%0, %%edi) \n\t" + "movq %%mm0, 16(%0, %%edi) \n\t" + "addl $8, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+1536), "r" (f+256) + :"%esi", "%edi", "memory" + ); + return 6*256; +} + +static int a52_resample_2F_2R_LFE_to_6_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; + asm volatile( + "movl $-1024, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" +// "pxor %%mm6, %%mm6 \n\t" + "1: \n\t" + "movq 1024(%1, %%esi), %%mm0 \n\t" + "movq 2048(%1, %%esi), %%mm1 \n\t" + "movq 3072(%1, %%esi), %%mm2 \n\t" + "movq 4096(%1, %%esi), %%mm3 \n\t" + "movq (%1, %%esi), %%mm5 \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm7, %%mm2 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "psubd %%mm7, %%mm5 \n\t" + "leal (%%esi, %%esi, 2), %%edi \n\t" + + "packssdw %%mm2, %%mm0 \n\t" // CcAa + "packssdw %%mm3, %%mm1 \n\t" // DdBb + "packssdw %%mm5, %%mm5 \n\t" // FfFf + "movq %%mm0, %%mm2 \n\t" // CcAa + "punpcklwd %%mm1, %%mm0 \n\t" // BAba + "punpckhwd %%mm1, %%mm2 \n\t" // DCdc + "pxor %%mm4, %%mm4 \n\t" // 0000 + "punpcklwd %%mm5, %%mm4 \n\t" // F0f0 + "movq %%mm0, %%mm1 \n\t" // BAba + "movq %%mm4, %%mm3 \n\t" // F0f0 + "punpckldq %%mm2, %%mm0 \n\t" // dcba + "punpckhdq %%mm1, %%mm1 \n\t" // BABA + "punpckldq %%mm1, %%mm4 \n\t" // BAf0 + "punpckhdq %%mm3, %%mm2 \n\t" // F0DC + + "movq %%mm0, (%0, %%edi) \n\t" + "movq %%mm4, 8(%0, %%edi) \n\t" + "movq %%mm2, 16(%0, %%edi) \n\t" + "addl $8, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+1536), "r" (f+256) + :"%esi", "%edi", "memory" + ); + return 6*256; +} + +static int a52_resample_3F_2R_LFE_to_6_MMX(float * _f, int16_t * s16){ + int32_t * f = (int32_t *) _f; + asm volatile( + "movl $-1024, %%esi \n\t" + "movq "MANGLE(magicF2W)", %%mm7 \n\t" +// "pxor %%mm6, %%mm6 \n\t" + "1: \n\t" + "movq 1024(%1, %%esi), %%mm0 \n\t" + "movq 3072(%1, %%esi), %%mm1 \n\t" + "movq 4096(%1, %%esi), %%mm2 \n\t" + "movq 5120(%1, %%esi), %%mm3 \n\t" + "movq 2048(%1, %%esi), %%mm4 \n\t" + "movq (%1, %%esi), %%mm5 \n\t" + "psubd %%mm7, %%mm0 \n\t" + "psubd %%mm7, %%mm1 \n\t" + "psubd %%mm7, %%mm2 \n\t" + "psubd %%mm7, %%mm3 \n\t" + "psubd %%mm7, %%mm4 \n\t" + "psubd %%mm7, %%mm5 \n\t" + "leal (%%esi, %%esi, 2), %%edi \n\t" + + "packssdw %%mm2, %%mm0 \n\t" // CcAa + "packssdw %%mm3, %%mm1 \n\t" // DdBb + "packssdw %%mm4, %%mm4 \n\t" // EeEe + "packssdw %%mm5, %%mm5 \n\t" // FfFf + "movq %%mm0, %%mm2 \n\t" // CcAa + "punpcklwd %%mm1, %%mm0 \n\t" // BAba + "punpckhwd %%mm1, %%mm2 \n\t" // DCdc + "punpcklwd %%mm5, %%mm4 \n\t" // FEfe + "movq %%mm0, %%mm1 \n\t" // BAba + "movq %%mm4, %%mm3 \n\t" // FEfe + "punpckldq %%mm2, %%mm0 \n\t" // dcba + "punpckhdq %%mm1, %%mm1 \n\t" // BABA + "punpckldq %%mm1, %%mm4 \n\t" // BAfe + "punpckhdq %%mm3, %%mm2 \n\t" // FEDC + + "movq %%mm0, (%0, %%edi) \n\t" + "movq %%mm4, 8(%0, %%edi) \n\t" + "movq %%mm2, 16(%0, %%edi) \n\t" + "addl $8, %%esi \n\t" + " jnz 1b \n\t" + "emms \n\t" + :: "r" (s16+1536), "r" (f+256) + :"%esi", "%edi", "memory" + ); + return 6*256; +} + + +static void* a52_resample_MMX(int flags, int ch){ + switch (flags) { + case A52_MONO: + if(ch==5) return a52_resample_MONO_to_5_MMX; + break; + case A52_CHANNEL: + case A52_STEREO: + case A52_DOLBY: + if(ch==2) return a52_resample_STEREO_to_2_MMX; + break; + case A52_3F: + if(ch==5) return a52_resample_3F_to_5_MMX; + break; + case A52_2F2R: + if(ch==4) return a52_resample_2F_2R_to_4_MMX; + break; + case A52_3F2R: + if(ch==5) return a52_resample_3F_2R_to_5_MMX; + break; + case A52_MONO | A52_LFE: + if(ch==6) return a52_resample_MONO_LFE_to_6_MMX; + break; + case A52_CHANNEL | A52_LFE: + case A52_STEREO | A52_LFE: + case A52_DOLBY | A52_LFE: + if(ch==6) return a52_resample_STEREO_LFE_to_6_MMX; + break; + case A52_3F | A52_LFE: + if(ch==6) return a52_resample_3F_LFE_to_6_MMX; + break; + case A52_2F2R | A52_LFE: + if(ch==6) return a52_resample_2F_2R_LFE_to_6_MMX; + break; + case A52_3F2R | A52_LFE: + if(ch==6) return a52_resample_3F_2R_LFE_to_6_MMX; + break; + } + return NULL; +} + + diff --git a/mpeg4/src/libavcodec/liba52/tables.h b/mpeg4/src/libavcodec/liba52/tables.h new file mode 100644 index 00000000..7f921c9d --- /dev/null +++ b/mpeg4/src/libavcodec/liba52/tables.h @@ -0,0 +1,246 @@ +/* + * tables.h + * Copyright (C) 2000-2003 Michel Lespinasse + * Copyright (C) 1999-2000 Aaron Holtzman + * + * This file is part of a52dec, a free ATSC A-52 stream decoder. + * See http://liba52.sourceforge.net/ for updates. + * + * a52dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * a52dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +static const int8_t exp_1[128] = { + -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 25,25,25 +}; +static const int8_t exp_2[128] = { + -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 25,25,25 +}; +static const int8_t exp_3[128] = { + -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, + -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, + -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, + -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, + -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, + 25,25,25 +}; + +#define Q(x) ROUND (32768.0 * x) + +#define Q0 Q (-2/3) +#define Q1 Q (0) +#define Q2 Q (2/3) + +static const quantizer_t q_1_0[32] = { + Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, + Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, + Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, + 0, 0, 0, 0, 0 +}; + +static const quantizer_t q_1_1[32] = { + Q0, Q0, Q0, Q1, Q1, Q1, Q2, Q2, Q2, + Q0, Q0, Q0, Q1, Q1, Q1, Q2, Q2, Q2, + Q0, Q0, Q0, Q1, Q1, Q1, Q2, Q2, Q2, + 0, 0, 0, 0, 0 +}; + +static const quantizer_t q_1_2[32] = { + Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2, + Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2, + Q0, Q1, Q2, Q0, Q1, Q2, Q0, Q1, Q2, + 0, 0, 0, 0, 0 +}; + +#undef Q0 +#undef Q1 +#undef Q2 + +#define Q0 Q (-4/5) +#define Q1 Q (-2/5) +#define Q2 Q (0) +#define Q3 Q (2/5) +#define Q4 Q (4/5) + +static const quantizer_t q_2_0[128] = { + Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0, + Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1, + Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2, + Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3, + Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4, + 0,0,0 +}; + +static const quantizer_t q_2_1[128] = { + Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, + Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, + Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, + Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, + Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, + 0,0,0 +}; + +static const quantizer_t q_2_2[128] = { + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, + 0,0,0 +}; + +#undef Q0 +#undef Q1 +#undef Q2 +#undef Q3 +#undef Q4 + +static const quantizer_t q_3[8] = { + Q (-6/7), Q (-4/7), Q (-2/7), Q (0), Q (2/7), Q (4/7), Q (6/7), 0 +}; + +#define Q0 Q (-10/11) +#define Q1 Q (-8/11) +#define Q2 Q (-6/11) +#define Q3 Q (-4/11) +#define Q4 Q (-2/11) +#define Q5 Q (0) +#define Q6 Q (2/11) +#define Q7 Q (4/11) +#define Q8 Q (6/11) +#define Q9 Q (8/11) +#define QA Q (10/11) + +static const quantizer_t q_4_0[128] = { + Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, + Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, + Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, + Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, + Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, + Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, + Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, + Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, + Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, + Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, + QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, + 0, 0, 0, 0, 0, 0, 0 +}; + +static const quantizer_t q_4_1[128] = { + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, + 0, 0, 0, 0, 0, 0, 0 +}; + +#undef Q0 +#undef Q1 +#undef Q2 +#undef Q3 +#undef Q4 +#undef Q5 +#undef Q6 +#undef Q7 +#undef Q8 +#undef Q9 +#undef QA + +static const quantizer_t q_5[16] = { + Q (-14/15), Q (-12/15), Q (-10/15), Q (-8/15), Q (-6/15), + Q (-4/15), Q (-2/15), Q (0), Q (2/15), Q (4/15), + Q (6/15), Q (8/15), Q (10/15), Q (12/15), Q (14/15), 0 +}; + +#ifndef LIBA52_FIXED +static const sample_t scale_factor[25] = { + 0.000030517578125, + 0.0000152587890625, + 0.00000762939453125, + 0.000003814697265625, + 0.0000019073486328125, + 0.00000095367431640625, + 0.000000476837158203125, + 0.0000002384185791015625, + 0.00000011920928955078125, + 0.000000059604644775390625, + 0.0000000298023223876953125, + 0.00000001490116119384765625, + 0.000000007450580596923828125, + 0.0000000037252902984619140625, + 0.00000000186264514923095703125, + 0.000000000931322574615478515625, + 0.0000000004656612873077392578125, + 0.00000000023283064365386962890625, + 0.000000000116415321826934814453125, + 0.0000000000582076609134674072265625, + 0.00000000002910383045673370361328125, + 0.000000000014551915228366851806640625, + 0.0000000000072759576141834259033203125, + 0.00000000000363797880709171295166015625, + 0.000000000001818989403545856475830078125 +}; +#endif + +static const uint16_t dither_lut[256] = { + 0x0000, 0xa011, 0xe033, 0x4022, 0x6077, 0xc066, 0x8044, 0x2055, + 0xc0ee, 0x60ff, 0x20dd, 0x80cc, 0xa099, 0x0088, 0x40aa, 0xe0bb, + 0x21cd, 0x81dc, 0xc1fe, 0x61ef, 0x41ba, 0xe1ab, 0xa189, 0x0198, + 0xe123, 0x4132, 0x0110, 0xa101, 0x8154, 0x2145, 0x6167, 0xc176, + 0x439a, 0xe38b, 0xa3a9, 0x03b8, 0x23ed, 0x83fc, 0xc3de, 0x63cf, + 0x8374, 0x2365, 0x6347, 0xc356, 0xe303, 0x4312, 0x0330, 0xa321, + 0x6257, 0xc246, 0x8264, 0x2275, 0x0220, 0xa231, 0xe213, 0x4202, + 0xa2b9, 0x02a8, 0x428a, 0xe29b, 0xc2ce, 0x62df, 0x22fd, 0x82ec, + 0x8734, 0x2725, 0x6707, 0xc716, 0xe743, 0x4752, 0x0770, 0xa761, + 0x47da, 0xe7cb, 0xa7e9, 0x07f8, 0x27ad, 0x87bc, 0xc79e, 0x678f, + 0xa6f9, 0x06e8, 0x46ca, 0xe6db, 0xc68e, 0x669f, 0x26bd, 0x86ac, + 0x6617, 0xc606, 0x8624, 0x2635, 0x0660, 0xa671, 0xe653, 0x4642, + 0xc4ae, 0x64bf, 0x249d, 0x848c, 0xa4d9, 0x04c8, 0x44ea, 0xe4fb, + 0x0440, 0xa451, 0xe473, 0x4462, 0x6437, 0xc426, 0x8404, 0x2415, + 0xe563, 0x4572, 0x0550, 0xa541, 0x8514, 0x2505, 0x6527, 0xc536, + 0x258d, 0x859c, 0xc5be, 0x65af, 0x45fa, 0xe5eb, 0xa5c9, 0x05d8, + 0xae79, 0x0e68, 0x4e4a, 0xee5b, 0xce0e, 0x6e1f, 0x2e3d, 0x8e2c, + 0x6e97, 0xce86, 0x8ea4, 0x2eb5, 0x0ee0, 0xaef1, 0xeed3, 0x4ec2, + 0x8fb4, 0x2fa5, 0x6f87, 0xcf96, 0xefc3, 0x4fd2, 0x0ff0, 0xafe1, + 0x4f5a, 0xef4b, 0xaf69, 0x0f78, 0x2f2d, 0x8f3c, 0xcf1e, 0x6f0f, + 0xede3, 0x4df2, 0x0dd0, 0xadc1, 0x8d94, 0x2d85, 0x6da7, 0xcdb6, + 0x2d0d, 0x8d1c, 0xcd3e, 0x6d2f, 0x4d7a, 0xed6b, 0xad49, 0x0d58, + 0xcc2e, 0x6c3f, 0x2c1d, 0x8c0c, 0xac59, 0x0c48, 0x4c6a, 0xec7b, + 0x0cc0, 0xacd1, 0xecf3, 0x4ce2, 0x6cb7, 0xcca6, 0x8c84, 0x2c95, + 0x294d, 0x895c, 0xc97e, 0x696f, 0x493a, 0xe92b, 0xa909, 0x0918, + 0xe9a3, 0x49b2, 0x0990, 0xa981, 0x89d4, 0x29c5, 0x69e7, 0xc9f6, + 0x0880, 0xa891, 0xe8b3, 0x48a2, 0x68f7, 0xc8e6, 0x88c4, 0x28d5, + 0xc86e, 0x687f, 0x285d, 0x884c, 0xa819, 0x0808, 0x482a, 0xe83b, + 0x6ad7, 0xcac6, 0x8ae4, 0x2af5, 0x0aa0, 0xaab1, 0xea93, 0x4a82, + 0xaa39, 0x0a28, 0x4a0a, 0xea1b, 0xca4e, 0x6a5f, 0x2a7d, 0x8a6c, + 0x4b1a, 0xeb0b, 0xab29, 0x0b38, 0x2b6d, 0x8b7c, 0xcb5e, 0x6b4f, + 0x8bf4, 0x2be5, 0x6bc7, 0xcbd6, 0xeb83, 0x4b92, 0x0bb0, 0xaba1 +}; diff --git a/mpeg4/src/libavcodec/libgsm.c b/mpeg4/src/libavcodec/libgsm.c new file mode 100644 index 00000000..731161e8 --- /dev/null +++ b/mpeg4/src/libavcodec/libgsm.c @@ -0,0 +1,95 @@ +/* + * Interface to libgsm for gsm encoding/decoding + * Copyright (c) 2005 Alban Bedel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file libgsm.c + * Interface to libgsm for gsm encoding/decoding + */ + +#include "avcodec.h" +#include + +// gsm.h miss some essential constants +#define GSM_BLOCK_SIZE 33 +#define GSM_FRAME_SIZE 160 + +static int libgsm_init(AVCodecContext *avctx) { + if (avctx->channels > 1 || avctx->sample_rate != 8000) + return -1; + + avctx->frame_size = GSM_FRAME_SIZE; + avctx->block_align = GSM_BLOCK_SIZE; + + avctx->priv_data = gsm_create(); + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + + return 0; +} + +static int libgsm_close(AVCodecContext *avctx) { + gsm_destroy(avctx->priv_data); + avctx->priv_data = NULL; + return 0; +} + +static int libgsm_encode_frame(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) { + // we need a full block + if(buf_size < GSM_BLOCK_SIZE) return 0; + + gsm_encode(avctx->priv_data,data,frame); + + return GSM_BLOCK_SIZE; +} + + +AVCodec libgsm_encoder = { + "gsm", + CODEC_TYPE_AUDIO, + CODEC_ID_GSM, + 0, + libgsm_init, + libgsm_encode_frame, + libgsm_close, +}; + +static int libgsm_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) { + + if(buf_size < GSM_BLOCK_SIZE) return 0; + + if(gsm_decode(avctx->priv_data,buf,data)) return -1; + + *data_size = GSM_FRAME_SIZE*2; + return GSM_BLOCK_SIZE; +} + +AVCodec libgsm_decoder = { + "gsm", + CODEC_TYPE_AUDIO, + CODEC_ID_GSM, + 0, + libgsm_init, + NULL, + libgsm_close, + libgsm_decode_frame, +}; diff --git a/mpeg4/src/libavcodec/libpostproc/Makefile b/mpeg4/src/libavcodec/libpostproc/Makefile new file mode 100644 index 00000000..00e4033c --- /dev/null +++ b/mpeg4/src/libavcodec/libpostproc/Makefile @@ -0,0 +1,28 @@ + +include ../../config.mak + +# Overload incdir, postproc include files go in a different directory. +incdir=$(prefix)/include/postproc + +NAME=postproc +SUBDIR=libavcodec/libpostproc +ifeq ($(BUILD_SHARED),yes) +LIBVERSION=$(SPPVERSION) +LIBMAJOR=$(SPPMAJOR) +endif + +STATIC_OBJS=postprocess.o +SHARED_OBJS=postprocess_pic.o + +HEADERS = postprocess.h + +CFLAGS = $(OPTFLAGS) $(MLIB_INC) -I. -I.. -I$(SRC_PATH)/libavcodec -I../.. $(EXTRA_INC) +# -I/usr/X11R6/include/ + +include $(SRC_PATH)/common.mak + +ifeq ($(BUILD_SHARED),yes) +postprocess_pic.o: postprocess.c + $(CC) -c $(CFLAGS) -fomit-frame-pointer -fPIC -DPIC -I.. -I../.. -o $@ $< +endif + diff --git a/mpeg4/src/libavcodec/libpostproc/mangle.h b/mpeg4/src/libavcodec/libpostproc/mangle.h new file mode 100644 index 00000000..46480ab4 --- /dev/null +++ b/mpeg4/src/libavcodec/libpostproc/mangle.h @@ -0,0 +1,30 @@ +/* mangle.h - This file has some CPP macros to deal with different symbol + * mangling across binary formats. + * (c)2002 by Felix Buenemann + * File licensed under the GPL, see http://www.fsf.org/ for more info. + */ + +#ifndef __MANGLE_H +#define __MANGLE_H + +/* Feel free to add more to the list, eg. a.out IMO */ +/* Use rip-relative addressing if compiling PIC code on x86-64. */ +#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__OS2__) || \ + (defined(__OpenBSD__) && !defined(__ELF__)) +#if defined(ARCH_X86_64) && defined(PIC) +#define MANGLE(a) "_" #a"(%%rip)" +#else +#define MANGLE(a) "_" #a +#endif +#else +#if defined(ARCH_X86_64) && defined(PIC) +#define MANGLE(a) #a"(%%rip)" +#elif defined(CONFIG_DARWIN) +#define MANGLE(a) "_" #a +#else +#define MANGLE(a) #a +#endif +#endif + +#endif /* !__MANGLE_H */ + diff --git a/mpeg4/src/libavcodec/libpostproc/postprocess.c b/mpeg4/src/libavcodec/libpostproc/postprocess.c new file mode 100644 index 00000000..5574026e --- /dev/null +++ b/mpeg4/src/libavcodec/libpostproc/postprocess.c @@ -0,0 +1,1158 @@ +/* + Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at) + + AltiVec optimizations (C) 2004 Romain Dolbeau + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/** + * @file postprocess.c + * postprocessing. + */ + +/* + C MMX MMX2 3DNow AltiVec +isVertDC Ec Ec Ec +isVertMinMaxOk Ec Ec Ec +doVertLowPass E e e Ec +doVertDefFilter Ec Ec e e Ec +isHorizDC Ec Ec Ec +isHorizMinMaxOk a E Ec +doHorizLowPass E e e Ec +doHorizDefFilter Ec Ec e e Ec +do_a_deblock Ec E Ec E +deRing E e e* Ecp +Vertical RKAlgo1 E a a +Horizontal RKAlgo1 a a +Vertical X1# a E E +Horizontal X1# a E E +LinIpolDeinterlace e E E* +CubicIpolDeinterlace a e e* +LinBlendDeinterlace e E E* +MedianDeinterlace# E Ec Ec +TempDeNoiser# E e e Ec + +* i dont have a 3dnow CPU -> its untested, but noone said it doesnt work so it seems to work +# more or less selfinvented filters so the exactness isnt too meaningfull +E = Exact implementation +e = allmost exact implementation (slightly different rounding,...) +a = alternative / approximate impl +c = checked against the other implementations (-vo md5) +p = partially optimized, still some work to do +*/ + +/* +TODO: +reduce the time wasted on the mem transfer +unroll stuff if instructions depend too much on the prior one +move YScale thing to the end instead of fixing QP +write a faster and higher quality deblocking filter :) +make the mainloop more flexible (variable number of blocks at once + (the if/else stuff per block is slowing things down) +compare the quality & speed of all filters +split this huge file +optimize c versions +try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks +... +*/ + +//Changelog: use the CVS log + +#include "config.h" +#include +#include +#include +#include +#ifdef HAVE_MALLOC_H +#include +#endif +//#undef HAVE_MMX2 +//#define HAVE_3DNOW +//#undef HAVE_MMX +//#undef ARCH_X86 +//#define DEBUG_BRIGHTNESS +#ifdef USE_FASTMEMCPY +#include "fastmemcpy.h" +#endif +#include "postprocess.h" +#include "postprocess_internal.h" + +#include "mangle.h" //FIXME should be supressed + +#ifdef HAVE_ALTIVEC_H +#include +#endif + +#ifndef HAVE_MEMALIGN +#define memalign(a,b) malloc(b) +#endif + +#define MIN(a,b) ((a) > (b) ? (b) : (a)) +#define MAX(a,b) ((a) < (b) ? (b) : (a)) +#define ABS(a) ((a) > 0 ? (a) : (-(a))) +#define SIGN(a) ((a) > 0 ? 1 : -1) + +#define GET_MODE_BUFFER_SIZE 500 +#define OPTIONS_ARRAY_SIZE 10 +#define BLOCK_SIZE 8 +#define TEMP_STRIDE 8 +//#define NUM_BLOCKS_AT_ONCE 16 //not used yet + +#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define attribute_used __attribute__((used)) +# define always_inline __attribute__((always_inline)) inline +#else +# define attribute_used +# define always_inline inline +#endif + +#if defined(ARCH_X86) || defined(ARCH_X86_64) +static uint64_t __attribute__((aligned(8))) attribute_used w05= 0x0005000500050005LL; +static uint64_t __attribute__((aligned(8))) attribute_used w04= 0x0004000400040004LL; +static uint64_t __attribute__((aligned(8))) attribute_used w20= 0x0020002000200020LL; +static uint64_t __attribute__((aligned(8))) attribute_used b00= 0x0000000000000000LL; +static uint64_t __attribute__((aligned(8))) attribute_used b01= 0x0101010101010101LL; +static uint64_t __attribute__((aligned(8))) attribute_used b02= 0x0202020202020202LL; +static uint64_t __attribute__((aligned(8))) attribute_used b08= 0x0808080808080808LL; +static uint64_t __attribute__((aligned(8))) attribute_used b80= 0x8080808080808080LL; +#endif + +static uint8_t clip_table[3*256]; +static uint8_t * const clip_tab= clip_table + 256; + +static const int verbose= 0; + +static const int attribute_used deringThreshold= 20; + + +static struct PPFilter filters[]= +{ + {"hb", "hdeblock", 1, 1, 3, H_DEBLOCK}, + {"vb", "vdeblock", 1, 2, 4, V_DEBLOCK}, +/* {"hr", "rkhdeblock", 1, 1, 3, H_RK1_FILTER}, + {"vr", "rkvdeblock", 1, 2, 4, V_RK1_FILTER},*/ + {"h1", "x1hdeblock", 1, 1, 3, H_X1_FILTER}, + {"v1", "x1vdeblock", 1, 2, 4, V_X1_FILTER}, + {"ha", "ahdeblock", 1, 1, 3, H_A_DEBLOCK}, + {"va", "avdeblock", 1, 2, 4, V_A_DEBLOCK}, + {"dr", "dering", 1, 5, 6, DERING}, + {"al", "autolevels", 0, 1, 2, LEVEL_FIX}, + {"lb", "linblenddeint", 1, 1, 4, LINEAR_BLEND_DEINT_FILTER}, + {"li", "linipoldeint", 1, 1, 4, LINEAR_IPOL_DEINT_FILTER}, + {"ci", "cubicipoldeint", 1, 1, 4, CUBIC_IPOL_DEINT_FILTER}, + {"md", "mediandeint", 1, 1, 4, MEDIAN_DEINT_FILTER}, + {"fd", "ffmpegdeint", 1, 1, 4, FFMPEG_DEINT_FILTER}, + {"l5", "lowpass5", 1, 1, 4, LOWPASS5_DEINT_FILTER}, + {"tn", "tmpnoise", 1, 7, 8, TEMP_NOISE_FILTER}, + {"fq", "forcequant", 1, 0, 0, FORCE_QUANT}, + {NULL, NULL,0,0,0,0} //End Marker +}; + +static char *replaceTable[]= +{ + "default", "hdeblock:a,vdeblock:a,dering:a", + "de", "hdeblock:a,vdeblock:a,dering:a", + "fast", "x1hdeblock:a,x1vdeblock:a,dering:a", + "fa", "x1hdeblock:a,x1vdeblock:a,dering:a", + "ac", "ha:a:128:7,va:a,dering:a", + NULL //End Marker +}; + + +#if defined(ARCH_X86) || defined(ARCH_X86_64) +static inline void prefetchnta(void *p) +{ + asm volatile( "prefetchnta (%0)\n\t" + : : "r" (p) + ); +} + +static inline void prefetcht0(void *p) +{ + asm volatile( "prefetcht0 (%0)\n\t" + : : "r" (p) + ); +} + +static inline void prefetcht1(void *p) +{ + asm volatile( "prefetcht1 (%0)\n\t" + : : "r" (p) + ); +} + +static inline void prefetcht2(void *p) +{ + asm volatile( "prefetcht2 (%0)\n\t" + : : "r" (p) + ); +} +#endif + +// The horizontal Functions exist only in C cuz the MMX code is faster with vertical filters and transposing + +/** + * Check if the given 8x8 Block is mostly "flat" + */ +static inline int isHorizDC_C(uint8_t src[], int stride, PPContext *c) +{ + int numEq= 0; + int y; + const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; + const int dcThreshold= dcOffset*2 + 1; + + for(y=0; y c->ppMode.flatnessThreshold; +} + +/** + * Check if the middle 8x8 Block in the given 8x16 block is flat + */ +static inline int isVertDC_C(uint8_t src[], int stride, PPContext *c){ + int numEq= 0; + int y; + const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; + const int dcThreshold= dcOffset*2 + 1; + + src+= stride*4; // src points to begin of the 8x8 Block + for(y=0; y c->ppMode.flatnessThreshold; +} + +static inline int isHorizMinMaxOk_C(uint8_t src[], int stride, int QP) +{ + int i; +#if 1 + for(i=0; i<2; i++){ + if((unsigned)(src[0] - src[5] + 2*QP) > 4*QP) return 0; + src += stride; + if((unsigned)(src[2] - src[7] + 2*QP) > 4*QP) return 0; + src += stride; + if((unsigned)(src[4] - src[1] + 2*QP) > 4*QP) return 0; + src += stride; + if((unsigned)(src[6] - src[3] + 2*QP) > 4*QP) return 0; + src += stride; + } +#else + for(i=0; i<8; i++){ + if((unsigned)(src[0] - src[7] + 2*QP) > 4*QP) return 0; + src += stride; + } +#endif + return 1; +} + +static inline int isVertMinMaxOk_C(uint8_t src[], int stride, int QP) +{ +#if 1 +#if 1 + int x; + src+= stride*4; + for(x=0; x 4*QP) return 0; + if((unsigned)(src[1+x + 2*stride] - src[1+x + 7*stride] + 2*QP) > 4*QP) return 0; + if((unsigned)(src[2+x + 4*stride] - src[2+x + 1*stride] + 2*QP) > 4*QP) return 0; + if((unsigned)(src[3+x + 6*stride] - src[3+x + 3*stride] + 2*QP) > 4*QP) return 0; + } +#else + int x; + src+= stride*3; + for(x=0; x 4*QP) return 0; + } +#endif + return 1; +#else + int x; + src+= stride*4; + for(x=0; xmax) max=v; + if(v 2*QP) return 0; + } + return 1; +#endif +} + +static inline int horizClassify_C(uint8_t src[], int stride, PPContext *c){ + if( isHorizDC_C(src, stride, c) ){ + if( isHorizMinMaxOk_C(src, stride, c->QP) ) + return 1; + else + return 0; + }else{ + return 2; + } +} + +static inline int vertClassify_C(uint8_t src[], int stride, PPContext *c){ + if( isVertDC_C(src, stride, c) ){ + if( isVertMinMaxOk_C(src, stride, c->QP) ) + return 1; + else + return 0; + }else{ + return 2; + } +} + +static inline void doHorizDefFilter_C(uint8_t dst[], int stride, PPContext *c) +{ + int y; + for(y=0; yQP) + { + const int q=(dst[3] - dst[4])/2; + const int leftEnergy= 5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]); + const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]); + + int d= ABS(middleEnergy) - MIN( ABS(leftEnergy), ABS(rightEnergy) ); + d= MAX(d, 0); + + d= (5*d + 32) >> 6; + d*= SIGN(-middleEnergy); + + if(q>0) + { + d= d<0 ? 0 : d; + d= d>q ? q : d; + } + else + { + d= d>0 ? 0 : d; + d= dQP ? dst[-1] : dst[0]; + const int last= ABS(dst[8] - dst[7]) < c->QP ? dst[8] : dst[7]; + + int sums[10]; + sums[0] = 4*first + dst[0] + dst[1] + dst[2] + 4; + sums[1] = sums[0] - first + dst[3]; + sums[2] = sums[1] - first + dst[4]; + sums[3] = sums[2] - first + dst[5]; + sums[4] = sums[3] - first + dst[6]; + sums[5] = sums[4] - dst[0] + dst[7]; + sums[6] = sums[5] - dst[1] + last; + sums[7] = sums[6] - dst[2] + last; + sums[8] = sums[7] - dst[3] + last; + sums[9] = sums[8] - dst[4] + last; + + dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4; + dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4; + dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4; + dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4; + dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4; + dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4; + dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4; + dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4; + + dst+= stride; + } +} + +/** + * Experimental Filter 1 (Horizontal) + * will not damage linear gradients + * Flat blocks should look like they where passed through the (1,1,2,2,4,2,2,1,1) 9-Tap filter + * can only smooth blocks at the expected locations (it cant smooth them if they did move) + * MMX2 version does correct clipping C version doesnt + * not identical with the vertical one + */ +static inline void horizX1Filter(uint8_t *src, int stride, int QP) +{ + int y; + static uint64_t *lut= NULL; + if(lut==NULL) + { + int i; + lut= (uint64_t*)memalign(8, 256*8); + for(i=0; i<256; i++) + { + int v= i < 128 ? 2*i : 2*(i-256); +/* +//Simulate 112242211 9-Tap filter + uint64_t a= (v/16) & 0xFF; + uint64_t b= (v/8) & 0xFF; + uint64_t c= (v/4) & 0xFF; + uint64_t d= (3*v/8) & 0xFF; +*/ +//Simulate piecewise linear interpolation + uint64_t a= (v/16) & 0xFF; + uint64_t b= (v*3/16) & 0xFF; + uint64_t c= (v*5/16) & 0xFF; + uint64_t d= (7*v/16) & 0xFF; + uint64_t A= (0x100 - a)&0xFF; + uint64_t B= (0x100 - b)&0xFF; + uint64_t C= (0x100 - c)&0xFF; + uint64_t D= (0x100 - c)&0xFF; + + lut[i] = (a<<56) | (b<<48) | (c<<40) | (d<<32) | + (D<<24) | (C<<16) | (B<<8) | (A); + //lut[i] = (v<<32) | (v<<24); + } + } + + for(y=0; yQP; + const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1; + const int dcThreshold= dcOffset*2 + 1; +//START_TIMER + src+= step*4; // src points to begin of the 8x8 Block + for(y=0; y<8; y++){ + int numEq= 0; + + if(((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold) numEq++; + if(((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold) numEq++; + if(((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold) numEq++; + if(((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold) numEq++; + if(((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold) numEq++; + if(((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold) numEq++; + if(((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold) numEq++; + if(((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold) numEq++; + if(((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold) numEq++; + if(numEq > c->ppMode.flatnessThreshold){ + int min, max, x; + + if(src[0] > src[step]){ + max= src[0]; + min= src[step]; + }else{ + max= src[step]; + min= src[0]; + } + for(x=2; x<8; x+=2){ + if(src[x*step] > src[(x+1)*step]){ + if(src[x *step] > max) max= src[ x *step]; + if(src[(x+1)*step] < min) min= src[(x+1)*step]; + }else{ + if(src[(x+1)*step] > max) max= src[(x+1)*step]; + if(src[ x *step] < min) min= src[ x *step]; + } + } + if(max-min < 2*QP){ + const int first= ABS(src[-1*step] - src[0]) < QP ? src[-1*step] : src[0]; + const int last= ABS(src[8*step] - src[7*step]) < QP ? src[8*step] : src[7*step]; + + int sums[10]; + sums[0] = 4*first + src[0*step] + src[1*step] + src[2*step] + 4; + sums[1] = sums[0] - first + src[3*step]; + sums[2] = sums[1] - first + src[4*step]; + sums[3] = sums[2] - first + src[5*step]; + sums[4] = sums[3] - first + src[6*step]; + sums[5] = sums[4] - src[0*step] + src[7*step]; + sums[6] = sums[5] - src[1*step] + last; + sums[7] = sums[6] - src[2*step] + last; + sums[8] = sums[7] - src[3*step] + last; + sums[9] = sums[8] - src[4*step] + last; + + src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4; + src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4; + src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4; + src[3*step]= (sums[3] + sums[5] + 2*src[3*step])>>4; + src[4*step]= (sums[4] + sums[6] + 2*src[4*step])>>4; + src[5*step]= (sums[5] + sums[7] + 2*src[5*step])>>4; + src[6*step]= (sums[6] + sums[8] + 2*src[6*step])>>4; + src[7*step]= (sums[7] + sums[9] + 2*src[7*step])>>4; + } + }else{ + const int middleEnergy= 5*(src[4*step] - src[3*step]) + 2*(src[2*step] - src[5*step]); + + if(ABS(middleEnergy) < 8*QP) + { + const int q=(src[3*step] - src[4*step])/2; + const int leftEnergy= 5*(src[2*step] - src[1*step]) + 2*(src[0*step] - src[3*step]); + const int rightEnergy= 5*(src[6*step] - src[5*step]) + 2*(src[4*step] - src[7*step]); + + int d= ABS(middleEnergy) - MIN( ABS(leftEnergy), ABS(rightEnergy) ); + d= MAX(d, 0); + + d= (5*d + 32) >> 6; + d*= SIGN(-middleEnergy); + + if(q>0) + { + d= d<0 ? 0 : d; + d= d>q ? q : d; + } + else + { + d= d>0 ? 0 : d; + d= dppMode= *ppMode; //FIXME + + // useing ifs here as they are faster than function pointers allthough the + // difference wouldnt be messureable here but its much better because + // someone might exchange the cpu whithout restarting mplayer ;) +#ifdef RUNTIME_CPUDETECT +#if defined(ARCH_X86) || defined(ARCH_X86_64) + // ordered per speed fasterst first + if(c->cpuCaps & PP_CPU_CAPS_MMX2) + postProcess_MMX2(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); + else if(c->cpuCaps & PP_CPU_CAPS_3DNOW) + postProcess_3DNow(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); + else if(c->cpuCaps & PP_CPU_CAPS_MMX) + postProcess_MMX(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); + else + postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); +#else +#ifdef ARCH_POWERPC +#ifdef HAVE_ALTIVEC + if(c->cpuCaps & PP_CPU_CAPS_ALTIVEC) + postProcess_altivec(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); + else +#endif +#endif + postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); +#endif +#else //RUNTIME_CPUDETECT +#ifdef HAVE_MMX2 + postProcess_MMX2(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); +#elif defined (HAVE_3DNOW) + postProcess_3DNow(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); +#elif defined (HAVE_MMX) + postProcess_MMX(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); +#elif defined (HAVE_ALTIVEC) + postProcess_altivec(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); +#else + postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c); +#endif +#endif //!RUNTIME_CPUDETECT +} + +//static void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height, +// QP_STORE_T QPs[], int QPStride, int isColor, struct PPMode *ppMode); + +/* -pp Command line Help +*/ +char *pp_help= +"Available postprocessing filters:\n" +"Filters Options\n" +"short long name short long option Description\n" +"* * a autoq CPU power dependent enabler\n" +" c chrom chrominance filtering enabled\n" +" y nochrom chrominance filtering disabled\n" +" n noluma luma filtering disabled\n" +"hb hdeblock (2 threshold) horizontal deblocking filter\n" +" 1. difference factor: default=32, higher -> more deblocking\n" +" 2. flatness threshold: default=39, lower -> more deblocking\n" +" the h & v deblocking filters share these\n" +" so you can't set different thresholds for h / v\n" +"vb vdeblock (2 threshold) vertical deblocking filter\n" +"ha hadeblock (2 threshold) horizontal deblocking filter\n" +"va vadeblock (2 threshold) vertical deblocking filter\n" +"h1 x1hdeblock experimental h deblock filter 1\n" +"v1 x1vdeblock experimental v deblock filter 1\n" +"dr dering deringing filter\n" +"al autolevels automatic brightness / contrast\n" +" f fullyrange stretch luminance to (0..255)\n" +"lb linblenddeint linear blend deinterlacer\n" +"li linipoldeint linear interpolating deinterlace\n" +"ci cubicipoldeint cubic interpolating deinterlacer\n" +"md mediandeint median deinterlacer\n" +"fd ffmpegdeint ffmpeg deinterlacer\n" +"l5 lowpass5 FIR lowpass deinterlacer\n" +"de default hb:a,vb:a,dr:a\n" +"fa fast h1:a,v1:a,dr:a\n" +"ac ha:a:128:7,va:a,dr:a\n" +"tn tmpnoise (3 threshold) temporal noise reducer\n" +" 1. <= 2. <= 3. larger -> stronger filtering\n" +"fq forceQuant force quantizer\n" +"Usage:\n" +"[:

    }*FypdLfkhJ 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ƇW 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⩔@k8*1HkNzRNlz3uRI{^rFI0cc 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�kN+Oy^6eBG%SZ)axSS$!Rc){m~MH1(nBsRXh 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%0Dt3|^Dg|XA_vxS2cECwuH@i} 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

Hx-v*MY>na%3DBV>i}i$9 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�hN870lcRr*_tb#IRhpeEva0gs~~Gz;L35cbHA6zlHSS|JwgAn;&dR=4ng( zWA|V}%u=seT;UB7(^P&{f4?Acy!*(+4-Ql6?3v@b+$LYBe7tS0ev^aK4ml>~4Hfbq z99x#X_-oL?qs!jVs0-dgCdoKUUoV8UUgW{m0LA{9eWvKRD@-sKflKHSU90 z3BwHbSDW6)3O=dMY^}Y{H&5F0;o)Vg551gmrex=vzV_zCm3zn67>hSBKyk4-@|7TJ1>>zwLc-K=I+9LtLk3bN^;E z@sJbWWY5NU^opm@o*RD;l+59Clao4WurNYSPyV$*Eo0cD2kmAF-?b)cE=bT8o?sEh z#eBl1@Zq21r*`G=m4`BJYgiHbSMu7W$$Ng(2W-zH(s@}VV5p64|0HXezl!ViCrO=f_}y%S{GLZkq{WykeP+YM+4m$^W>olEO}sd}c|kKj&o4d+HfHlSXB$yz zzNPzJk{`_D4u1IJ+&t4u!3#GWo!Al9lOio+dyC27MV-3Y4YeyO2NS}?dw#~RIJ!@6 zL*>B_XT;jlF6Hg9Hw-e6zLJ`GG~-ww|2s{|gSP~hIEij~9(?f2De?G(biIZN@s|&N zSuJjPabiNyb@ze>)#ZnOmNeMxQM_R%_wMby66U9Gr#H(oziQ;F^ypc=mrY%WvEgS~ z$J2uXcH;jF4%DkPt?#>f=lj(P?%9`bd*5W}e#zKk=wRR*c%1!f2oK8f8vP_FN~NMRv1j|?mu8yP+`Gx@bmufY#f0OnnxNE6!>NT-#8fXjdSYLlsNh0 z<^SZ@e!UeIQQ);Psvw0aVuOTYuAq}-ff4@;yZHYJ2RTISdK)UH@I>*?{(o!X>!~Xi zcGOEgnA&}e;nKbZAJW|$4#cwWHdSBr)n(%W2OEU{Yh5V00EbJ}+ z&ju;}+K`xGFagvyVfSN_YgT6CIq<&af53--ZoEgQ{s3z@6|-rpM_r3NAH#)24LSC| z2Kkj6RU|}Hzr^t{9{6DYxLIq89RGjO+;xn}51i%oc#Ibx;O2j5R=dGLR9sntg^S0Y zjp3z*O8>+^k_YbnFi-$FApW<@k_RPBdzJ=hKDhp4jmQ-x{>MhI7$3juXZ-a4Hw%A5 z#S}J?CG7`W7F5W8b!=jGIOWn3AMzl9?}q_y(oW%Tf=gKM(A57!wY^;9-1l_|b!)RX!!srw%@_ zKg!1N@Yhn2eVSemKgb_D{%ZB{R}7oBvwzm)O#YDgV?rFe&8o$qn_nKBI)3Xx;>QA` z4T+z2v;SJ@etFt#76$%+c!uX8o06|TIR10$;=?~px!*A#aA@OIKk$92T2p{wgM%zn z+ldrO2Rr%ySu$((K0G0 z9Jr+!{N~Qt{0jv>Yt@nT?ot%{v*Vj z`o~26SOfBHMrXn@qp??!&JI0a|Qo=Duy8HJtx{c=cv+pst6Ox;UH2YKt5_ z!2~|_C3S~Bq`orB=hrZLaI`^0{;r&EqUf_l+IH-sO>;z@)}PDh(&71e*G~S5-fk&Y9BT@m+q)j!sGS4{o)>*IsOOMxBItTm>Si5?S#*VcP7Ui^m3OhIk4B_!yaF` z#|}qodAJX1KKw9S@#2je3yk+%YAX1#@W9Fqet%yaxshky_#mRVQTfnMv(kf~4m;;n zRGGD`^maO8GUIad<(xSi4&RaQIkZ%XQ71#j^W7nFmZuDHe}wLdc7EU9+Hzo)WP8&I z`Gp@hFMN6hM}?LL73OOLO@eN;~)a&DMnFnVD2kID1i{@pU&)aLEC8GAP>5dbNT-v7J9cuTuxJwUA zOW)vl*xklLDDWI#+oWB33p9e{Wv*T7{>5i`A@PXhd@dFJiW1fLK6We*1KJxKN<3uG z_?hj{@3`~eL^4O6F4wUKkE$#cEo7(2NwzPG6Xx3JH=q0LCU$Pc3wIWn@Z8HWlifM7 z`p}Bme3z6L&bTF~YFA(=k@%eH;S;vDqYr)d$QTqKTKPlG`O1eHWht4<5BBo6O~~Py z)}#C0q|Wrv#Z|L%tXU_%=5Pvotu#50FL_PhmIJRgCP%vzoU7Lu+)hdAUX{dqBA1+&t!wNjl~`_=~Z ze*f|PeEZ{`{dN97pL(_Z57XsHSQskx!Qkk@KjLBxR}&fp{$8+k4AGV6)VkW~J6+q6 zv2`I&)f&mtjH|c8etYj(b87z8{*;!7f0RzJ^S4ZByQ?SJ9QeWDkBAqe!wRNKhLa+S zXPK3?3py-jB&<~0-|f(mX3F0(<4edZ#|n`>HbO~zo+@*)O{fS|m$cB5+>s*H`+Ir2 z3qMy|!RbQ})%au=3*7qL^4zhnEivSfln~PgW8Rhssn!WC8aj$*5_}61Y=j+RFHiYU zqs+N7^Z3ILKitH=yf`f=$KP}B9*~1@S&kmGuR+CI{~P{HGXm!w~QtU#}riP z9S)hrlzjN(w6Icko*&%FX@?fF#BpCZkn~}d)BlM(H8)J=WfNL8o9EEQ=W^Orp)TIc z|Mt5kY&`FEPUUi|=M ztliBExB1!aP@m|c#`^l6tj~w93Df=esC8ttO$icfOO$xc*nBu^3g}b|3!(JoZjL2a zE*~;)YYsARP1?d}koMujnGzN=9gbr+7#5r{o;tbBzoI6>K5*h0&c7`Wf1L5ZsU%qe>@6OO+3;B>H)2C4L`miILCg+1DDaVHw6q=8Fo|ETeSsb_` zz~o@V8ONpq|AIKB22YdrBYFJClk%r_yKad3@F8;j90>~pfy9R!PO&pvB`8UIK3wpa z>EeV6joF7TOwkog-I$T^;6fd9}@dZ`fqyrwp{X1GY*z3s4?pNay;=; z!i+5!n;V}bGMB2Bh}+l+ed*v^mfFr%w!}=H>v&=Mj;HO;2WQM)Xq@i+a!0!VPugz97`!K^VLzipW6SaG?yc_QE$eD7VU!Z!HVR_pn4IRM( z?FSalMh~u~StO(syhsz|@MD>%#+H7l;F6d{j`2GF$2?|C7W&H@`@(msB!+Zx%qx7j zpqXEsEjTzt%}QE?)m`(+Lhcp`VYz=yH+42l6W~>TWBZP$QG{80F~fp%#uAQ%_>vz6 zDU6wp4IdJ@xHl9wcDN|Th<9ppAAUaXQ@Xu@K}zz+Ct-V5T_Ak>?i;pb#7kzZOv`TWXZY#61pBMAP7f$nP-*dRk`tU?<@_xH7 z6IxoiI1_%~dCp>>f9FY4$Ce!h&NkvP58PO0oUd*axWC6zOhEYh9!DDqF4LD8IW0^K zst*l{5y4ZvCpOJvDh7PFQ`;V45=B>ns<;M}NNd)_!$$ekP{P1|c6N@N9j_ zztM!HIr`UxFlmubi3@z+^DL>zQDRoiSfL~Fye;v=Q3X}8Ue7~~niUzU`yYgr>gt#< zf49(KYLTrdFgV_pbdcdva&KUkV{Ve8&?44f4>njaJ*hZ;hKpH{;c{FBg9a1p(ezVa zUUD!j;P`5MgJqJ2Ob6eB_Z&`5-`ksy?RQJsP+=YTB{FXA!;3tZ8>}}rDJmoc7Z^x~ zw>61z9jegro;PKK5}QJ&>LCHAdm_$J-@6;0?aDtCRryHayz|C>4wt158@eaG3VE=A zThHV1;YayrE+2br_2HkP=^+P4j)WFT@#zWEtU}^ea2!a?Fkok9$S|0~``YGLu^ zM~46X=kh;fxZ%vkVb{nRE5{js_yMR#ec=Bp6|LuA?g%+PuwN_0{(pn_mwyu(k{S|t z*yKN}@B7c06j`*(>VJ2G{?o(v9q(AwGkh>$pZa4TX-v2F2? zU-fBLM&&j$MrDRWI?rvD?g(=g-LX`&F-^tRg`FadAuo7s@XE;gR{{L2C)wbf|-Q@ijr@xHwo^q zaAegeP!xV)-f`^jiWqiV#VetKmcClR-B;3`HK5w4U(@ zk@IGD?{g-vQ_i)a$iRdu4Wneg9~05{8401m=f!6?Qv|U4V3AJpf;1GQ=vFn9F8qW%e>JJ%K zpVM1bsXDz+KYp0$LqNY{Px}Yu)*t*wz1lt7L=;#=vwU9sdcI`>vr7Ztx26ML4ZUH-;MV zc^^d%y0FdiknB+V&0zE3OrX{ptr-=+oD794PNY;mc;cbZx5t=8X=)c^>IDUcz?Hk3 z*_$N)wO1ce^5wg}N3>&$^u3P?$DH1?C?~G^;AB0~pPNPT(1I`zZDb;<@;g~94#o5OX z84e_#U;gXCgp+s6#SG*)G>my(tS~S*qh#n+aN~}og^6KAiiE@(HACyBbxvQJWLK9-0pi688_s5;Y`h1lDBSu;KrmdQXUliQ&&~t0h0Ct&D8=$9muZdt34^J&vT<*N-MPt;+v! z;UCviuIJ7C-TkYA3M6WHBrBL$8Z|CVV@!C%TevWWF+uE0V}`0XGw0=mm>_+1br1aw zYD~*)A7-eD$yY?^eQ#Ni%U9sSx}8OopL@yDd%cgl)v77` zUWXI&-sl%B94yMUeIK06-*Yqj9t_ZT(CeN=27tl-&e$+5;pA~d3Fjym5mL*|vo_gGD7-?uLH;FtD`i_ZUK72jbtEAafZ zsS{TkJ-A?biTlA4h5qEj3w_m9Eo2xuRcckZ7ru{4)9R6^sL@?G^YX!uSDH9IS${+@ z{XNgc)M}H*)mAX!{r&i5aW#$sQC=nt8!8NIL51z3MR6*2Vk}#X z3rgZYKb*Z9`!!Yf`3yw!Gl6m@Bm}Onem+ks%%lqyKiSIB`y|k#P<5K527$l;nKv z#26V)CC%`tRh*C{S5d$sbrF@xwsx5QAaW!WZl{yQ6uICR~tU zKDaN2N0nKeQ<10cc)MpolAZn!nV;f+a^%l^gP4X0MHPijuuU>Cb)M@?+vq7U5mtc^=e{Z9KESH!S(kk#T+M0f%(U_dM<*-&<6qtDG1rl$fs1@t!jK@MFtwlIoQLWriIcS>Yu! z4{q4L+TkKsp5PukIa4cx1AdY(BM-djUg2^0!!nkI8xDSnWU^#xn8c@>eBOFPn4php z{HE732H!iBIULzs_c$8y3*3&gm-_HOyyHjok}oC#Ctp~$2l!T$=!M-XQJEugVU2X( zvy7Dw65mR ziWt6>L&vx6IR8UtsWLyS!i?e>Q=%QuOlm)r|8T`Ag>7FnJalKtFzlPY$4;}Et3&L) zCg)+rTrVLTE2;S`M_Ud%{IGqPFeA)Co~4*k?ZrN|2N&4;*_fBIyPj~!xbq`N!7(A! zT}3g&$Ff<&#EL;gz4N+MK)BR$=SP!FR_x0E#a-0cP@?yJE`Qq|RhCUo3P0*5G8GjZ z$(We3^wCjTofCfCwV@6a?Nf*hTnG<1%1PV0^HdTB2=1^HqonUgheUFDDiHpFi^|30}q~ z1{)T3B?p7w_vF|T4#l5~h~0ksOyrJE1@kbnQ=`%W1~#XtP*j4e~kYrblBIJWHS zxi<6q9RBAz9`beb*&F`rFn8Y)Zb)zc6gQDYp40Ao>x1g&4L?%k4=!xD&lbib$&m0_ z^wpCChdkICDt@>H?byX6S+r4lQR16WNvj11>RB8W{#3D-rmqT%XRoX8VXlnX9d7HO z^2lKWo5KQ52A2;l+z}7jG}GK~E(2|z?v57ZEkT=U@$-*72UAJ_MqAs?xnD$i!7;<(rKR8ynpiIhn zuW(>O%ZCX9+>R3}rMOo{S$s5Zepq&1WQQihhCHSQ3sxsV4zG_KcN0!l_}Sz}E{r() z;7|U-W4DB_D8@?deOTyuBmBVRwo7Ug5*k*pes4N?P_V<}!(59Ji)E9-w~5)<2qo+Z zP;_E=VS8mkj8@!a6;DM6{@!)`3@K9<3f^8^eDHyH{J$?73S8#QF_Zf3^IM}uOopdr za`xjx4}R#Vd;C%7?p>R5f6`LbeTwXd8J!m_b#qK~XsR+w5aeKfbnvL;i#1wi@;t8A z*DW5@nD#Hf*PzMY`faXHa<8flW8zmo)lyA~zlGBe8Xo*;wAAw2A(Qj5a}GBt6m6ci zsv^TG!hPYD4;51FmyaF%@XqB-@x2cxbTeD8CMjGhc(=tjP{^WIqSuHe^yujcUy|fD zi0rY_=Un;POHhV~ZAp|+NAevh#@!dwEEV?2b23EpT1Ya#uy|L|lVia2aD7FBfaXhX zfeDwJ8M&$)Gdo#-6}(~m@II_2hy3$96D!zQR0$y zNiuaX*}lIVwyGe@{MY*bi9ZD+O&{djCEs0CyyR73>^*_QnRU^J8>tp^*c(2~XyvacaQbdx zr_ZiavT;%2j?P*lIdcZu-fmmJPX6U0PYl9`v=*l;*_ zF*jr-ewm}FIz^uMz#jH>JCdeaUbvvD%4{{qp(0lEILj5`7-2RA@#e;a8dJVw4UICF z40r62=V24Hh{`%zuWb`#=`a=hYNS;RUE2a_GaH_BbSw52H05u;)xIpqZJr3@ys5$} zqAV)XHg;l@=LpMM$#OX?{qiG%Vb1eCTCHvDuNrnSR$gaYz{keP)z`wP?Qd!2@J5F3 z!5a1^&x$`)5BQjW?y5ihQTzV4nY(@~Hz}|u@Y*Oe9e8|5L6on;Mbmj=MSID9ZKMso1K29oG+VZ8qSiPbps6%0< zK8tdiWZQ$ViPO57#g{&`h|v&n7P(>YqNpHD{snW}g*n3W1Q~fBw3P5HZz^Ou|9jqt zAKYx)%oCbAQra`J+$1@KzOy(Q?hmu!cK#QAa7Dz28@8EImdckWu^%(68%o1#KI{cmC>;(~Zj^^iw5`52zH*7LnlM*!Jrt*=;f=v_GS06gq z^ee1{mGzLmhDt?^$@OUr6Ac9n`L8hFo3M1@2E#)WcdMMdrO2T$)6XNt&aSN>`~}bJ z4|x+FsB_8jw=vrYW~}@sv2dYKq&QE@q*!<6z$g`c5#DF2`CggwyiK>n+%n2?wr)QB z;GeUZBG;*s)&=huJ^jwf7;r9e??aZYdrVj?jH}$Fgt#?UbShjH;y%H8;6$R@v9rsS z)cLsYXnSOO@?Sc}$`G)e?ZCGQ3oCXw^0Rs0`0{Axt>dZhsvI3TS$`B+w#PhlNLqYs z>A?=xXST;5gzz=^hCbC-XZt^u!TIn9j>0b%4|uj`9`!3Kc^J4VEThJr%|y*}A z{``bJ28;os^Co-<5#slrG)+~Y#aTvz$N6xBUHg2GJR!C?c~=$o3mXcU4^}*wklj$> zW2p3CgN^v20~3lOv^kjtG&x*$zO-ai@KNDz-^KKLX|ke6jnE8X4$VU?Pn|x__`}jC zwT*+()}gpH+3JuLk6uN9K~umFQ@2S12P9_r$*|1PX>3s`GEs4fif&f%iD;Hf5obMWpGr(j z=ePNAS8R$@mClm@D;>vx)h|yr3VcjqpEAQrqDy~~!173rgA3j{wjWu3{BU5ytS2HT zn#@E+!a5H>^jXkT)%sA^|JrHR1+OYL_;cO+P-+$+%4iVna^Cw<=A-EuC3zCdv{Wmc z*q!zG9Ts$jMYu#wnBH_<>1%dxo3r40scFl_mq@fbOzn#n<=|iJX!6r(UWTWmK**Oq zekQ?V^DCOXG@BWjFKu7)Ox0io>olIWOjegBjw-`>9BF^gvl!PsZ%GhtI?5hX$Kb%! z)O@=nK&Aim+sBQoTDdlKC>(m%x~s;XVVX32PZF{Jmg#vlX~>Qu{k^{OdM<% zH64o91m=D~}5LM7r_A2xcd zFcN6rsq5gR@Vzx<+R+I%>g#z~4pwn4YUpB+;>qB{o+nse9&ZuQyEh@K zphUH)sd1K>LqP;wh{P zx`v8YOb#E{^R?)|?%~u>Yj^Hk!mvlANkH*i^WlX)tPec6k96AT$sBMwxF+D97lv0p0_1GY&sZyT(R)^ja!BlCORT79;^wv&Dw0s{Nc;x_QOZpT9`igsIewm z)S52h;7FC&U@KPQEM^g79Z=S^^FfCJ-_Zk`@)yKC?_So-Gs*Gvjywy=k~OLoArc3s z#7VQQHBfJVa$qlaOZVc$6_%4!k82-RxMU$LpvEc3@hn*OU4@f|PJt6Y|2!UsC|;+@ zjUVJaW(v&ZJhJP2kcBAwWXrOD(+q5yQ+9^&-Fd#$WYL5@Nlp`$f5^EWV|;({>D2^}7KJ@h z{Kvlr?LW%A{_F93k__82ZCN(5M6dNzF!r#j3Q$y&n2?&uDIhhMu~E5+L;O95L-bxV zwU(C~3^b~oLREyKgc`ru9&C8V@L+?N14D4uxI z^gD>d;6f4Wif)POLkrift59fOaIQje<#8M3X{Cqtt0IE@gIo+PVweJKALdT@H;1#i znUBY*L!7l`9cR136u(()0uefS-EnhV?Po~en|Ow!VW&utAj1|z1|KOF5p~WWjwwq7 z9y2X$auWy;XP&3fHF1ZMM`GfH<2%xXc>_EicCcCTHwAoeacwMeeAxa$f+4U}GDe%D zdF#;zu@65ujJbbZLOVe3oQ1q-woYc3|tk!`H$vodj+zGl}t55|N)`7bPP zIUIa2k1=tcH`=$Z&lQ@+d9eo3_JD4$nsBA0DOa)iZ)A4!c>a@;R8ou=M$xZuIb`|xX}bBs*q z>QvcgFU6KC>=v~aw=`!z2$B4_jaxYLdh0RW#+4E!J1ug;m@``M@OL&R%+M2f^1^LO zn4%mXo8~!h*Y+cJ9FHa%9`0m)rt%;}*70{3Q-CJZhIvz8CN^?(K3JB&(QoI27YSRq zSf{XkaWI*pkYk>@tevefPNF02NOK}X^*s(XYt9Fcvb8f`3EJv7D9m`qeR)}wb9$3R z*6x@u*Czb<$ns1-#YT_IpWkApx}xf(T;28qLHY9p_NXSGW2o<*awwo9I!=&L^PLy7 z=T@BnJ0`b;o)t%4AIg#yW?jc3e7EaE)1(gz_~(6?z{S+g$}I8WM=)cYk9I{{hv@Qy zEplbi_oR3$ESn51d`y!PwrW^7F}!s;p6Jipw#0|CkHaA-`A~xRi+t@P2YG^xXb?My`o>yn)(g*Hx+Wmta9V8N1Dw`2FjIV+UA8Y>;o z^0HrIY&lv}!0qt0Zi{>W8bKRbu}MWC$&M@;29sZ!@l>Bu@~_b9VF|d?^7`C?8t#h; zw>wVxH#~3dym#e8>6S2Q%f}~Ib$d*Bn;>D%dO+LY_rWLk+?cj#vt}B&eCQ}*RdkT8 zzbDrC;YHczEekdzJ@~`AF~mk9@IX?Fv)Gh(P2TMRmy;ACEH%5P?iFrW-rCsS&RD~G zL1VU#x=pR|ja0T+cHu3$#q(^WD@u)yw&)LY@C z;M^os-6C+n#puf-Q4Y)Zo{mEP{H9_X&F{j?O6HX4ByZDUSE`TU3P3R z=4mk$^ho+>ld-`0SJk}ggB@oR_C9DS-+e$wzW0aa;*;0r_%3-IG_`esm@K1LhF+sY zt(&=w@a-RL;Ij4-Ri1dSJ{y6aXOj;p9Ji>qcH$3e5piKW*)**+Vcz%N zwAre!H4^f?)T_^Hd@teLlb+c=H>tUA{**YeJ$4)h;)&|V)ftbnEP6RTli}$dJ{^g` zsW;)T;)74ljtg0mC32E4wW!H+apZ*YD@ROhnCe*0x^PxR zOVelO1N;uH#phLYn7PuIZdk!JCHA9cz`s>NO4?nI!u{jp&L2^4|DaWUL_YuCs-x=c z_v8=#+_&k~l|QlvtSXEu>bSW7z7wqZm$*)@pvG0(?$=vozUEdrw)&3`AAH;?Qv3D$ zlZPCN{XS+w6JDG==)nDb2~RE`L#&B0&*8=;ZTYMR?`^1_!^vLFcwkS`rVKSBQLcIR z3?&br8j5lm`|}>lof_zn#_Psi`G^y-DZg8g<%Z?5pp6_`x;NQTIc@oEX{0 zV$HB4%UuLZbsjXhJ$O*WC^O|p09$7BktZu<4lH;W&F`zYV7bkU8dJ?v^E`fWHh#FA z^|W^uziV0VoXNdyOaYS14<^p~-s!gG%#oMenp{#G&W(2-%KXlDEb;l?p{69c;Pxf%78S8u!VLS1n;rNV z^yg)?GxoALs5LY`G?3=s`?Bru4=n+eRYD4rV%G4jSRlY-C$If~g@K&>^vaDgXRo&? zG_9I`wjuYnzfC>UU7aAYW){T{>@9*aG|ouMCAwCg1Rn&rdKi225dBk^lZM!D!(RQ=!JG z3E!5OsXAV~^f~cQCiBO~r@PO$D1Itwk8{qUoYx0Q<*-xpl@XM@Dkj2r)$7HoBH zTxuA>D&9Z;SNunvSDPN3@CaFUEyeEvH!t(Cm-mv48=AOeHdlEjEHb|R;r6`=7b+ER zmAHMXR7_?OI9So5Q{g4I+{QxWas0z4TPDm%IDDSlWlhe>%*X3Ip0P4F=kYK^@mpvx z-EKAvxA~yjuw}v9DSfOD#6Ipgk}y@2YfH?RNk`fzsP&6m+?AO+nd=^h+hW;=JUn+k zTwwL?a$e*x!-&t&u}qOsDR!ag%j84Ns@!b~<|bOwEQuecF!R2+@~UL{5y5~21FMf5 zCUf+-vL$dni@lC*$+vN63XR;hitJ+vOd&64n{b=<72`={4~9xTIj? zgaU&V4om!fvLZxO#2;z=&Dfw*eR0vn`~}CIYrD7-w|5;1oYJ4Ub#<$&w$L6&#ha?S zFD1Psgd~qN-CW7~DTw>S0oFw;EKXQ7?|4(8A2)L)=PZE()0*G&Bsd?az9+>{z_9J* z$p>K;T8t8m-uI?9@t80tv{xTmTzzdK=i5JAX=Y(ab$-vx>HNU*ti13+Omt1@y|4pk1R86nzvpml*zv&8{^olYu@6lf zA2j7JxHn6re$Ta!A?b@Hp4+~x%rwyTbeu9_%d8^@YYn0~JZeuSWXK-~5SYt&dJoe7tk7ua2h zV_4UAXu*OMRu%E43r;K%mh(8=j6EMFaH;g}vQVy2mV3c&BizSgp;jPv-mB@sgp9B+ zI}GMn@JU=uijlDqK6>Fk*PVsh6%E35hv(I96H2&XC4NAhvFyVKi=?M2O`i@{C`|r7 z>4VJorkDRZ1tv(c>uf%9o<+EJ(uY4P8$M{TzVwZ4jAQQG)4~uC`QT6O!os|pko@?<;DZ1+JA)WM zBl`-r<^%O?Jn`&5-S171lwwX~5OAE@!qEC#Jw~-ffltW$f#HIGGNLR3yh3(%;fc?g z`CBGb@V`6gq&&T%L5hWe_k#iJi$68?KQ!7J7KN>1epvr)f(L8Cf{icv+b(e!UlQ)) zVG$H@a@Zm!(aGEYZ?)q0c4m*P?vu3eec7DV-^Za_ZmAT`cxm{ z>?v?GXdeUy@>77-Q_TpYJutu@Fb8y^p+FHiUihh`95?QT;|g zi*VfsNAvd}D%9*_(ZLd%4+r)>Sd_0I_mSta>&fCvZE8p61UQL&Z%K}Lu6gaZkAUxy z>`TYgq*;XLGJJ3}j>`A36FB&Lo`k^dOCs!7GWJAN#ItuzTVb|B;MK&3CD&K8H#W3C z$dOvj#uN~=IyeG8Kz-jT` z%ZDNi7yM%ZtsqL{U^pPb`ye%#iNQf$JlWDDK|obb$|B}we^Oh&_*-@U=L_mMs+r}r z*;It4$TBaVD*aEW?ep#bcMaKJZs^#3ewN>tMvo`gW?ya%ieNwP)u4WV7f;a+BPK6E)Z+SWjio`!Z=tC%21&ro%D*R(*jU6+xW}4+-go9WE@2-s*_dUDirm3m3TsbU0%eTV5sBT%_yoyN) z3T^C1-?Lw4T_*d8iD{Bx(c5({A9Bqlm?RbiShOyA&)vwl(ZF(&ft z%RvF|$8r2Av)ndua|MY9-4o@W_u&ZZj+F;F9FEH~a53q!9#B`-Rpak;63EOGWxQuN zDaK9R@1lgl1dZ?xwHRgFmz-f!SPydY?zK?pS@!vmkbHp?`#W!D#yOYnUKIAdFMF%P zzSG{XW(PCNhW1MUruxkP^R%iK>Uhpr81j9O2k-mNs*@b-)yJJ!LKR-@vZ$}GU1rewNX1HnJc{65Bxt;`(JMP z;San^`~R(&d_O>vvox?`Nln~}uD=KWB+gFZYEPISdaQ)~Noi%npQRzP(*y#XPA*?F zA%HhD)~d2+|ymhp=>+t!=Y*4Sw#E!9X38~3~qbcUtz%eOu9u`ai4Vb)nA>g zEbR??y6>yJZIzFAI4DZQywrWr;;{LEj)vTHHl_(5Ch%$G)KuF>sP^)AvM}xxKhD^| zx>qqEPQW?hLrZ~%rP&e_Igc8%34aWj8WtYt;nL9$Z%b%N+AvRAV5e?Q`lU^WGIZD; zF1sczzKpK~ej#$69kfNNA!oq%Urk1wD4;{F>_zzv!QT~ zJ5-$HdSQ~tyg=f^kEBHbKVmH2GkrREVuj2`MfQrCC@r1rKppqM0?{KEY<+z6W@~iE zFZ{0MzA!~--V~+}H6~({Sszs>E`RUKy0AgkyD7lzz}bf!@_Q_q6SrGFJaF&?L%>B1 zL&Y!60#?gb&oP^zo3N0t>A-`-M}$3D4#z3X(h%jYP?+Q=zVtBTmV}dTZ&>FGoU^f! zIDRSVQbEVkhc(}Wtla~X>=}QsbeKF&WB&E!iA3u!3R!H8GZ2zFS#hWeAru@|T(DMIg>@vlC^BZ)yUl#0m zy5(bmMlEkm$%B7PD<-tr3tf@oh-ZHK#P!vIms_1o>;LngC@^nYd}O`2hmM7oMU8gT zMdpv6_WUyEROC<$`v2a)_Ts}mtP>v`WMCGZ&v2kYK;h^4kXK(074!tOUp^GT|I2sp zm#%r-2U0}-|8IWiAS`=0U%-)5f8p^ZGF5RKCM3_}Q1=Rb$-#7>h2QX@AnzV64u>Z* zUWCY;l91wYS#o(&jew)ct~i0#tq%i^*eqve{BSQ>p#O~y$Glq!OLVxIZ#`EL36Nvh zWz}cZxQM@x$#`MJg%i!;FLpS*hVVeFvu zTr)G#`p^Mo6PX(eriw;C5b2#}d{4MT^Y}c$#&2^g+}J*xKD1e&p~UKAfNa=4K0`+p z9p-0$#2xlZ@}zaT+8*kZX!LTd_|T$x-beh>fhcbQ@l)=1_~@e4@wR&{(3-EG^XjzhV;4gMUK&%q$8mD&j2su5p=%AJo|YJJR@p zJ-oR#z(JY$@Z9bLnlwP)P4+GXWYW6b{`uzpWr1k0ST=Q~W9Uo5`-eu0o| zLm8Lshm+5pUbfpY%dcub`Y1Z^9sh$KhyM@G@8>yS$HMqq;kbgrgI_7j<1+rSGT4Al zcx>QV{e9K3=8p=sj~=DEPd#upd`aoT855X4t~}@>Tks+EV9C@wHFN3>B_7PuQRGbC z&crZ9RWo4b1DSgk-W&`ECpQ}`V3bsxP$ni@@SEXXZ~g+7Jpup^ds0rH=~o?j7Izpe@~2?n_k0 zMu}_gA%%}7&N}KH_hl=Kf(1i(%hB@{5v+@|=S^tP;&7Mxvb1r*)}04gau4$So+rU# zv2}4L>y{P)EyIT_;%grY2<#DEGl5Bf#f#%6&k2VO5*3EBJTIQNE|TEWRIQ#Q&d1ZR zqWDy4&RetOyuKjSh%e1u;GlD;LtvWj2C>S-vl^ZoV*SlY|ZCv5%_Up zi$I9*L6!z*8x#HF7QvndwT~r7Qf=qE2evNSzQ<8b`b6<@Cf-?J_rBN?`B1~Kui{Fv z;d0yeBF>7-RF>~il!!hi9N6|?#)mY6*~Khe_a=35xEQ|VZMtFD!FKu1mwDU|9fa@6 zpWtAeK1G;iYVv=k3%lRwF*&j5>HmK4-tbuS53BRy6->*I-~0K??wgr-i}BB89_$}Q zs?Nw)FpE~)J;@s-xoY8zA0N`Bn|=Sk)JU-pS@HA1KAY{U*-RJts8|))H%$wEyvfs^ z*|hFY!!c&%#vg6l*yL9APu=7Fv;Lmy;dSzdSmK!-A1Vg0Yc*LI-goudqilU%uV1k; zfWNWBk4>(e`2ZiI`#eU+8TIUkK7M6b8dp|kvByhKZZ$&>&(_BuxF_9X4Q=o+V0Dv; zo$W6pe^y09=%n1WdvT1ehyOpFFh_#v&X*YyTnu|x&68)`x>iQghF!(%OVgqzM?R}* zA_5aWUy>7;aC*`Tg^5qS4<4DHw)Z_db8XZ2mA{U$Zdl=@I9Dh6i1J(}uIWo`44fo1 z7F=BKyU;;o>46r;16Bugl$nkNS~nf^6P>J5aiK{-+@?(X;yc#m7Z+IgFlPEFX-cuT zJl}iLq-D~DCa-%Uyv?#K3j0~A_ejjX$K&?*y+F@5Cue^zKi>BCIG(cR-X?+jX||dX z6}n5_ewE_Y-f)-omTyLkPH38{7}K}S%o9%3MsYZ-5nrHVCSl{KFT~FsXEN`_Q&xr< z6BVvL;_NubZ}^gzsllwrjiF&epqMxRN?rboLVGF%I#`%2@-L-N30?H$;g1VTxmgs} zs<*kG=Wvnv(8GVQ>cbu0_M?q?n~bW|f6ki`CgQgD9q%E54?BcqrZ8PdU`f>(n(j}4hM2_2yJY`#BKK@Z^WAIQAZzy51kKrjWs;INIh^x7OykYXDY4Q~navm!~ z_3UcwAx?!-5Xw=+ob^PF!xaCLs=#|u&dH(C}< zd2csQzQZ&?>3}D*#)8+o`z!1wc?NLH?|yzfui{_+0!PdDVGo}^QPK~+Kks;W|5NT1 zac_>q*(M+BCO0+Pe?7V6ZQ+M+Oc!z#4*shT?!LNuReh!f8>do)fySd1Y_SXHCZ6PO zQh9hlGMsJsAqDG-2#do_3$A3cAB;$SsmR#rp&utYIp#SVL+v^b9bJd>FE%_}=ooOq zi0O#!DdVVwZPHv0FKnN@oX91^;ohzLpoJ-Zg@cZw(mjD5*5%8%AG9RQeQ=)j*&G{n zb|Y=Z17Z^G&gM&2RH=S3@o<~5Y)8KnavgJ$yxw9g@VsTRzyx6#`QFOJ z#9fLXl%?CBxVGJy$}~Yy`bYt5li-2|hD{UWJ{jmS#eK+QQ{itj&zZzs?Uv8Ubg-5o zNS^2vNCG*HS|`;u2^!fz+ecAGk>gyt_C3q`eA zen~A=UbD3L;F7)WjZVKH-~1Am2+eeiuo^5jFEJ@1;O-TlE z(|SEBEUbFd7$0(iAL`XbEz z_Rkv|q#oRsV`Ucg-jz_Vl*;h``@R;h21V!7r$8NaJVxXJPQeizCK{xApLCz9y;72iLGSSTxs0 zILh9e%<1LuQfjyVk54gA9$rwev^PC9_xH0CECTYC?<#^mvUDc4uB`}QYHq9$X#CyS z^2&4XOa5sb$`_Y?X*=($>C6~VGT~g2v*VJMhaWcR@l_?Mv|pPLUE#$3-cMlm<>j6k z9FDy_2RT^xCpJWKFfzAgdN~QU+9)!XeVD*}aGm$02_G93qYotn_S;QZt85U!_=hoY zUGsqU>PA}bX z!hX)zAi0na)=yI|d|LkJM=hg+(CfsYR=*jNvn%S^m=5rOo|Vh>?T469}ETjJ!;f^jD#8;+hYWJ z6c2W^>^+(6BwXd3_@(`D$`a;#UtS&(E(pjMXh@vI_@3v455og7fiBkNQ<~QE9Q3&0 z#@zaFhO*=efwNC^UpiQb2yC0l$HF%6vw#S*;_QPQ5+CfHFNx`BFg33C=JSaPSTgNO zPxpc6jmOq66P?;{>hL|A>Fa)#?wb1knn#=?)AR{W3|yc1KCIwmYhJ*^ny^K{|4Q`< z1t0D`0{*`*35dxF~2t+VKN9n^`yQ zefUS=K;tXP-{A8_nbW#&KFVE>u>$V3%6_5TIj z>;G~jdAu`-V@x=;z+jRs8>`ZW4yk6QX2zC?hA_@Y31?UsG6Wbm?2z2G zMxyuGxkVBQ-Rz$O4zLz5Z`dElI6>l_5v!aEe@o%Cb32UrU$-=*a#@KV^Gh6wZa17a#HrWK6No7->B3gdA$77fF2YP;vH<_CCmR($U6IVd{ew!I!fFmTXuuAw!{E zy7H0cFNMSFs*ecEGO6lwq#2&)a4|f&Py2Wz|O2W~|c-iMld4|ew4abjj{&}nT; zQ4p-;X4uknS7G0S2i!u>+ZZ(N2{?Y#=TPIR2vGZQz(v=4se%DR_#P*&4R*gKeB`*h zMYk$KMBPuCBYDo3!w)YUSmU=NNK5Vh>V?lII10?0$vV4w9@jD%@g@e&3WW(7*PA`N zjL%#4jZwVxI4$#(|q z%iO>x|4V#_;wlUI0|hJ%6&xB5%)5`D`gXPev|I1+LyZeIEbI#oFE}H8ko&S9GmFxL zgcH*L!)ofynLfzyHCHfqw@(Uh=FD2d(D-R}-Gf9O=I$Ll<%b-MSJql}1UZ~!{&~ir zU%dY+-zObohC?5kRhds;-u}I#^&Zdb<{zRA`fRL1$^YaG6&Fm}Xi!)!G~3d# zpIMgw;maRRn|W8U{g_lx@3JT%=>hNj<)Y0}GiuDIFuZSBs3M}!u*zs<95d4jBMyh7 z2f3OV@9S9W@JziQ9;PVt-ebbAl7$Bqw(ohs#ZY~3GLN^=6iyBo#e*EjEELUEzO*>z zHeF>l;ncdAWZWV+(;@d^gH-h;d48_+*Qt%)_r7$v_%zo98Lc>`0iaS1BUM+&!-%VfFkCGKzbWE$=5fH@WYT ztJC82=FYz6>U$ErCNG+#-il57FoA#XLk4zxq z+2MVoL}1~Ee*s=RF{;ht;mijdibLhtF0`$Fey~YstJ)#a0t43e4>AXH6f5?>T6iGo zL4p&D;r-i{sXf#tuq+`p>LFu|hYA6L_+pVL>hYj(ev z=P0<{{6lboIUB|sn@sSHV3@`lS>f>NI6kssD`D^MG$*EqCjL)$*G`v6jDu(fqJ4-~3 z;vX-ydAr%R#sqw6yEP-%B19wg8o#&CyoLviai7<79p|unuI^(eFyZ#`0A+~{cOLh1 z98o>b;jZ~ArA^h-o6GYIC)1P?C!TFiOvhUkYQDEBWJKR{XJ$}+IQtN%UR6xX!iE;6 zDLW6&Q`A@@Ah|@8$0MLgOtML^;V{F7B!j?b2j_9PFgHj(Q{t>(?QmhTFuK4k&{Jk5 zBsrl$fMGq0LW0A;1!7KY4Av*kh*n>c%H&{V;QGi>x~KVihuddfM$jQ}4C_6#ntrIu z9wmcKKW^Rt|GwfQ%7^pJPY|Vk3Fl8E6YyU?4bW# z&UWs(maPk$53BF75t{x#=EH$Ze~(fp&RLJRj_ncfF;hMwEZg*L&x*_UCWIt3$(>{H zkoXvLzh&t}$CcmP4urYbl)QMNJZ+i6!{becdk$6~T3~Z{kCniIQ_SXVk4_rKr5JM` zQ@#IF`TU&2j1eF5Ih6wBi{|j0Xa7*ZzUuhnpWhB>c<3`cjW>z^FE6COZ{>pX=fjx| z{%w#D;6B*B&ku9~ih%~Rp;l+%#8(Q59Jdxd)DUFI@ZfDR+gFs$hP-h80$7mtAV2YwZ?X3m6W_vHt> zk8CV(U@NF+T_CU`tb*CQK}W&dF=6%n!}I1J|L~xmle2Mwvyj%xP0SK{dg1P`rfUDr zvR#?n*fQy(_IB0_fr+H7BJ|0|fjBDOpgI@{TCM?kLh;V3O+PmX$W|i|ZmcvrtCp=)SKKxMg#5^fG z<}ET287+;>C!QTm5c|l(svodL_xHRhEh!rFl9-c2_5#fL`{{62by#w z&U^KEJ3kUQ>)0#yz{6k$KYOz!tAUK8;AC5|9>XTnz3&Bjzgd*(a~#<6eNP)hfbV;6 z5eq4|2La3X2IMSjKh&r=olEiFyIIedwko-6Uo6|eBxuee_K@elN7LW;ti?wvFZ7(g zC*IJ&tI@mv@iAvxGszWUjGp2NNo%%oc*x1~uqia{v1z$;T;tcO^Pc+V>v-9(s28O1 zG0bSJU3s8zL438JZD2*O$KreP2QwHOD)?VGHgVSdQRhgCoKV64(UCQ7daskzetCwE zx{sU|Gj906Cwm}TJ0!=Rhxgc=xE1w@MJt}#*-t2ypYkAsC9x@1{e}@=OHXu5dadh2 z77foU?VjE}Ue1XQ@^W9=?g>e((9y1L3c7BiY`mVc;r7DMEBPl(-=Qeh&gyW?_NB0) ziJ9aciAM3JdwZBp6cn6&qTpN=a!5ja??Z=V8ATagv-SfzDss|{oSLl4d!J}9I_QXW zvnMysn=)y_mM6`eT#P-sQbLVs-zOdrU|3guX{kU1S3VEB!1?>)xuhv{XTp+=;Yej7PA&w7^HaOKXH2mWc;9+!L+)z>TQ8$jkt1mu2CVsfq^rDrVf7E-Dh&RdkY^T2$;NOyIpIB0Y)w zL(82BZEjrb)hC=-62t_Wobv=4d792E*nDtOlxPrBm0olCtd(SwA=_!z$48VBxjgkb zTn$fVGjbeAYKU-T6=xBs&%r5b+I z6*W|1*&P`~<90;FsgyT;e*=Mr1DOv4t@a(>#t^078jvZd%+THxk+5 z3P(eJj^2|_!pkZG47M*3(PaH5Fv0tbK)GP^y)TCv7H~5+EotTBaDK1oS59lbg#0aslA2w()F?+Cpb;0jR+y^&@Fs!d&?Qmnv?IYP%pP2)hQg*=3qD_;QgmSV)v;JI}dyikm}FnImEuB zqVB`LWt^=4!}3;Jt?;tkZ`syA!y!WX;qw*&6U##%?qzDGQ+W4$B)NJs1|wVN6lj$d<#`a7aX~vO`0(`k+i-aqt1L#}isg#McY-7;~<# zP!;wNXNXXo(Zi6wqrD-zNs*(%Bi~zKilOGT1+2yQ1bX*cgt*8Sq+~X2h})&mVSJEd zr-O}v?-b<|)(2T0xY`K#Zu36KawyqGQ*rxVJ$_ZzmZCPx^9mb;KD6;}eCH7%!l71q zPE6)YD>Ea@xmp`%`x9oi?*)AB7<@S|$8-Hg=s#u|`={ZF(##Br3l0`MigWq0(6L3h z^?i|(p(g(tE#?;mDe@=Sr~c6RF}Xh|0_=;9;B_< zKhbl`))nh7J`7lTlO1o>ZU6wiX2~JC(Y4tqxR*cWh}}~?P~Id2Ada%O<35-A*T6|Lq7SCfXQ)H zL5ul??<-iF1R9yQHbfL8Enm*r9rxuVU(0>Z*OxAY`-mMW$a{Z|-Hckroh;ny z6C>t*;?5Vi#-OG6UZFum@u7pr)&mdHx6LUP`>U&~k(BSn%(4BPfrt8g*ZCZ7?DK>; zyeBIaMWGTsrbJ7kbuSV76p~=Dkp~zzD$-A{@8u^ z$IFo+E5ai|Ci$>q=k=d2 zGhZwWNL=7_)L@39SUZd3_N51%96fYA^ba#mXJrViNMe6qk&t$YyW~74L%hzzE;c?} ztCAfXCZs-esJbV?)Gp8Au&|HA;YaPs*39gK96pN==m^X(KFBdEpCLj~aK(g#GcBAA zB20$_bt;?<6=xshIZ?`N`%Hm_A-o|%QTWLZgES}Bh7Q&?hJeG11ouqfS9~Pc*6uV< zn3tvE+&q)R=ey7EwQy4V(z>ikvg3O7L7t}My>CQ4c_&TynXx%KWBW_qdF$u2+*q0Z zLjMvMA4e+lxdLYkjp|8_j2u^XC`vdVy*TNS*VU~Y_uorZbsn_vxKX1sW9{-)-xs7X ze(++Rw)Y@Q^Sp^)F3c7>##Xqx;D@*TLB;Un50-V*9o|*>@Xw1W0tak%hVM~z2)w0y zWIcOBql<($hx4694qv=t9)J!W_#hzDqR_^;KTP1rE)M65cjUHrGXxkovHhP?<67ag zYt4&)e5()NT+80ja7Tij`fq!S3>?_Ll^JP&T9E8~Ig`WB!^+FKSgOyl;B?G`BV3oh ztLP;JI2Y)%2>-cXp)mVcFR!zw`7AT91C$UbWLQW;PNU+aLy02 z=93TM<`GvE;TE^h64N}!(F440-iqzZ+u4rAMRD1e=X@j?IZU%USa{89R4 z#o&BMK}qvv_94MH1!024bEYX;xI}%eoB4&6IXF$qYtp0{lkZK4Um|vCj)uT-6|o5u z;+K16=IS^F99h`OEg;a5e2BxOeL081-G>6)-`kj+-}A7u@`FkwKHm2pIc5TlAAVnM zN&CJ`-lJ|phO$S+mo-x^P3!Rr5SKA_Jk()Xsa)N(bi#)6oez#}em(EY!;WpXFYTsY zHuU{m+oEFY%OrT|7MH-64K4FHSL%peYEhlCaU~Zo7vrNZ7gz8zE|)1*n6mffp$B%y zcb??9HTmTdMW&M<{_!f8@YkPX)8j~-qW|Ml^@EsCi~eVRIKg!IhmL}P9gidn;|If| zSyMGbY*nUTIASB&z98q(gT$W&@*ze-Escr+zmF`CcfVyH#=7{K92d*dhaBCPuBm%# zhUf~Mn``yp!qP7ihcq?|7)jlZ=Uq1Cf;4~T<#wjVoQlXis}ColWJ)x2)jXm-GFn!4 z76;u5c(P>6#*CmP2KBt#HnF^EL83kBd6dezHa%Zw`)Z~^D=m@@C zP!jQd&k=@(*7v@Nj>U}}f#UprQxvrvifr5EKHOOFui-lzv)qRXS&bC}UWNxbuI_1* z5H3g)=<+_u)0DBw?h^;EKNqW?>KhI zmj<<9DAR&@%CbM*9@kSrcBG_pD0!Y10(SBtN}5 zAi;rc!3X&#&01_<*j`Lq9X7vYf8UM||2!KG`A=;UEdMiqv8uj2i$eB;{7$cytv)+a zr}|h}ZMacj_xK=-@4tuNwSJrIzwXtX27{NaMVa;b{d3lb6=4Y!tU(V%OF~dgs+r<`!DeTP)=C8iWEZ^+# z!~Si<>~|bWTe#X>KSqd!u*k@_U(J)3XYkP3Z~@@~&l+H`d4Gh_&PM@%s=2p6X*g%{r=XrK@Z;tG2Yf$#W}LZTl^AD;x4f3%VFN1< zb{VObe^y!&{Zr4JS+h#w@XHPMD-N${JUiL!k@$T6W5)OD8(ylN6PB?voJwCJK0}~klj_q5mFG5Qddm)8eSWER z>4pi;^CpQ*PIT~QO*F`DWcaqO#IU8V;PoNL%L@hf*hsf1Y+W31Ag0I8yx`x2zSm8O zGioD0TuFI+N5*&V2Rrfq`TT5m9|`QSoqo#eTVtn;WcyRDE0a2n*>}6-x=iRZE8xGe zntl6$g86asryZO>?brCAk+s$0$i=4h^%;j8Rd#KCBrzvWsac|+UbQ_mdXagixhS*V z>KAvli$92lnVEu)D7wwq#4%}&WP}Y1+ak{jCm}|bJt9nM^{+1l>g@66NQ!vlt^fDx z`DT8X{g-~Rhl)2XEqT_&@THDthD5g3*8X|?&;FJe$}78l;F0T8NKxcDV8MT_F2=M$ zNV4_g=0pY&?bRVXrW_83FFgpJ&deKAV9$RmX3Ye?8VSdKh6f1&oj(1i8#=b^kPtXv z)qJS_`2!_Mhb{KK9~G|OauR5q(p+W6xT^6{{r3W+1r_o?4o+o0^#A%RmZMqQgfGsh zH|OSPc(t69t8s;SW20Y8%Z})$irkMhiv+l4d71FPKVKLM4CI7nEj@Zwm#tvR3MqyH1I_M+h7^GuHlgkn zZzT38C{`^^IQrm&faLT7IrhIFHAPDyNdN|KFD81|Cv(VEr@+Uvc*c->!ILX(o zern;=DQ)wg`?f!>PdIr`sN(aXhZ859c@Uz=t`}%gquN)HCfUwxy3Nfq3Wl1x0p`9Vg@ob#YFcH%qIaPPH*4rR7H2 zg9&BbP7^z-56|3i=Ji>&)<)q;D_o4cBzoraG#wPb+$eE_g)Na~nT?V(&mqBZzJw_r zcmLb-w`J;fCIx+IQ@-_il_29i#TK!9&I}qXZT_Af9-!Xs)1M`aJ`|e!39+=5=t#7; zB|2Eqi!9SNnq3%@5aD?pl9J|LUHviu^6A zasQZ&)<|+6e^A#nN3`Vg9C?;a{9>Osh6&pqydhk}+tqM<0-M9(MgI?29_f?+Q6J04 z{^bGR7Dc8B5<3}KnJc8j*h0TB{Jg+Cy{Tny(Q(d%18oA1{thL956utuwSP!l$Qf9` z7Es~Ap5mdRCHDUygU5mo6F3*>F)aLH@Wp%12^Q8wHs-)T$p;+5C)Dt$=7v~F^RfhbU^gs4b5YTf5a4| z|AjD~+Wplj*4v+%p|Ze{?PGzB3bRpT+!V_Qjmrxwt0w*sclz|#_X*Qd=Tm<22Ubm} z;Qv%3;OL;t!l)==$HVyGgZ$m*1OFFs*fF~v3ZLZku8wLduW6-T&AR+w(Ik{7Mqt z!lQJH)&2Qf{WTt6xf*Y|2_zQJkw37YznP!?_Q7vUx zaM^(JF9OJ8l-3RwAsAQSAb``@Bm*TC374?kIRK>+lG2ZawvHRcRG>r>CA!VNOtFti3D7#9%ZlhM)a^ zWyQ}Rhs5~j(yz?_c*`?a)bZRb33FS~QMN~l{egww(r?VFAGV*+5Y}T8TP@4^HLO|E zOy2*eU(@6VtJu%}fB)d{Dt`9=Gc*dgH5z`-|J&(M^}WddugtRG6jw>oWl)fyQqa$(l&V#cLKb)U!?m6$) z)HcNrQ*5R+I3LcoNH~4?;TydRr*G9Y>W4gUXl`zZVm5yGqMl=(I#1Kf=`s%tHPYmL z_RW!H`jPcv2mc0%2UjE>)N(q{xs^Ekj;PC#53ie<4n`zMO@7!C&9lcqdifzi-HH^m zj~TA2`b8zTW*t&|R}?johr4ONO1q7cRCZG%PgTT`t%?f4_olBgFjwv3WZ4lWA|k`# zW_Zw{Mb=MT$PFpQ+17t+DSRy69hb+4>KKpDA8v5ki$zxzBBQaOPR|P zKE8wdOtPQN`EWyG@p3*^hISc`pbIm&MG77SndVnGu?alst;*%;l6mmKk2k^K>V^dh zvw0>v#6%T5KhN$E(|%#ajS>!rDE44pKK4U5IhYlar!X-;%uutsY0M+UBHG8pa)#B} zJ|Oiak5fa$Z&F^dm{${V*gxNTw z>qJ!?U$->sDE_E@z`2;c)rFtEp)tgpz2V;z5BZqDz-BJT2MW3DjsLa=%gyoQ(PntX zq5MK=hc{b5oR3J5U-JQnbpnhJ?Dw+R)oF1YVwfOs{2-s#%INk}EmK|J+Qwh4KX#af z^IK<8nMqD#|DI=U4$XSbHu=Fq^Sy4oJtxJs!Oyy>tN-{{ff8+dE-i z7UP6jJSDFW9eiu`o#*H(ZpS`mDajpfUwCa6H~2~{yz;vx=%T^ov$8z*X0B`Oo~a>q zPmHsfL%8Ad{r{cw{)j5h;GW(#!7r_L{)6P){kao2J~+m??LISSbDN6pejXh@*5mIF zE3+?a;0ZY_P!M*%O^osQwto`!w*Prbw|_YN=Az@XKZeilZ_Pf;A)H|IFTb&S|7q4b zNyBgT`+4NqS2Xbat66d(_+j(&`w5R68#UbD8lK}(@NV_p&&y-f^jE!%yYbN4U)=wB zWxhQ;bG9d3>BId1J`>LMO%I9`ip)2cH8-hWI1}T1;Pe!(_?H@cLU&1SNaJ(jb8xz- zx7}HI|B9VgUs&@_VU0grE0HE>a8ly@LTBXz7TFKmcUXw?{z$HU&tvv0h>!7zeU+5- zql^#tRvgP<7IIFpF=l6TX?9OC^p@zVF-nLvp8F&J%fy5thQiG~30Xo+2U;&g@XB!h zF_>{6MfB|-W2Ol9=8l;!Sz9zY=C_rdW%|6KR8vF!!^MuOgR^H#3jD}z*^$!R@b?1a zh625x|9LkB7dPz>5b18LdSy6cC-+VV`y~u@k`??fF2%BO?(aE~Jd0hJx$j`|;oLJa zuGb{n7-l`NEJ>L8aQ}s+7YcN^n9?Lb2RA-5dX^u?&VRQCp|Gzdj zR`&nr-B7T$xnqV!fAePt?uY%){}^tczu}lgY`;_Ph0h!wDN=RmKmUszvAocB@F3H| zlgSz(-?xbwKRV8DW6V_D^s!*=2aU9Y2c1`m9E?z!Q_A7>d6$t8%SPRhr?nhj5>}N5 zeFPf?j5^|OxuhMik>GC*)cWkt%&8#zwwLSR1N+?z8TfbXzxPB%@7Kn=Tn#tk zXDwq36|i{Fqagk|=H0~=y#c-R70xykZ4=Ml!}=g)<@%rXoJVH=%Q9~CIgr83(x~cl z{_~RyGCKdSvM}UdRpbzHil3qWtYBY!?Y+>oWjf{cnCq{La5ETaegP+03%`#%6Wq2=$q4Ha|2TWS*Uun0h#Warniqhr$nn zt|&<|FBSDMuU**qhp*Ak$w0*TI*)_jw#ru;P7Kw}66(_5*aXyhr^ITiNKV-Egm+`{ zFZNLDrhJ}!`?rdIPEK>4URV&f!;Eu6;kgA#dJE-)_#OoPlI(6g;kiTl8goO1+UL6- z7C~1gP5Cnau(r+3?+>>Xe(;~RVE=&!>kn(F_1l@$@R%LEAf^~!CuzdIw1H=K!v|T$ zBl#8SXT)<`;-n;>A5ImJ@%!$0Y=!&7&hISOFC61+``%XH_;UY$_1c2M_dMbcUYMS* zlg{pLJTT{%Wb?%XY?U`!CcHOkSs*?qRRFYW(x-Mq8wN(vuq z$IL5C^AkOqE}Y>knAv--7nZMK|_--4M6D&1q-jZdQJt8HRj32~*GiNc#5ke`2TA@9Il=)rWb6 zqna-r;L@&d?BDkHLSxw;#{db(6EWW=T|UF-sIcL)jKuGA2aa*R`M>YMPM(DMxmOD= zv2Iw-YS=jWAWIz&=*AN_#shVX8wK@bZ1@?OJZ#v1DoB6)wbkK**Vizs`#1Ic?x_|S zyb)->&QiAUO{nNUuMEv5odg31HhuPne|O}V|9nXLs2ZWD9j^A=gr%XtA&e*fJaf=f zyAAHAZmT&qI`9azOnUFdzW2$p7YZxotGCUUujBvy|8ImL*G}(!R$oFMmjk!)@BkU!6HSTt_&hu}NPAxk9QU)k{>SgJ>VGk-%a z!$+-?+y}Z9<`pRNA7Wi2xLJ7ebDma%2MM(-TQwtnJ)0HsIW2$LelTZ$*>H93*9($? zg%t{&^1FDiM%%5Nn=<|Oon=>Vp6z8_6ZiaR`}u-&mVae=t8Q~inH{k_s`!@2=SI*E ziGx6T~-pm^AGzM@ky1i zEbOpQ-(XmrBgPo-oG{zPIjs4s1G~fHH!{ZT!JpX7ZhyG+&B4GWli$3Bm@3>^jE9=2^$1AEX|aW;|afT_894|969l z4gZ=BvGFAfE_Y_RF}JyMew+5&=FUF``3(WQae^}-M@T7I(R$9zGv(_ROEG;A zU09GKEECh@dT@f3<+--}?@N>F7L^`v5%kCrX4sqlgO6Qs^E?TkncH97IH6UmCb>&e zZpM_@C%kj3-Z-q2<84Zi4QIEV%`RXU5WDr4WvWdmomWXjC|{H3h8?{4p&~d3AW+B>6CbUok6cR+YxP z2OM}gDa()TP*rGANsORwXWnJMH=XfE_l0aYIon^ADwp2*wA8&kMI2v94UuvhJeNhaNd5c7cR89@~b4JPQ2p?QG{x7Fo4l zu%bkciTOeW2k!yf2xs}E-CI6P5O8d1{K5XPCi|ZIS+N$Sze2U5XM;5@rauU*`~7p8 z99L?KSNGJ$Pmi7^q;XX}Xy8%d^g7r+UtT+B_oD;JT~fs&pIx`UW%_*wlyoK3Z!&hLq?S8MX_1XmI<1 z#q%};@8^Ha&oWPB+4)oA6!UaZgXuT;6yMG`oKdcK(s-g_EW2EDSwo$}+#Aa_8dVyc zdCIb7_X~^DH;I^oT<@3;&YyA6Ce?`MCKU_#5#2rr>10#}Vg$B*bhx5%yr2 zjU0!=0U5^6kDrP;RigJFbvy}cGN+Nhx>pR>+4AyC$+3&Y@8w7 zcB&%ymfM9(X$CGC;`xo+Pv}2zJ9yBUo#&99k?^lDPmUzPh#cW%Z8O;C9aZ~ftRiZn z@bna`49|ht?9Up++r+mD=vUZ$VMuB}aOpO??6g50zb7mM{7FMXvw< z$M9u=2WOv~>!vvE!@q0nj4f@>5^C{xcoJsTelYu`c~^2xv6RhOotEaq+|AAEmVbF1 zyuZEtaNGHuj{XaeUz~H)GcE*_x@mk_Q6kfM@FWj&Tj$QReQs($m^`n>$ZS+$Y034x zxW>&xnq^Nc!x`mcU9n5%KCoy`iRH9!JE+y^sdsU85TE@kTg{)I^6X3h{|SEKVR*1f z)p!v@g4m>GhnMi2+a>3fdED`^!O0X0Bi^P28Rls!qNW#_+Y+_eg`A>~2<=ytVBX<* zVEtjvrlaTovF-cOk;G?l%;`yik;sDx<{gd?w+D0|{F=b};O_;-uP;)(xI4`xxb_%4 zZ@zhet$06=wB7F)`g=^jeXDM6W08~i_v_(4z8D$Nja^2K6K1aC+xu{fQ(H@l$M$%G z+Y7$N|L>JFW<0@oSkasDp?up-g=1~$H!SA2rL=#r;yKLd-}ZB3;WIw_9ej*W?k{Yx zc;9B=yX_6{26;AxSr?h!p5Qa%Todn@&=P8J^zG*BJhj`8-%4b7n2^X+^8ekca|tP$ z8(vO0$*Wi0ES>v9@}SNAwbLF4Xd8cdWTDyKD(*Dt@B%s2vLgpTJ5)^*@_}HC2h7=}BX;%mWJzo!G8Ktz%6l!s%A6S>8uGJ==mMR5vU7 zEQl3qS@c6y>qV0o^8tqG z?>EGb7BxQQ3X%VF_ELhG4F7wjG83JqDVc90>h^I+z`WO z-KCge}_5D=a_pHQGH9FIWZz$&#DsQb+`@L4L8h|d;Y^PM|J(F$ z&--xo=%eY=*|YvgZ3?f*TXDwN#mnb~4l`eufkjehp*=f~lRr;@pV@)Je@4fxc1j7j z@^3TcZAxxcY)I=oKf%bU^{%htfejLq7=Ab&xCiQfhy7&JIOXJjOJ8zr?Y{=tK# z%`5mMS^eF9NnI?hW|#kPjI-?iX2-=3*9g5)IX?3}Pww}JUAL3td2+YE6lhpt&Et5Q zC2@m~@IJW%593!nvTKdut(>Iz$l!p?H$LU$xVEpXjrQ!X{{L;BxL7!$UW4I};rs8* z(szICo+EM4^!o;boC}r$7IXLIq#r2Q)0Nn7_9r6mVfA$Wt?x4rZa87cXmP{iRi}Qf z-NRSG?LF1a9_rC%+--F$Ql8IzzW4hPH$i6wJJs)v3&jsQEYU0ou2{e))Wl(Y@PYk# zh6jm13|PdqgxdQ!n7rnj^mOnCKAv*aN{2aY@A;1`-Q%}dp0NJLyI!&o!AR6q{UzSw(aJf$Wr>`#@!O8*Yag?V zAGUE`tNpd=+IKUjm6UCGUZPq-q{ zpiuh!Vd>f*3Hv~4F64YYPuOSsm(nc{Y{E7v^k|eR7&hf@KYrD+x%hyM2~$e)#noo| zQ)G;V%lKMFCKxC_dd6o_n6e?nJlaA;s;bAu?n{UB!77CdTOH4un|bgG z(fE*dbNJ%=rv1+5+u9$jzp%Vz-=e%C6O)gdUvK2M>Pgo8-ZeJ^q*MW;I}&Y$51Zeq4js(X*%}B=OZc(uW;RX@v*aB@r6m-=kg@Xs}BWP(!cHR z;aumWg&!S~nrinshoq{QRoC4(8IV%ARLARQNwr?e`~T~U7CviHNH~B0zePjyTl-&;;&D|i& zc+h;q@*_pzznkul)d-j>Fv^k^BMQmv%GSNBk-8HNjg+?o1vqmg8Zx`o7o z8M!U{q)QfZ&#?NmkhSp}pOcrQu<2og5|JOd2MV9@NhnEeJ$PiHvYX+91I>qXKC?R% z{t5EvWHPdMJgm@vI48xqjcHHDjWq3NXTRKJZ~M#IsPDVGr}e<@M|1e3DsqGwEaJHD z@wxF;vkPpf^8bI`{^6`P4YovKcB$gM5)2;}elW@FamveC@c+T%dD5v19{Rs!*E8VQ z&TLR9yx?Ie&&j`SMlFubEEm7uut??qV7PtHVd=L&CUUUecM4}S@U?praNPR9E}n$h z^$`-c^KXl_w;A|td&5)z{=mgG5^Nf5=`$?En95#wKDuz6b=kb-e&uMis9e=ZGYX2+Wcj{L@*3OuNZrdItFWlf)SdrZr&8}egOVXO<4zGTR z!lNlp+YH$`{}|hqH#0}^B+nVYP@&^h|XeK<$Ycu=(I4kkUWZS0W+}9H2F2t}YsLgg{ zJgnHF03Ph$XSjkb?U1d8#WP8!VlzH2+ZM}*Q=7ll|GS~Xn56zs;{N%=&g^=5YxKCp5kL23@JZ_)=JIhc1AyLopy!@S~ zV#jT+xre=Le%qTL77^|*m~`Oy?IKV(zpawxDc$(JSd2HOcWrTRn}UYPyf=$B`4qR# zOKt{rih~o`v(E|I*hn5!yub1v+gVk%+Aa1m!N*^&wMu(>yvKa)Z;z9cwHt1z?ER`2 zQFTDHsW|z`BULr+4@Tlb*H#uzljF(W_LL`gyTXMae!IPAGj`3p6(Yx)d|~?9%V!K5 zr51kQd0sVH=-Hi&l*2u&4-%USTXk=&;>d`T&{6CcYumd`!zi)CV()Rj4bQlulka`h zW^diObOTc~Z~L6j%@S(AYj`8RKfn2($L-_ycgNTaeEpSKLL<*YdSN2m&EiQ?BJ|FQ2F-ZdV_M8H|$Igo6rCM zr~Tp3!%63F{z$Ie&-;(LmwAP2i26Z$_Q2*nW(N;!klIkNlh>4E2medQ1%=1>lt0{N zd~xta{eSxt5jOw-KX}5D*HR}L@5Ojve~yekJ8wL*^!sWTj-pNn7c=p0{yWkvH`ISS z`2_QQH0|clNRfzP-?{y@;dvK>=kmqv$E^9pxEJjC=xDyju&H!=h|#VNzneSwRJr8$ z-C};XaYx*TB{IP+TfNS+sHQ$Xt>N+G8~54k+HHQ!4l3*1Cx%Uu5xHVkc?2Fmb^NLr1gwFW)IDUF2owp1t&C zzyWVI>0>_+O|0P06?s^Y-`o{A|JcRmPS04CWe2a!UF0A+Tl7aV%k}!ha=9NLemKTC z{X4Vw8(B`qBTdVC;F@9}2n4Of(*R zD`1@a;KY*stX(WF>#A~0gI;EwF>25~xGrMx&M7^O2lW>P_cvu`AGT1vVclR6^ur>7 zPvOJ$yL(hM+uJaUM~d-qP?mG1!dz-ydUz4G~TAOym@-#VsH92(R6> zhV8=h62txX+mv&De{J?LnNhpGdWYM?&CVjiZ$GbDxIQ^)PVM{;mv7s<|1H=O@bB&k zpVfYMr`s4!k}WWB;xM*zV{Bx<_25YU-n)lXc8h3x@>e9YGUqMW5WV-qO6PmecSR|F zoP4m??!z(8Z+8RZz8f}Wzft1TR4s_x(UHmWIpvIu$ttzvR)4W6dwh33>=C~CkIn4% z_dB8!-Z*^Nx?Xfqj&WwE=+f-4YX|F0I3*Pg-dLTQ&Hp>tc5^J>E}=_Nnh`Csnfz5! zLEqUH_^@1!eJRiKj;*}$*Z%)^xeO|QFdW)nEitR~n1SK8?>!mejU`%#`FWe-K5u0* zarBOq4`Wx-6g7|w;E{oyciMddgBJQsRv%s2~Yoj9Z>$=qy|$ITGCh2dd^ z-X7Dvt`BxSuubS)llxElS?h!68%iYuW;T31a(~I9Pj$*ktvv;PyAmH5>@`;?Xz2)C z7;(a|DfRoq4ZcD=tvbeT8;v#D<&vJT@AxIq#@y4>9H7=vbihWrezB0VTdR)xhbioJ8+Ei_}#8$-@8lS+3I`G2e*<+ z7V@|;RW3Nj`RBGqqVd_CZGP&{x9@nO;%GciyDGx&JAaraU#ByNP|Jqo=(kh4c1~E? zwB1N}#*5M$-+hm4ZT#M*pkZCMLSp8I;=2obxBd8?=qw{~(C&6>#lghScR;LF5})56 zmOuadwVarx;xZvg))zU#&ki1DbZ&U!;VWfxP570ua42tXbH|J$GHOL^i8hCMH^^06 zw;A}`{RuQY$CEJc@{b!4)rTY0XKtwc|NnZ#V|Edy>;->6Fn;89W~k5(Ry6?C-VbuW zO8tGLcSYsKl72Q^Ue7bUTSOJs@L`G=)*e~VU3w2rBKplc>6ru;!)+{v(Eca0fmLAm4k zg;QTTgdbCm@sJc@xxX;J<`ZN z%;IF(wEfbN$IT2gKAhlO{N{fd+bzb5GvCo0mV2FO5#4hBKVsH`KlV|Kp5|T26mNGAncL)YEMS{`+paOxbxpcCD3=YD9vbK*v|b z2{+VNy_^?ozKy>WayR3=Fu z?AY^~wIhkS<&KO|D_@3}r(@y6g|oKA>)p9?x!j z-+Hj_JKF-kUh6W($Lb#pzDsR?*du(~j!iqa;qyPK+dPbhU&I*A*hSW5^7H>@+;IEu zhBL?3$QYQI{H^|Q{B}8yfuBLak>-7DX?$)ustFHPD+vGR$xnZ{{pg`I&NcB?`Kw!Q zg=Ck=bYwp4oX2wiVatKa@Auo%G8V}vJiYd$OhTDm$4jG5V(m6=_KGZ)t2_Zx<_G5P zTVQ@6X2a}GiH0-Ws?DNzBpY=X*FM}(p!bWRVD`nmF5KH+;n4?-T0Jt-;i*a&Hko=_wUgQ@=66c!lk0@ zCBpTB%8qU^aY`IF_?zw8(jzQW4<66qZ7SqC;XK(<-z-R?YlelG!Ga0BQ>KVaQK)U~ zn_bM4yS=orcEJoA^J>Xs8z;wzb%wCVw?g%hC-!Y0i_))SY?9dNJhGRCicCoKNirhM| zzk02?siK?5e5*hKx2hj~`U~ zzQafCoQ0l{<$IoldAT19Vw+jkWWC|`pI>~~Lw$2S&(Rnj2fsarlCAoUz0dw$ir%WY z!EbMKn}UUMeoDjN`u`t$UZk}vf*(N8Q z@cLjdyAsb)iJ2c%J{);F@1I0}68pmqK1~N?^wbl+Twt91psIu6kRM-!7Cso=}$X1V+y$t;)8 z9XR#E!jNmX-JkHTds2-Sl^a%eHy+x}KC7Lx+a%?A=DPzwW;Tm)&(qj?UaV=JSnfjU zd(W4+EsFDzS;%pU7MnePt5F1xDsw=E{Ew0y5+Z^@rB)3O*jX6W|2I^4>dEmx zeY06`eak%#2DuoO^Yu3@L^~5%m>ZqAOhX<1pH)95w}Ok8uhqc8(&P2QmJ7)b4#+Y- zus_S;`uLX$ixqpzROf|{_T}l`S;z3oKJ-0*&Dz5cU#(KMjq2uMHQ5A#y$EXG`&_wD&;S3Ao8o~z z#d97UJ^Nvs{{P*FWB2OT zeP45}=dgsjbPaF*2N|~?K@!ZZ5;rV4EShg7?a^V)SlK49Sl(0}g@F3Qp)Z!T1LGy+C z`0Cl29y2!-T$+EBMTY4I_m?gUnVkx}tOZpb9bSAp0uBpsU2+T-%G>vt9^dFSIx4(i^Z^bPi2Sx-tXLsJ%VrdJ2R9lw^U$1H23w(pCMZ+ zYE^-Zvo+n{p?k*#_1XUTapm`Dt7Mx#X z#(iqVrOorWYobfiCayL8cvxY%TFxO!E-C3iwLQjSS1fruUg$Z6yS^y6d+3zlhbxZi zew+`N2%kS7qj})Pjx^0xN9?{W-D6NAQ~j+)rn7{leGQMzFTEEQ!qHRHSo=WTfCsXU zmOGofD(aa#D?LoJEhgnMP6;#4?6H|BKWEE_ltr?vE)UlT`^ZSjzev!VVUfV6_8`B9 z%Qe5{jL{1{DQPX`eY+++h+{Lm{q2;@gDad1OZ(q^mJ~Yv!B8&gL&5qV=T>M=ZAh|b zidkQAwj(w|bg{To#RQe=ls)1L_wh9=mGMa^RJ-IDh*}93-jXhe&=k07lOi)Aj!%uZ zDMu#wK#W1b@kTw4A2xp&QuZo7NKM!fV<@uC?T_KM`}-so%&uo{EKJD$al=w_p)-4# z61#hyP*Z-}K{KC&7t;0Jdc>5{B%6DMKNwmkSp5EQn|)pb&w^*{Y%V%~nOo%~ViHW> zf4s0f^Z>t_^RZ- z<>n?fV@I|U)x*q*VGH+Op1~F_*W9b@w z*3;}FBF+6K47)$tecxl)l)3%Dxm%3UDgRWw*qI$CA6upn_Pk9%?ckgL|LuQ2$YQy< z(K(r6?uWnwm;XJ!37Um@yV-3;;-k0+OP4;->y3G^h5I#m(yrzV{bA5I>w>bVi`? zhT(0Vgax^q+RX2Le7mE@>fr_bHb>Kg3q%+m?+Bc^AoeOx_%d1rF8xQRMCZV`sgE3Q1z`+ahQ4CRv zcX)F@r180MKfmJePyYXdLix63{MY~gKGwx}VD2k}Le29$xqIK8Zu(=?lo7tc=f^8k zB>`@M5Y+;)+|7^8c-o3sj#OkGoXk97PQtehjC1lAF8!Aga9FVOKTpEU+}}JQYR>!y zQ-0(KE7-Xnc5xJEf7T%Sd0B6-DZ7$MtDrb@-Wo}!BS8ns+1w80@vT2`SaE)!2-hBC zBeUucHytd*{SQm$|ISXH>CCFEs4P_6@c6yhvORGRK%L>n^`FnE9+7Kr`uLuAuVRnz zZ>vSCWFF?&o>p+4Bi8)r@WbnySU+reXIqfbuO+xZq?y4%i2HlDT(yk(O7FR4ml|SN zpX%C3u`qtUs?RW;!HRDgt3vhip2i=A!82F|{df`*@~6LTIZ=z1;L3TNy1k=>Fm@`C5nj zKktV^PhDZ7M(YRzVbkTFo;#%Ov-1RW?z;29GGV&31k(}a5BFkZj3d(i@t^(wIzoo| zXoXBi_Z?T0HGZG{-P-CMJ6o;9+YXxK$lh!E-`tpBTxVh=E>M!H*kt?%G}F3xZ*$YO z!wRt#Il>K(x=NdhA6T$+MOYXqJh|I)-@<;Wnel5F!o78PnFDt%siAi0N3ofyx?~u5ie_>YjAw$EpqI+*ew>@6%+9!57 zPPeBbk*PtYc9S0a!#+?nrh1ctQ%U4Cp5wY4l!1iCoV`-n*KMi-Z#HL z@xmh34J!{n$cp2gKH-NA3&*1fgK73=tG_z#`C1Vy;b1UL;DFV3&OdAT;^wf)HE}rV zPrtX=p@Ku~VD|w7$%wyUO)cK8&PES^{7rS7`>{a0Aebd#K?VOOm#I$f2WNJ~sInO9 zDDcnbPzo>*{9v#}j)`SMDkE!j^2c9RlFbJk&Ivd+81etHwqrc{KyF>*LhU1}|AZQL zH_ec3+>rRQ{vcy~g0m3gqx$b347Pf8T-uo^VZ*|k@WFuh)6;eA4UNaNII?Exul)7F z;RoC5l$up471LQdc>FXB#8?*a=`+7-&pnvG_!@(cP|L!<$5{;w6+9R|wAnE{Nc&gC z$#wit%=A-_4?a*RXK(oDBjD)x@Ppm@{|O%i(waFPKFHslKAmaW+S#rP4sz7-*t0TB zW8d(A?FaLeA52cOtt9=p8y_gdvwg5(|Gr_rO?c4`Sv#H9sFllmqkTs^IDq1Zy7x2Z+0iox6{ zAm%kgg~fBtNI?g+OJ5@zLoJe<0CiA;bS^Swn3t%|-KccARTjx8S{(MNin-54S`ctvi>pHW?YGYaP6CM9i^AxY~~G#(^~Lgt=W= z2jf*ZPPkvbHSSx{)(xc%x*#^XN{il!?i8%>yeSa6%r z{(?7=tUFIgoxb$F?Vz0jyOhX=f+MpFWVqV`Ht1({c!-$ks#)K8^L?8IdK-ja zJ~+%OR(7VbciSI>e|G;C7#wtrSGx56z^&g}6AJv_yk0oD>sCufLfkT@8S2~J&*`x- z^m=K|U*5fX9&^Ixz;1!C=R3n~wym~Uw>itajbDs8P4bNU4YiO$@dp-P1s5BwDcU8- zY9O~lqK0RM#BT4uX&YSZ^+VWKK5*b*XyRFPHs`>PI>s;iA73i`Sh%#F&1{D7q5XRl z`JYyNx%2qY48{)@%;L-k>brPU9W}g!L|4eZPWWm6x0!_@pVQDmb{?a`2l?yGAbGnW zUfb2oB5a_oYpdl0ze_3oU|S`}%$9It-5(?7Bts4N=c-!|1xhgIiHWY;B+&D%tZ0E~ zzjyaL-3x_|7rq+Bem->U*6~&Y`8Ed2fGO+ma3qCxPmbqr>EiEXu-Z@||Ji#*e?P;6 z3i%)I_k|8T^L>_aKzi|GF)f}8SB_5?*Zx>z@%&EgqWppzHM)lVg~z*ub)U`YUCVf) zBSvwd-UTVKozAz~7dG(oB+ReAD!%vF5;HD_lkXH=dZr37&REzyfw|?*tW{DXx~#u) z92NLgUO5PXDvv8>2M=rzetod%!9!zqk>{MK#%1J~ZFyzH&#!M$y# z5)*si5w|AGHnZCwmwnEUUNG(9h95~y<#zRrE9X`Gmim36t^3)lfInd`vw9OFTCz5T zh^TIH_L!0JolQXP{PrJ98=iJLs|rlFjCP1&T)4p}hd)F6d{NV+fRcyDS9~$OoL$1s z>T}WQp*gd4s>U&86=na43aada6}io~53rRspFhCHSN+`a(6*p}4QZmkoRSm5B+9i6 zt3gBPi$x6zblhT!*-Lz{JLHvS-(z_G!Qi0D!6T6$ObZIs%`#*f{pI;QMZaIXuxPh1VJeVy zJh1ouGNDkh+lNJj-)=0>&+42}$b48j_eV0z=buvyqkk6hCkPx63qIHvT_@q=d+)<> z+jqST5scRNN_d+l&UvN$<;)XyHkKFdcfY+{5a+b#g{}Dihaudj4A>54?Udc_c*L{L zlkxNcAEWgFB3$l0-8+oepHHh=Aw56AV#1P;`FnO)sP{{_u3=}%eo?yhp^w0UyaP4* z{|+u-KWxbvdNnZS_{%#MYzG~9#5P@i#@PQrEQ4F;LomYyeg_HO4}5Gvt3uoP*&7<} zC^A>@vn3p8;$Y+uI6cdNN8rc=2RVrgJQtF;ABvM<&d6G@G4-hgQ=-Yr9U_wHrx=f& zykEeo5yf_-Q|OMSC^x&4m-4de5Os+eY+#(*-kCfrkGUyI7AhE$jYsuUyVX zp6}<;g9rAAbU3n4(`!)?(34$zymuQTqnB)=MGEgj1%;o{+5#v2=j3+0*m+DLLW{fl zVULLJwt(wZohH)$igOW#$%0!?|It982_rW3-9|IY9hXfV~Jr?lEnwE%~Pv_FPS#|MHh$wq+OD-DEo$J3?6wt`I)5WQl*n zgK{tb4fPfbui66q=jUX+ySnfp_XfQZ#tnv!cDG9d6F+QybdV?csKOS;hnLrc-5! zv+}ygvXT#i>sdE3oqLrQv9zcwH26q1SCky%hOm;K6Ms2~FW4%Tk~LR_x3^`Zbok@8 z%;U3l-$=GBD!W?!;(;ZTQt{GaXaC-l*Yi zQPl9%zeiis zhnzzXGus3Ll$*J(rM^)O`H_5fzrcj07Y}bVXxU|Ce9o7T*`8@jj|1oR6$jf?HDw+N zNV8n9nAzNKk&_hA@$H3$|B)NZ*;md`5N}Ov<6LIQ`naaTLz?B{uFhhQd#7|A^f~9U z>qs7qj+w~ldCo@cFlZ`7oPY0)XAeUSBo@p)KmS3KYGdVfo;w#_9R4NJ;#Y7)%d_S>(q|MD}TgOt`&;Jh$|}{nkSOL+IV91gC7CR z%}yWkn;0hW+;9}yGc|sW0Q&(s70!gS{8z;r{dZ|Lq#kFQz~tN{SmC6npL^hgfb?oM z4mr8gk4hQx1Xr=y@Raa2t&M0oKcPgtn}h3l_47`C?Js8og}8j#8Jw8qnXBjXY0POk zyRn>)(Tz)>g@rMVbnh(^=sV;xVze1{Ud-VaKfWKNU9bf(0*<@RNS4&GU zryXDTeQEHYRvQZgfA?FxdsZ(9Jm4$4jq#CW?d#0YcNgwE?R}bji$`gjq474w4uu0# zAAD{&q+!v*JM+rnC8--?OiX`HYo8Q)L0H^3=vMgeKrYsoQd`*PKEJZS*8FIPf8*BB zsx?Lq4HuR?$~z~-^kA`%&W@$>IvXssCB(#1cw3C#-}o5uGd^tD4$hsO7eo2?9`Bnj zFV21Bjk3D9j8L;&@!^L(BDve$J*FPnkjlS7OyM<;^MpB#jtdhf-LqnSJxAi8%k!%| z`P&~igtX-s{GR3{2kLjMl2AM5-R7#aj`LRH_5*U-2c_A$F9ghQ?(+AE(&q{A-*)i8 zj#U!3-zD}4zuni*+jd8q<%9L2cE2pcg^l7)0geX_=l=fjMe`tN?_WFXGTTLhtakG4 zccdIGe*UR%Y`ViP_x#Rv%NP&QxtTuIZL1U+J1^W;Rb|)FPI%b3(0jpy1518OOxb@) zQ9!tGhkHrclN%>lN*oS-3(v{*SShh`iNKBv(J~)E-FczR04_$WtiT01!p=et)7Kck zdd>8*)we`6Im1{KAhoPB*tgLz1Eq*?~fSwceV|F<{Ju*%v>kY z++U!Ze(zb+k*2Sw+ZOnNmYr$Tuq&Fix3t`7TK$H-g-Pl8JTdE_ho5dw`j)!)ZPUMo zV-i1Vmo-W}Ncqbym;UmG#Qprk^0_~b2(V9*jC|y^-ZeJ$eT)Wc@%&|nW^guS@H77H zFsyHUus~AC@#6z__J)Q({JCy5a?C$3Bs8s%<6^v!-dy#2iHU$qxkJO{!-cF9#8j#Z z4sDQb+pwh3-pXKwcopxir-pGNhkMvK5PZ+UxqRyO;li> z+V`=mM2?9iAfb(ialgEHg(ClY73Li?n*u60v>vdZ4^4`!DisJ)6>ruKSS2oASa8NW zgt4p6_QwU@sX_)K~rR>W}T2?_W!~OQs1;WNT=%&5e82cb&Vj z;lu9-t24JH-Q|hl=`mVwezrr)r#H&~;&KEQ|^QizcL-PT4fhgFxD@ z__am; zOBBy>UwdEdJg@esL6yXVBdmN04^DhvCGq?IVY&PtFEfe{Jr;Q0&&qx1_dO{_C)0!t z5(_xx*qQ#Ve)PTj-oxE499GX1FHAVb`R(4KU4DDpEDzr}ZYI6=&Vy^5_xK{z3uKHq zQ;d0->MZqyB%ZVB7fw`oeRcBQqIDJNEYH|qHSk-s$cPje7U#&#Vlb+&$+-QJds2Y6 zw5~+;*_|a8RX2hc9J^7?a zP3M-&zA~$5o`_@ZJ2~#uy-!yZu=f>!TeaIC_Wpf0MVaMC!LPQC!xGB3>qHKiG9}os ze@-|Q@&5ud`xA!`0y5K^xR!=;91(CZ@%+o-6k%h-n01WdgMiKIhPrJj3e4L2vOl^X zGT*6?Hk%_*Y!z|s&s2shp9)fw|9x1wqO&A9Vv)&SRX0A1NDY(k7Z3PK*Ug$&!Z3bBlr9)HL@YIE*NDTlgHjtI}KEvkw#>1V%| zbDP|bQRYfmC&Av(bY};1oa35nyx> znC0Zccqri49#8rHlMOd^Y9+qin`xa}y!!bYCsDrc<4zU^&#zkRY+CL(;oY`Y-t{i- z_kX?Ttg6s!YVcURweo9aY27-(W`#%FH!FUav88ZsMKJS@3OOcLgG2>6CKkb$CHesg zQUM7LLhYBe8z0!8723nPqFJyn#-?m^*R6aG;!0hv??JLy9 zSx&x_X6KyyuYjHF(Bi`n+~53uwMG2WbW?-w^Nm}7{@@dN@lU?~#ZuvA7aXosFF5RK z>)*Izij0Qm>QdqEEs9#7SWS8*jwNYS8n$n(h}2MF`&hJq`@CF8)%-GN360q~{revN zZa==E+F9W?%NYaZ5;28GdUX%GJ|F+PO!a+tvfS^tGEyc#_Pz;vaFpfu8+O50hi-g0 z#w9y9OtK*H51(@Vt$Pv+=AUnPXCH9>G~wH3W&F33Iip_ppJ`<<%nc@3Z$T$>-iCDhyW zZ%_V_#d2fqhAIh$6FWkWG)oj7W;n`nJD0(J3PTNVQ_d2(DhA{8i>6<4C{(cMp8ueI z?~`|;^DK|MawT5pYZBXgc4qZD{bKf=k0xFDIQbg4#6y*K%Xf`@ZQRVx_nvY^*cUg+ zi5_HNd+|`?^2=|hrJl1$Gu%*RU+^GUosG3P;VD0_`G+m(3%wfTKONMxWmEaXH9b33 zte3N79T%rww~b~)219Jn>JTZm)~8ROF*>Zj;rsB{hIIbT$D0kz1fz2|Cw&st+MM+H z(Obb8D}MBdpJHzKwANM0pwQw+4Ih_lavpPH+A`mNvll#ABq1<~nO$h23LlHwlB3Hj zGQ_JIk}H|dY)!1V)LbORF7V)h4(|dUd6h`_1qVX6RNh#4`h^om#=>G%o0i65Mq7}%Sc7|UPCZb;#0Wa?08QT#ALwT>Zasj2InHpd6{ zdl!5VP@aCTA!G8?I&1`)j*`yLOec`NzwmCn7`Zy0hP)KGA z<6t=CJNdu@{TR33DhwY4oSP3Eh~iPbkS5G~mN_8*uFyRJI|0=NxljKIWu4=4@Dku> zWZ|&kVPA0g|3yKL6`)Lz!OzIV!L~B+(RYoB+SeeYQwyEc)S?_8}G zbq|+Y9KM}Ve2%Af`+{~w}|O`TVmcOv+X=BSHgNDgXQ5uZ>MjE;%xQzF6_FU z@W`IWeTLe9o(D5;m^VDOJW^nKplEu58E3Eb)e9~EChmQokr3qe=*6LYk3)$8NmS(peAqRs!JL)~tr~i zU>6nWS)4>EXOyngoZL(m$C+GCc-TTa|j&0}#a{{6>EE|LZR|x-I&yb7K@>gPzn6!ix!=niY%WMh?*tdIL=a<FBh&> zQFZ6#Ir-DcwDkp(PHu_9BYoZv2V_hVCwk~dSS*>~ckr-4_u-s7JpH>oI^sCj#O!pq zx?%<69nK0#M~j^7kK!-3C_XIYsXlC>zQMxphlRKd@1`=o2Xp6_$dn&BlRW41T(xcD z5>F$l7e43T+Pq%ubKH}aEljs>sCc(BdMD3$(8_eWNq|E!q~XE@0hbLqLhMf;BnBUR zpb*L4@NbJklYj~H#jVNh)A_G9KK1&ydEe?&^@#()JBuTEtLLahvD-D~6aZ2dh=7-JV?wI6Fd) zO!>LytrD|wRCE8C2LZRb0{3=H7(VRX9>;djU0>g+$@S#v;#r*f3mzZ0IeXUPUDSgk zIdO*z_xrXO^nCbzII&0Y|No$b)XTaC79SR}Py259eit8)L(n$9m)~AImf7U&Cua6B z!|>gd-BB9dqB|G$Tj{dc7$ht<$-wF0#G@#dZT~BjPE+W3{&sRN*6IH9w zW-**3Eu>cvop|JZ!B@pcXS0u&>^;P(Q+-dmR`a2Pbzj;sS(n1*1s4Ao8yxXH09xvr zFhBSAB}jMncK*>V&a;AK9-T+dm4-_~-XwE4#Oj0ejClp9+% zwD8uy;wh0(WIj+|#3OK(Gx;l*OG5Iz@FE*IChmX)UJiRUx&99#|HWGr9EI|yYN*S1 zvR-OS$SuvCRwm6ZEWht=`lcyNKb^kZzpG;66fdm7E;QHL-mh9eL*e0#~@| zD;{4+1FbP&=Q^Wf`0an2-Quc7$wyC1*FJY}*cW&B)s6=*>JNm~aN5p}kvJ%K@@YnL z<$j)o{x5%}eCK7#2N^N)^BiY%d3?OJw_?M`ejdM@-`{Yh*zJ}pe8*ppjQIl#F_Fu2*grM!OKXTvHYkl{ zUMF$T>feJVhr|Q39;&*vBnUiXep8Ua@^DLXnEH=YXW=_McA%kQ^{S*uAp_Aa8AVTN z%aRoSqND{KJt2GsTp#unS(r&DJgntm>rtv%%vj?hx;f#&;+sj18hX4<1+rXR0wR`e z0y0~=?eiP`xQ`u{|NFu4{r5Jr!mA;brSlFO@!eX5nPe)gz`{xI#@%?1+tLz@_;WX{?IR zs^^!=a^_3wJhw@ddEWH(tU<#GGcJRI!|m}hzw}&!g!f%2NYhyHa`%lLl`H`n7c@){ zt`JFSmu7$6z}q~5>D7vC&|w#LO@A*Go^yP-c>mlV&sPWNyD9cR|9ddU43xpIE?E-t zNN<|mrFT3D^DAGqWHM~DlVY^Wka0W4|Bm_70qzxl4noX$WPD3}5uz8dCC4T6;MDm!GL=7)nsT@OV>4g*<8JdxA>lmUrt$@k->;acpCVG6 zJzHdRMwtDo48xa~c%HHz;pLF^isUU0x%^he=)o~A_PYVc@7GCuK7V0F@zK^6OINAq z9KPAdl(u(A-+5E9&GzM_-OEnU0_A!UHG7HPjEk{LgyOJH?P|ihg23Ftdm4 zD}6SG3yE3}{t376uYSo{VIowp=lqe@gyS{q4;*I>&@zzW{G6Nbzwh}sRfi{NE;?|SXeTXm&6u%|mthV&_n~zEGH!-tE0W)W_IGF` z%wGQU@4?eNj1SgUAFf%D#wTjWJa<JmR2TZvWqhr@rB4+!AhkvAXp=kATJu zi_aD}C7kEHwY|_-vUhPm$IV3l;;!nJS3Wn^><#|=f0i0g!i2Mb4>=3X`r6SXSn$ii z>h!;LPXl~J4lEI?VKR_-STX<9vuhWGf4<{NX?gI$fVXe1%l_G{3{n*n1YWRI`mwn= z&0O%^sUbCyVUP3z5tSOIgAE`4NH0AQeptZihb+&c9XthWaVv73UFDtg!?i6;xGYD; z^^f86`K%W{rm*r$&1emtCCPt!&$5Ts^RH&xT@s(f`=WT>LoXS-=d7QmXod*QlQ$SzALrJczFEa zvA9(d*93OxByG2e`&iv9p&nhek#BFtbIyQv%SU(GchpH7blkq`ZFbX-+y~o0yB$_( zbL$s-1ROnB%hSa*Ub`I z^Ph?7a#bff#~EC>dQ$G`b1UJjr78m6&niqGc+vEC^D-jv!1Tlu;RJh=OePqYrMtFzPDEny+kb3( z&p$r%-PuFqwrzhX@8&l$+trZP&yFTvz8;Yyb_*tvj|$WNW_D zg4dHgN;rRsvgSB)-g}`C0nuOwdZqp7S*u4U3%}oTecvXbIfLKsw(>jf@}$@|JPAv4uat>xblc0> zW%7)vMYc?F!A5}>O$(35{77cy&JQz;u6zz!2vr5ze0+}co1rQ@%gmmG2j$jBhwaV& z5@)=KwK+*3j_Z#2#&^C?_Bg67ZqCd!=9wc_B(sWRoz=7jPxQBlD;0otWrnk|@w0A@ zyB)#NqO~+(kL13O`4u~kcP`)YYxW$8gRZ|*q-@>qJnItD7L!$c6nJ8v;6s@^KN-Ir zcKq?Wb;~lzNB;}@&j}sbIaTp^B3}!~K@Fz=KQA9x#IPZKb>Nnt2bOU$u>Q4pU$NI! zjPIP5T&LXIFvkz4Zxm=YO=xIgoGZkBAi$`Comrg!YK=k#6Jy_bsmqBQLguB<{8M|H z*XR4gJo~pB`{Z|2oNkWLn$LL0LHk^ZQc1#NzPl`H7tdMkWIS+;YufF_?T=48-{(nK znY+tc>{GLZmULcYzuB_~+e^2ucC2`ju=mlW zj5&r+(2DV(gLfGp%DSFS@Zi2Kap4%38TkBw7an1He&4$U7PxT9fin38gL@{X zzmHX@@wO$*d%nStPdxeV(l!IXe_zAoE7BBQn=-ZU>17{QQ0L!N_d`V z=DdHSdX<-nZ|VlkGG`v)HyQWV$qSr{`@Z?o#O8a3-&sM?nzy>w_Heu9GuDM%)pH(R z>*sH}eJn5Y_w%D^dsbX-mQazd+o3<}xl*?OUe9IDF01u_&5rvv;W(Q?aNS*&g&M4K z;T9h^zL0F(FiE*H_xyjGrpt>BlJ@GqzkT~2@1a}re?x_WSFL888{?Ptt=(gWkJcEDXS&sb~pDWxB z2ltl;JD-%(+7PFH?>n18h}m6cx!m7N^V)YVc`MIsNqW9)(xH^(gIUvx0onMZPiR)L|T%Rk|(Tw5$& z-+8#iBI?3nR$Y>$2jlV9cR-}uY2%CfN|o7IB*6j4O#gfwBY(`xrkcemxvF0%)ajvZE}uz z-p$2grE6}HVIy(S<#vi-^D@Sy;Ab-5dS#v;Q4U!Bf$xz2s#%ho>)gJ}c_g!%ot=1N z!4i(Xu!s7W>lHQ3n;1-+A`Jc?WR5hn|MBqRhhhVrczU?m!V;q?E)ztfrE@rOYPow zvNW`o28b*WP+iS%>6aag{?|i6D`%MoryagvR3i4mCQ7d+?)lc`nrD}CI+~egl+KlO zka~W!l+^)<^Tc9CB-`x_mD#{(&WDz$%_O5(nj9S0v}|_Y&gUxG3u5hu^R2!)86V*`CRK z;W?`zqtT?NSx>)rHdrXI@c)pEn85yH(dlai6C@+pD$17~Y(MZp{(6gO)&_5e2Wh8g zNStpLKJ-FKxN$=aKf|SskKC#)Bfj2Sa8IA*Soh6ut0&(H>~KwfU}62>)w4gM#}=rG z$(H|WTPNBkxYcHklCX{q+XYX3t6j`T+|RC@qbS60%Pk_!mAh;;>sJYWPLG6!$2#1W zht6w0>=8L{<}H1D9oyBN^qdc+7e?t9Z`4SR`n*nBx69S*f>uHEjE_6HLHok0+O%^U z9$yz(cwnYu$+N7AwHJ!_9G5aIxck8J!m-5;#jVY=`4u1Cay~vG`LKY9?gTS;p1sR7 zvQEboJlLvvs9~djL9l|RymtFlDb?b~%@Qix?%mLDKdkC8z43$Xt9f!lx&4v{{Kx;~rQJKKaiL4aYjg3Hmh&?H_jb4m zvNp)Yo7BoMp4zLmciAD?pAD_&#pkdeXmEY1BeL-P;={@lKAm#B9v#aQ+9%d5BfRvV z-o+=^_!yruZ+3*vliU5exdbHF7}efrw_I;} zu;yB4Tiy|i^8<>UydXwq)hs5VN_yx zcx{PFw1DKUbsL)xXH=|QTYPk(f0pVy&2z`CZ)qj9`4ueet8!bjD^vSQ6fbMWly+vG zUE&-~6B*Ore?9&Ernvg$&V>vO0_+D`oJ_v|%4YZUv2r@FMl<0s=-e+yp~fbLDePAt zeA(Cd@cZ=esh>lnpDt_aG1HJ^{_`OS;zNpt*Q~*{^jKp#iH;`*xBd^L;x zEaU#iD$XC0K0S3kdf-F-&sFytS828W`@f*)r|8cIIT>6MQv=vfM1@4(<2>RZ6MsKN zg|qd+nSP~`mHQvOO*L8gL7;t}fclnX-VXt1y`o(%?hSs=#c;#5=ZyBEC83Oe4t%>h zQO~_Z(c#%gt{0q}7C3#F{J`|;a`El}U)e8z6hv1s>bQyCiF<0RuA^w8%=X{*;{~;Q zlmBoq^UM=DB)K^3$~}iCat^OdxGr-nI9^dx@~Xm__fU)e*Q@vCL=I}IKFnRPae3Kt z#_Owj?uZ-|m>=S}^9Bo(X<+DY_7^rh%n9?9z%b&W&K(O;rN2J_4vAOIG z4Of^OyN^HQb(*NKX9p)+-Pb^o`+S=&PFjCYMt|OElR19pyI42heGnyS9oNZurA5r% zVYf{|uxs2ej=4Nl@?2NTnpfJ}OPj^iluAo=-266?Em$rmYevz7krji^_&Xw5BlDN@Q#VeiAHnCO8;9>Gz4$UKHn|b;dNwW&533@gJ zq)yb>d7{_d^ZZU1q1qR-OS#T=UY^6c;N?4~GsiWa>gA+pIK@1RY2Q2T(DE*UJL?Lz zsvh!wc-XHEjYkhAq4ewRu_UqnU0#=_GHynmz1q&Nt@F!m90O~ zire&R%LHAoEpy9x7OSd+WSI(TSUtDUxY02u;r)x4=N$gM&c^2?7r$ls&v*9qjMVpB zZcfu~)>!jjKIE3BB59_<(=^-WQsR#(D+B)2KYIP~(OTwJuMTxMsPZ4;Z)tk-e_5yU z3f5ivvXkd$23KjPnKyz6nep=w*3WVnW*RpD2H zL3hIZt8(lu|BqiV{rNmNV3$URu7r)oyIT(u8e&viwANJc*a}Tq!zIt>do*4z?5yj> zy3*;{O&!SxA1H*gH~i<34EQ7c$iqSJY{=sO6S%uX844@RR(E-~%&*$+pdiQm<3d79 z9BAo?f<~A%oe@9uw!v zH?6-Aw}!tnz+FF##aVfgc^G5~=*S?){`W$v!-xGpIvozHI$!l}T6^cGL9jOy$A_8||Crx6 z2r>Q=u-WUtKbygR!6crT6V4w5n4N^W-@W0A%X60J3{*l$r*8#HZjsN~g@H(U{ICRzFkcSQXw}%`8 z?5;xDLc#=oEeMdbyy$&EaUs{*RT`KO*<-f&a#%~`)A(VGqw9(uVk zy}o^AaUyew@YF}u#nAEdfotJt&u=lzQg69g<3QkK-3bso?xUur6M$-}hR zq21w(#+AvtKRqyd6R_q&+Cz@c-Bw=qhko%W)krd=oiqsMoV(wK@jk;x?XwLL?95D( zrR*&YHv8W&KRh5LAmWTuF;{P1{ zwEs7US9fFgiXNVY9L5`%o0tv-y=@DqisLE|uziq}uNiHG?n7J6_b{xsm0UhWs)J`i6^{~U0q4bxsUH|4a$zerB3k}_HBu-x5Y^9#+%W?g?~c(d5+tdQ6u z5qo93WXtUO5OSZxHZ(y}@`Im=7a!l`wmiY*r)FFdkK_E| z@=@W&1*59e1rHmS%beW&YS(@-6)&agHGTaTom>^Ja6E7^QS7t&D5d^|Nt;=Gr&RHR z^an~CGK83>1{{;*Ijr7e6u>7TTcu?6Tv~AbAv?j|e9t=*g_4&Ce%#EovR~Bf!3m$2 z4^FsL%S3#Q!6+R^C}zeXi%K z!VK?O-4x1kyk#wLhmrlz)U%)ZIyP`#NX&S_{fA>Uo7lNM53d|kj15ws!MVO7M>}3@ z@$!3W32$3B^0XZ+$Y)&7+*o^rVQ1?amLIv-Y`EJZWe!_7tM6h~Wu3&d`Fw(TsF~d= zhv>{K93t8C^&LBoH~85 zCGf-KJ**0>oX#KGctaaf7sv>-Klo_C_N#|why4D=shtV3m)>yhwQVbn5R+^* zcoC%Xq)BN<=YuQ!{4M*mL+j6NdyuFi$NuL6@44wL3JD6@910)o-?j(@vv5pcYJcz} zfTe#5TcY2E2F6oIHrTrVljpBXkYi%G_`|TmhW$s@)jMqRZa23HbUHu$Fe!#d>5jvr zuh9wycOSoISaD*npMfN+L9D~%4;B2M4>s68a{ZvlP$0-wVetFtfe-S}``uzf{e@I-V@nBhv6qA7I!5e>eay&6+3;p#@L4z%#tv9T~J|5EMbI`jh-4pO{aL9Tm<)A5HrvHsB0ziN73!f(^cAH2vKAY^u{h4QvPM`;yMW%A` zq7_Sej3nDHn)K{WRc}A~UU2o6o);(lp4|Rp_t7HB(8_4W%ok_clC7N13Hf9+yxb^# zkwGas=sO?F;^0Q#6Fkl8mgl6+xD8HZJ>fm_*x^KVAV1f&=7p2RggUP^f1I%KWKa{k z^W)tz4>O$Sc9a=}IJM^2UDGO2ym6eHo2Oy1-T7~s9BG0zR$Mxlxb7DYJObh zsQ@dk{x#ENBqsIpe{8nWFq3T6p0LuP;>PB_;(G?ux?PSRHpxw%BWdhBXJX-kR5|gj z@0_a@EKVLN^KvPWN!6U3@U$~dVaDNgJXd|f`4_7DA3o`sc_T|M)p)`2p#Hv_JifgF z#}sbQN|sqXlfSu*JK~v!)WU>^%{RQ|Boh7S-!bDps<7b2;v>i86q)zW+VSA*BT3$$ zCmaeN3F;T7qCav);cRpl^ukMwTY+9va(p@4`JNMy=xRV`r z&+arQ3tccRQRbP{%2RlJ!|bLRc{#?Xe$^P87|S)MJNEVR@?7ma@A9*GVr+o%Q^seL zovhS%{cdUK6V+R5?%?qDg0D$u&kip|RS^k~Wl=6YKbhPNF3+2IdEtx|Zf$B0mTd7W zea_~tVATHbv6nf&^CFk6kBV1h>~I(Fm1MKZJm^v_Q&6I}zM#unZU0@h>KQRJV;OX1 zR!8y&CU50lxUOi0gMOy_RISaRTp$bQk9h|doXuqVE+ zQkIQlQz(*PW_mtHN<>}RyXi~gM9u~s<~t7#FA@DY!trlnZl+XC*<66=Ru1|<0Lg6FM}4&rYn0JMA&*9F8EpK z6{Kl0^ORbBoZ#4)Ves<60vQo`7U!-H3uN>Pv=qyGoeM%`t>&6NW;j-$B3Iy2VkLX6 z`rOWkJgXj@IhZfOw{Y`fhj+p*{1qJ*K3d0{4D6Wa2sHE;xG^@IFZ^6_LY3XfjgMi4 z%wgqV0bwS+!ox~l^8diD`sO*m3a}sdZZ#jA^VVkeC475 zf7TU^cNH!+Hdx+sNtp2aAy4hIt0$&Dswgl`>U21KQK{Kz1;_4-QR}y?4Y;ORE~n10 z=0G0Xg=&V=?RgU)8nB+_|9Yr`;eyl71^n`yUhy9|UOs4JHfTI>QXxGd#lXig`}_vu zWG;nf&X;1#dyIdvUo5I9(%#>E=o7-5*Hq9+%dynN;FCHX>5I}c|( zNc-quvxfWHp&J%f3QL)k8lJ_;i`Z!YD`Mws4osAsGa=MV$s@HjON`CoPy5nE8x`8Q zj1LN&dD8M?v)LsVSHUF`jBKL271%XjFRHQhmV$-2sApZzU`&? zqC=RKqoG6aXYBbPg?fe^>iYU@KiC_y2xx!UOxJ3_CrJ<$0U)G7PN_SObWQ*yaCM zILINfN5Y#$dexDJ2GxKBjV1Et|0g6k3OPPdux2=@;L>5kqr)b2l|_Lsw4p%uL1L=D zkmx<}POSs06At|mIz2=0fe-(KkcIEko&;_8CAo5pk9b&)q(^bwhzu<^n_{+xL1gYYqJH#9W38B`NGQY2NrzK z`2OO*>){_d3K4vbEfcZ?9GPz?)~}y_LznIQ!3G;C{t(6=ZQP&$7HVuiApamxeEOSv z*#{pe^~9v!2a#ocFjix?iaj6qt=y7vlVy{(xJn# zp-E7XNvm|WAV*oaijIa8tKh*7KI1zRL?kpA&Ps`?VgmZpzFY&ilA z3FkQ+jQ1EY9Ch{F<*-qRt)y|z0ak{^hZHy%lP}5fyBtUm@UCcb&@1S^l^GDWwJRZ| z;DMp-BhD<*iYDth;(Hc}34L$!d>-eb_F+P)2}k=JC56ogex&7WXK=ibxMPpD2#ZT% z+%$jJhpf9ebT4!?eG1v2nfaFs~n3BoCFqhG__9T771tT z5(sD!$k5p5BGAaf8>H&`$oPPQ`~f8nuk|ljRxN${$nc^LbBa9QR5L#g=LgAKLpa`= z@IS~{AhUq~&x;StqFOKCuVS+RZOgJ@|GwaZ{Nv^W2h0T4cdszdVY7T%A7b}4Omg+v z<;_1BF7Y2+F^z*kHsj0Qpe5VS39%oFP~boK(Ec^}AcYWJ_J(E~$q0i9JRAz3WasR% zQE%1V0NXGgKVHTM3Zd)`jX7TP>ZT!CV`(K_XCiV>Pm>=}4e{g=*r>Cq>uIvmyId!i5 zfi)tH5^>sL9(G}jt3++Xzs!*0fAYVt-?zp{{=fx$<_nta4UKDdD0VvB;&9~I6`yC~ z#m~sP!-oCqgAW3_&GBBmjx9^G{;6`jox$GFctk?6Mf0KF)fg*&M#d8cY|M45zaKF0 z-2M9DrI{N(7_irPwf=73KpD#q0-;K7J@5&;5Tw1&6fb z1N+tN4UHnqOcDk^M08i{eb^z##A5WJL8UpBc`w6)3jWW3R67|K3NEv;Z}{8zK*2wR zpYiVtNA`yQA`)IfYrN$;l^;F4wC}Aldqd+H@N%?is?+-qI@l+iuwju&_#j}_SyB^c zAF`%igyX<*#|H|XLWcwkoY>@lKMK9CZN|^YxMPay>aZ2NUsa_@c+2-s6|aq7qQthq z;NJ8;p_Z;CH8HF<2J=k1HtC4QusRDl91`6tQKhhPBI_Fo4xxf3R=)!spAs7HcuWXm zf63A!)Ucp$eX*H9Lsxjq17+oV9|PK)16))E7HSr@GS3w4J*fLK#Y4B1L4QvG(@|d= zj)u62&zO_~0yO0&gdH^C5)ogt!BuwNgANHf<|dAX>-ZGb7+1G3DadntRIqM3-QwU9 zlHBluUyi-$-$#$6aBdH$Mz@L@i={OR0=*264|K4saqAElC}47&c;`WhwbY){!woas zI2q4OY-v(hsdHdP3eOAGi)SPjH1Be}=W?)ehLuiY+YE6v*0wZ*LgRafZgQ~Po5str zgvD^@^9i|6bRV?bnZ)GcCLn%5mU-W-`t!Ew{m=OsJfu65B1=N0UabH3QFKv+;(Vdd zif0TT1L|20ACh1fZ%*_6pvuEg!9Km2Nn(=CBD0=G2G4(&5)}j(8}64r{TM6Q<0Z-b zqeZTvuzdOYHZDuPgunh9W;~i{@;J?L2S=*D{OVQlb+?a9R1A3Y|8pGw0VAVLU#lb! zXC+?zF~RQs+`a4N4)ifxU_NMBtIv9CYW|Jt=YIST9_$cnNU5>ep2(oUnIPLx@@WT8 z{zJa`4T3TCe2j~qy560-R+9OE!##e+KPwbm9VB@78 z*dx>!jxapmW5USMUnw9s^T>iDx(6G$n)*F73<8WD6Q;OvE6+RN(rms#PfU?9y7BEJ z0g)-9_qZ7R3@;pzDRxxQSg)sG*5V@4RO_d>+@^+0-sPc1jSgoZi>nLYBL`kLk?=N# zhvq_T_jGsyuQ;l%yw2a&+hM_~^`J}Zhh9@dg=Ld*6R+c$HC}w`S`tM8aqJC=t;ref zt{uT#hd6jAo@5Si_K4u;V|JW<=zv1{9u<-0Ud)qvTf^J=*>xVo$q84TUw*t%;)v3N zB28f-h67o(jT_$ZFi++YoXsv7+_$jstH{EIGj{FeR=;Pbv|Eik!(#2j8{1xnWLqx! z@S*I-29=*KXZ;s5HT&~$?NF1H`%s`^67%_k>HF$?8^VsUH0Wd<DU>e3F@NKaq^MM0Ss{J8K;*9TK zr2qeT;9o$fkG5V{_TH-4LkS5^TlnXOv2o1dKj6;1QKfF(g|n~zpTP&f*XoBjBoi^>DyrB@MMb4-Z&G-#h3c;IMJtIw8d-L46K~i1HQ% z?eflphnnww?_#(Rrx5s(m1BbOq60NT3>)W72stRgB_Q7E5F^OO+V91tp~ZZh-!n-; ztnKdWs<|xpe${N?*;nzSqDJzAvTW0h0~69#t$HKe-aO@h+j?)KA_aqaHWFz968THl z3ffH6Fm!Bul;UtAWD)BjgA>9U7j-)4tZ0#JOL4GiWn|HeoA4k)gz>@N7meLq4j~7f zx#R@dMPDiy%;C_lKH*vs=`V?^cRTmvdoue(|^Fi-?HQ8RW-)H4iy{%A+l_G9L|6C8t|y{v+v(0 zU;W=h{l^4;M#dkL7Vvl4vz=4U=%`s4wEJUc?S?t^N(?0on;t4CG=6nBAh0rMN6dQ1 zGJaNuA3p?atllyv+|&P|d;0CNO1^mv3s_~BAF%M^xyZD@(S`59Dhu7lIhU6^{^es6 zYJ89&zv{n}w9U^Q_9Oij52pXh5qD;8)^C2~ zAoTb^3qwHlC58%Sj_8Yr85BfJ7Q`Gp&gR7Qe2)Rol@B>A&GY?i3>ihl<`yU^EPU{Q zS^6GNgVEj-jXhm#dQ}k?3mBp=En39pkTA(`k;wPejS~)@IB-zQWs8!)c`tzu3B?l! z&UBb)x$wMXEnCH=(lnL%;lajK<~xrR3Qx%uXoyv4@LTyrUWh7RXfcDAYx?6w4HFz< zc3+HcG?*cwQ24OGNw&7I;PzpIGflS-Cb(4|_`!bI;Ou+;hKL67oiU#uT-bSdMV}^% ztWAqTcDw_~0MIgQNeK zGj=yRtWoSgZ==}X=yLJlwV5v;RC73LFgG%Iv9LO?=et+)+l{B)CH`tYhx6AGu||%) zfgg7;L^|*==z2{1suVVxXP;ze!y10s3m>jTGMqgwXU`a6BExd@l;el}zxSEh?KA%L zBKPr+hXL*^3J&rONekLR5*%@CLX6B$4^)2=>?|-6`Y+oxH{^Qr5Aiu3LX3MBA1GQN z!kK#D@Yk&N`$G2F4#)S!ez3jHqL6JioyF+sZ_cNmwI&|4GGe}B!OoDrVfTfJ|3c5R z1z(owU}NMFVc4-+-h4PiMnWeWQeml9{Bp6?LdrL>2rw$qfRD{nSxBS6w2OVqnjyA% zm0P-SM#trg%m#5h47w~q2_6RLGctJ!0vr!*+{mRE_iN4+8-eEX%iN2rB2)sn1TQ=J zi?Xl_IGQqAEml66!uPy~CE-}bgu=teDp^EX zMPwX=Q$k0D?N^UU)pd%h0(+I zp#t0YB~nZohXZBwL>RX4#7Q$;EL|j9siYtpD3I{LPoVG*7lT5|!r(u(@eMkAnD$7{ zI`Ba*~zt`5&B-DE)Bm>9SoF_DzQx3hc!HJ#xHS;GusY;%e4Dp7aL` ze(qTEqn^ECgMnj6i3Ibj1)K~QTH-Eh*s%XdpZDP39Em#qW`+ny4&?_m8cYWt*dMpy zQEjMUKh&VY^yevK!T}b>#l{J8Vw1X7a`Y|Oa7jhwK@01tCw^KhZ!#r1$7y-9iv+a2 zt4OeF%i(IsaMs>?kVn3{%i-laI}V2~O|HvJ%(%WcJ$T1?h-0;5R6-4xMnJ=!A3Tf> znoh0-9U9E+tS?q*t?+&CdYrQ(_Pq+Hje&xfwj3AdgEXz`LypavADSF?Upit?_)s9> z_>u-6As+UoEeqNYEMwjx+SbkaqODLfM@NJ02KVGQq80Ux$p^BJU#L*n*rYYX-Y&?3 zr*J=`V)x;s=krR%QbI)pE;2PbNXb1+;MlP1Lac3<7{k^DdPfsk8ulJ^;cCpD)1kqo zWO3xdf`x(C7jY~$Qxagz=X7k;G``4erEx~w#L-*CTq7pIm3di+(@_t}HYR~{PaGB) z$R9DjdLY^VZt)!zRtv5zQ+_!mIxi@Tsn{X$`8Y$28e_ut_CB6=2l0a({LHG($8GG` z8D^H~6&AJEp1LQ0!JLiZ#{qse4*L*Bg~J~|)_WX$V1Lx+JJSO-R;{?|GkY6nH674m z&|&dpT(n3*GGEczQbH$bQBcbP#b#%NGir=%-zPYHeVJqsVx*q-#O)vV1~1m|=X0D` z-?24_XZUrk_daSAl0fv zE1`omTtm03lS9d|R-tL3qRd1gW~K!G7K;ZHG-3}52=a>dv!rI&m@Ku-c5o`ehG<7^h5*PIhr2C@i0VjOn7Bb$-$_vo8E6LV8ir`nNf{BqrLHz z!itU;jXzXb8xn05k54GyGLfaBh2uc7?Td*rlMWOqF&0YLo?(}0VNGUgyywK0FTt>- zFTF{j<5M!<_eJS!YK8?Z>L+bkp}n$XLV)bv5(LkrjLi_D)p4yYCsc2I8zx4s&qnJ69SmFSG2Hhac?qg?z2%8C~rHU@NYq) zuYiF9CmRFHp?4wt%xVd&3@(lqVoWbu>VkKDS7B_}C=kSTk$H2I0HgAr_PqyLlq?<2 zm>zt{5s*D`gOf$|A;AexrFa-ZUP*mZ_Btrg^^Nb4KzV@^qoWKD1KYh0{&sW4ljm6s zBwJ-Z3NWiMEtFZPuDyuWS><7Y6Qk2kg(|5D&az@j3X+@_8~H>NW_hS`ZaK^#&LY>b zVS+&NBMxzPzViwTmM?M%Ud5(0Pn<=#>q*~(4w3R1j0WY47Hk!mpr@4Q(%8{Bqr#1) z@qK|J!$z42QG6?gc%(O)L%@6ax4woD7O5 zvKX>DC>#_?{+pu_#^T1CxZV9Wac*OSQNW#pl`gaAJv^b1VSUuW#YWKSx#(o2gB=I!bQHF*G3%_yLM zc*^0!49pK?xbEDYXzX%;_wtknjx6t7M2!>{Sn9L17`)PDWp2L5$;!I*!GhqX4>CON zdk*fEkX*&sEupCOA&qH;#T=RMO#))dmlkbs4Bc=6vSVs zsPIn|Rc-t-!Nz5Sfe^zQnFk@vPW@F53*ohR|~=Z4b{9o`bSYT*Ss&~XXxJjQM~UG@x`*{e*5^vh?RK0DQF0GTSeV++ z$cr<+V~9|aufCMv!^hluHC(IxqA^nf-+|-DpHwqHbV^WQcMxJdwg2Rfnw^1F(?kUO zALt}HCa=7}6K4OzsW(Tmzx|MZ%g%+<8~gu!cwxwV(pPwI6N8h}Jtt<(7bgsw4>K}| z+rDUQR$|K#arn@Ehljy9y-9#4_CZUMO$XN+0il?0U|;L44wu z&vyhF7W8v8#PC%(GBzmLZd@YH^pJx)F=6px2c37#uB;r~GX>%f3UCEJRal_+Tt)Pt z!;9xEK7x%)LW8&@71pgQ&}Co5<{`qcvVVzq(}e{NktbwZmd;RUc=6HtZ13xQAGbL( zWCY?Q_ee0LiB>5ja8GoII^6i7#*$Ie`ei_s4vVwP!UG5P9yy}CN0e3FIo9X`H~Zmx zH7_qbDF_T_*YT0uVaIXBY}TAf9mz>rmcq8uN~dnSMhe7mO%zc&%48*29E%&z{`U-?pI@{b2}zJ*Wtfo=@LY+lpnyq+Y2g#+^Z=%Y>(jM= zd?uE zJxYwLIF2-OaC~QKVp(7!DtMscMq0O#szArd7tMSf`UOrRB0E}lERlQO%%H|~N0I52 zgh+)Z!-n@2PE5^vTKBjy&UBQpeDA$Lk>S`AhjRxUbS5kmWL@s6N#v z_L8xx`37@OCsVVBSmOsRkr1s4m66~bsE1=7K<iJo^`>DM~)TAEgK?uj8q(5GSZFj@iFwi515b3y#xnSTg4_(&f(jD6x2%Br!c@FfdVyR5X7-y%>oW#n+Q{mCr>hVimZFC==+Adc|*wrA*aN9 z+=oQwtm8ajb&$iNpUYuE;Cmj14Uw-J9(ZvdQV{O?#`r{tVM=&Y7n@!|3;PDWeFu43 z4(x8^U|X>Bh=$&WWike@?@i`&;qb$G>3_=w61Jgns^TpA{GE<-B%2qAF@EZ+vh+w>a=}L6;p}Tw z3VV1ZbcFiWGAtBiP1tDg!I2?B+@g7pghRThg@8kPfg-~ho_kYxlvtP>9(XW_u}P!~ z1oAM1$Y^sm9I}1rA;@O?ME9XVF6;dZT@zV7ID9`iJKy=>%*vQOk0Zf;=ZmHZ#y$d< zS<=`VZadT}>{xL?LyTdIfZtw)Efp?Ii!$^kH5srhIb$usby35*X=6l_PKDW$MYj%I zabRf|2nasJAtd{dg|q9cD_>J%Ta`k(f!QYkCFvFg38n+5o15zA@Ep8wVCVCg&W9XF zi@Cidj<*RkZ0nXe!DFG|q0joFv4}~4#kD|@F+kC>!I~o>O744$5}SoE<5^eJ=N~pG zmDCBW__F6~m_Yl3BTfzm6YK(b1P*dkE%)9Ru^{^4t?6+LP6~oy92yNdLR(#yySwl> ztQ9cUP-0y8&P9${K1MgLUgcE^`#K~KI&j~8#Spbo=3<4DhV7FD z4WaK@lvw5|@^L#K^u8n^<{|lpVUvIiv%VsS?!y_}`PF9>qOUc5Z{k>9<(Ltvu!UdH z!N8T_%z*?+)ARyxFSv>6_7VY)E+5}Uya_IqFY*ix?IVEP3smh~i_qA}L zXkS5Chc3qkyNj$RdO{q|*eW)3s4^TglzY4&y7Dhyv#7)7rh+<)+*W4!J`Yx>?J^P) z6-(qexK}*b62;7R*oZ@(IX^={c`@sXgINwYB%D|etUk!YmazAnLSup1lg0)uZHMmJ zN!hoT@js~HTwo>8{>b4^9S_^p6(1ywcvLzKYE=BpG&vaL1m1snwY27`b-FL}4-Te= zQ%5G`|NsAX*}+B@31-F>8jLL)HN1Uzf+U%%rmqgmYht%&HvF|vZKb(p;lT~83VnR_ z73D8IMg7n7wY5bEuxK;}N;FC-J`8Zl+9upokr4P)??tS?^NZ#HB?dcz-|mhE3%G** z99H-hd4hZKyDCKkRo9NLAVz~#UgZi2OefX|IP81kSfS6dK$mrWfgzK}a~6ez>`DTe z2eXc_933BSXqyqT;~JM> zk_z`!35n?pE99#0@w6~KC|F{}9mwjiV**>Ahu9$nQB`gx1u^B54WYI#nl3oFwg(s& zRH*Z)GZ$K4;#lAmz)*dWm0_o&f({>-$|@md!Iv6O8HCIiF)k3YZ>V7ZHHYCnL(zuz zzdxiN%way=U{J+gmm#sIUa@>rLHE_bKRo9jq%dqh$WbHEaD9$yboPNC#z#7@uR1s9 z=Y@L44HBHr5C7^bt@`w%M}UcCU$gBGmKDo?l*k{jzVA555J~A zEwFFQ(C4sUdh~DT_xN9JPC<ugP5zl<|esH3}7e1~1#~-|V-1vuM!2)K-Mh-syjK3j1DbfddBqJsWFwXwD zAn}9ZYW)o^x?=ndpH@E=zxPu{?p@^L>*5vmjfG4c?9Gm!7FgM_g$Zy!u(AJF_u`CH z%^pRLMUe$I{{LRJu4?4&vbbpA#NOD@;uUu1+Ls^SKF|BS{|&3HWdGwS8m!-z+Fg_| z2@zPqsM6 z0R;_)D=hOm9uytQ;bS@@z$DP z?#&Oh-dEq_bzXh%fs5dsKA9%vdyhXmJP%3OXU@0h!0bCbO56vX9Gx|ESRZT)a9Dgu zfV-)mm1)LI4KWsD!Slgq6qH0vU$XOgFde9UvBEdN;W#UE^Bq2h0G>9tbLGeICU@Rygkk(M85W(ij%)+9e%XEDa z_niQysCHXnC7q)TcIHhShb? ze}ArPq+dS%L4hH_QRv9#$B%y1-~aichJ)qGpI^=G2c#H64SxLb`Z#$%i$URsas~r6 z$*N`x@1_6b>qTv`=5M2+v)r@_?q1P#)jmqCF(r$ z_#YUsFf{R0D6mLwU!$hX-tb@l@PoY2#K@xkj2D-`T79Z=F=jOOF7HBaYaIx8QYKQBAWQ7I1OtT!iCJ6HGV(L(Q$8l)&U6vN{ zJpw)4GJ?)6+H-gxT&=$Mo#}$y`^A&{`CZxfK2~oMFyWck&Di0@c8{kaB;95LOT+3* zCxrQ=zOT?^S#$8fx_=Xe95zT*9}Efb%WCdweb2^t>Ozig0_z4=M*$g;iU2Nt9Vu7m z6&gGIx+EJi1U+h0n67VZY-J5&-O?nW9}r}qkZ_~5is_c>a;A+E#??pL6RnB_PAqt0 zD8lT(#ldGG-*#ld1_QO~iOdF3-PR1cff5D+O^mM(ax2?0z8VmQuvgoraGCbTq7pU}c~&xxBk z-$S2|!{PD{`2#CNn6-r*n=Kx+@i3;>@%(sD%i_>|s{Zq$@Ynws84Ay_AJ7zk-k`Sk zz%M0c3!_Gf-!UKmuwP(r@G$22z;dgA=??#+wJi(TPo3T~Cn{#u>hRkKHo3fKXl^#p zO309%zplc*;R!z@i^QH9E~O?09uDT0|L3ze{5O$cK0T}3>GFaWE)DKWAOCNRa*U8O z;eR~E^Uf0w;rO;fk0LLXfOFyV*dKT_Tw87LeZ1;{mCwq8x!&gvRB%tf|M5|1c%#om zkG~=ALDq6S3?ZkoF*uQw;U9F?|Py``W(Xsah}5lg^a8BzT;^)YNNr!;Iua@O@-;~K>=>Bk^qg2 zN5?mqHBAt1-+PidAf!W_T|=VjbCbdhhZ~AJH7q`?X%P{+c!o`4opk&0d%{9ow-j9& zopiV+x~Q2w4BB{O4fExOmIVchj1i6xT9~U31@OJEP-JkiJ#ny_A;4+{H^apndQuz? z(M65{njX5$$_>&XV(Nzuh&3_KTc9B2EPvpI?BDjk4jN3)58K|LUI) z3ai-0CtLoLgem7NWt%x97`CiW zNMLeN&@xbye6b+Gk?F$oMF$Nv9cKDkwi^ksG$^0EP`>vdN0EiX#5qE&iZ4ChRX8yk z-s5o4QNGFMp&QV|D19Q=@+D)z2S*m|DDKtJ84 ziQ@p@7l&hgvzP?Lr=DasR^jnF$e}2~5W~0gLLAeB)$?k8*e__aXPEf&0`JGNEnd7C z1}Uoh^8I}C z2Y!a7-skQ&1eV9#G_YU{xNrAi1;Yk5+ixpGDt>tWYSh@*wD>XOAC?6%91FZu80wvP z`QjLlw;%pcVgKhv_^Zs&yjJ@N4YmgkM)SfQi&hxh$sbsw#>;+Bwk6BrX;x#iR$QU; z)`vedT&g43)Wb7xKfK9m%Caqu3)jgdLq}9848QMI6HayG%VC6 zl&^^N)3A{^T+kuDXv>}(B1fLP2!?7Wur6WPDaaUWAjH6``5-|v?w~|~f#kYwXT~WP zoD9wx@EBj>aLM3PP7+|dBhb+Fo~4<^e;c2GLx|`6pU}d=-`h}r zuvxir^1+%mS*AM@o?3*kf{9_Ra;!rqsaF@WpDe?Of#F;PtUH@rrf&B943m^XBXK!Z_mH+vHhpoW4 zS>cR*2RF+O$p)W(eIfQMp8B0JYnT?K@jBQ^-wUbqKb~*Y5n(9e;;vyNBe=u3N^!wL zxf?o8cN5w=Brh>3IC-!*=5ac)*}i0DJkY`{QX|OoK9fmc#V4`fAx#^a)dbqu_9!yE z`!Ip&K#aCZ(u4&TrVpA-&+r7cFH%V6Vh!Y3!o^sqprLz8n2%Zcq9aq|AwSnC1sPm1 zGaBUNzZxX`pOGQ5sOOe9(>I0yE9nkyzNT`Q_X!r_ijL(?0s<3HaquWcc!>CZa4{&p zq3qC-uy_(X<3kSiLly#F?^y)&+4nTD9-24dsS9^wq6)(Tj_>mia52pPF;#RH+lOf? z5d~76yz&fJ>zV)jT)`;v!;ayA0Q(=q@4vj>udw59*geydKk(**dcJ_{_x+k5DmeHY zAJ`vf_`vsTmu<-VqeZ88WymqH6(ls-F~2(7P{205ub=X|m^1;(i~NgjImA&sM)S@GxR1OKc$>lrqrI!ONstBjZ7XJnkAusX=TLhivhG!Uk>!ix+7mEIDF*=WrnFgS`S7x*iT`0&G0N)eoAKEn}Vhrt*3-87V9f720K5 z;U^#xu=Bk~n;W-Bbd!Qc6gV;U>CJ3@f>4?Y&Xu9$*weC10@{sxPL5||*^TheyTl@F033`3VQ8+NO zLZmf$;o>>s4SOTozI(GRRxr_7u=ai6;eXMUvhHNiPYXZi9o%-TXOJt6fUkAE;=2>Q@k@WE7{VWVcy29AsB z9ZZ40<`f?I$D$w@!c$W&dIq!v>tqG{(KF2l9NKs|5@H{6NHB#qIMg#0d`SALmDtcC z;IczSlTC$)PvhJNJ|ox|SH zXrj;@(59lj;JD)h`}0B!7B%s_%)i(aJ_uMJsNjEcaB5tBATzgPlYn_+%SHvMpPt1B zA1Jo6>9H`hskB&ru;OvyXJq!UVc~q_s>k8Ab*r2>^8trCo)yxMBAgfRKF58qiG#f% zv0y4=AIAa~rUo{KTff}A6uLA_$~zQ-4!7-TV`AR<#P+;E!>Yr30|S(9OcLi@#C4`a zgO!J;J&g6h7E{rbrjG{&&U^_FSJC3-aNW~l5c-fKA>@~bgwwrlrVAYg!d;gd5+oS* z&P!A<`o2Vpi^C!5i-!acGt-M&Hw{gul%@qPE+!qV8O;+V^gL%u=&-VGV3QAx*;BN6 zYQyOVy9!c7%I6r!{JbE}Qy}s9Du;nV$K}&JI;@vmMV|7rD3m^G&@I{{#pqTm#-gz9 z5l2*o5@V1slY!X1CjsSrTx|RmN&;fD+yb1LKE{0NP!yhb;H=`22v5dJ2j)ZfxE&U1 zKGsV}VHD9x;B81$cyQsLfIfTk#fw@Cb?O%JE3>n|nythp&yXv}e}2`E7cC$DF)T>p zQ_(VGe>HiY<#X}G58U!cSQj@tGWv!eD&P}pVw!bPf2z0;iwyI@>Fu-fzdt$rLq&>} zVM&d^>5YvYHY}V<{%c}l?1i4~@sjUkzHp-U!^x-x-1dzDEJ9N|onpBUK2WgaP>?(n zP{IG%`*gEH0>6ASXB^K#o|=yj4ASfy9JpDV4>+VT?$iI+P{E<<*nNDzGJC_n8UfIX zbv@Zx@(dX^EbNS}g zDdUeE6N_ZMV=waohh6;4O!||>x)~oR7>DudpKa#O#&i<2PQBb zSg6!IM|_d`+B+v2GeQI!V#KPV`a~F(&J$=@Vfk{3qRe`M#uBZzEPc4dDxhY9W6CZN*p{O zq_Av;M@ImY&I=c|6)W5YcOo{=XZSWc$7_J>BFfR1|pUM7rH`)=NS}S5Z@AU z<`gs2yMRv%r#vif>u{PPW!&X?`JJreDLxOL8hP&joBO3586NR`XYI_1ix6OEAc<|d?HC_g;p6ARBI_&m#rLqEM44W)gl}b3A`Fuj5K=s8^ zMe{_5hZDH{zMC8pk}C|*UB$K`u#HPaAbk__Bf*)150-Q}eV7qmeMm!m!P++>3}4%s zW-~pA5%l4{^T9^PD8^^@ynpb#PBOU)AD#?m-i0llCP}p9#(r93(jR zSg@wsUS?)gRN$YbWKh25!G#NJB3k%tPj3O(OfvhcRr2u}PZVbgc{-d9$Koee)54eX|{au$4WVLaiIwoq|yAgf2wo##u6 zS`O&$eK3L9;W(3kdf@@9>Ko!5tPdhi-8;FwEr+vJNrau%f#slBZB*xyQ{4xy7T7Rc z;S%}l|7Dt_4c~!=cYjPICo_L2=vB^|tH`i;p#wvPc0~YlPl*|aNPYZ|YrHZ%5)5ab zJ8b)qRQa(x(8Qu8^?XHuYEy%lfrU+}qhzDO5rJtBJXk|y5)2qS z6u3PUI&IpTZH%ow-Wkd6JFL&PM0auGyl%N7g^lNQgzgI4l<@E>b-g^e%K3~VbLJBP zE7@lULJ~i4OZT)LN~qzG`w%v%x2vc3A%`Mkz&a%n@lGuzZYD>Cz7HMN`?{tCu`su! z?@^REI75@k$@XDK!hy3dHf?0ta#ir~!3zy5Bwj7xTzulL0$YQRf?Q;r*KHclaALnZ4!KwbeCFZ%~kLE!Xa!5GFZ~{bOUl?Q$E*#KjL= zm>1Z`d}#`};?N<`+o*Zo-b0O-#cAG7#RV=M9S>5aniV{3Hu_Jhc6m?J~Xi%S9q|ct6Ri|yJ;#HX5u~8LJlCU(eT*Q`;<}~}I zfh02nH(NDx+Mz@at({E|e8nY21Qp9Yl>5XP1N|-EFgve^(BnSvM8fqgSDbvqr_1-k z8T*2tKR)<}rC~xvhOv;t2gAb$#2(bLI3G6PHB>fOe7o^w#OZ0>D=4Wl&Hv8Wjvwb=tGW2dldN#n}jAz zIB;OU8;gSy+r7StIed|uR5ahQaX5-E_t3TqkP%`G@cPo2*(4xv?n8@Z+yNIQk$xAk z{tYT-T#TQTrJEeYXFd^_eMRulgDnS|M8x)p2+2uInG^KE+2PPx6e&j z@<~9F=feSp4fTy>2M!uIyNES?XXasPViIAoXlK3iNkMV1KnT}Fg-+IvgHszPOgLc~ z^C5w0u|*fl?ZaklP8SulBsjTwN)r6jvq9jj!IQMIg-GU|j4qxP)m=#(dv@j)99}%!Bt+3-O`aA!-OT~-FUCXDaRD|hC z+C6dA@_5GJPS9M_R5%-A|bg)t%UjE<^=q(H;r3Pr}?y-ge~Ojpv2LQb+ia}ie# zW%WD3!w}KW$->FiWYOqR`d+{z!I$Tt!%}HEVRs9qXdd6a0f{F#G_t21YBw-oTEp9` zu=678UdIX(EfLn1mZSt{pYKfEMGAXDSsTv?g%-GQs0cK(H0WD3AFR@l2^V?Ita4z7 z#sL`tB`!e~M*;OBWu|K^4M7_eodX@i44F=Za z2m3a|`g{NH?LYd}@qAld;RRlPp2GKvCZ9MY_N=&k&oTFHPXf~-#s*DG6R8DnE*1VICiw*_ z3?JuBh?3awA@0DP9rvd0>yG;*#PeklOS9pJC9J{g6%HIeqO72__#p?!nMVo%!7o;A zFfMkTxs!vX@w&hP72)E84cyN;j4Bivt9CRoCRjfB!NELl$;}@%6B)E8aw|FrOxpaS zae?CjL6L+21tlB#hADza<`>_d(8BC}CB9(izaS%ytdd!Kubf!=P@`G4DwRW- z-EyVFLFFZaoG&iTP*}>yvEcT^4Nl4yO$-6=7qJzIePi=zVmtDQgQ>0Z1!wEtQ_&0! zXGK^YI@r1%geb{WDQwYtIiv9pTMuIbXv3VN3UlLvi65F&SAY2Ssp7;Jc|L{$9`?qD znmu*aLRY>onIBxE?ELS<>4Sfs=rera7hLUW|3arXU1hgBZ zgew#p3v{cR9AW}P9=;QHb>i6BqO?PoZEvi@-$2&J76lF2C%R8sl9dG+l;DZw70fZg+^v8gLEh<$0grtm%?Z9<&LqDD5hsKkd3 z2ev+A-lNFQdfp?6#X$1TmxzWIW|hJimNxZ>--nF@gjqwHr397?N zEhQy&92%-J0!Nm)$18ZD@Tw9CuY6C0SR-M`7QtYhwgL{q|%Rc#< zvITQQyhLAUbDmz+-*F`&_5trH_Nm);oO~o8wnL$*e8W>Nh7h4*9-k8~j0G=lWg4{} zJ-_$Kk$K+@LYSI%JaP;cX!szvd}fP=j)fR=NAwK|W}O*I3_a^TwAci;HwhdsQe>IA zeeXjSLE}rpifpX+I1&tZKJh)#Fyl+p4JW4GGbEUGcp9fTIyg8P9Beqgh}$_xgk9N6 zVeio<1^snSLTo8du6%Bi3b#<)zC$1&?t!CY_N1Nz4vGmqd`*+e_qaIqDBqCgP7o4u z;*oumu*okaVMPne!E=i_maI9iZbo!#c$ePo$Givh3DQs#Y+4{@;9 z)oJj&Kdg|v;2-mbhZ+j}-K#AM1Du5#-f!Ca(=GXZb76Fh5{vb|;x$(ME}_XC2J1uY zex^B2SRv4u#&aU%i(?Q|gZS=)Z`gFc?>+C<&~ezLs5#%uMXY3bqX)OZ>r3Jrc@&wn zzBEmB5jSQwV?Orm5K|E2!%3_x$tIDLcnuwxdS9|Osqpj#F@4|DGW*gaCGO@a+)Ny4 zjJ^Ve7mZj1BsO1Mr0aHu$B~00ue9mlMHW#_kI(0f?Y?ghu_$5@Nbo$yV8VV*ph19R zhoX$>5rGZwJAsbTAI|)fDr#?Ep6#{b(xV+mJNg6HN-_Tw zP?*lw{;7|3!F~Cs;{8V^YIy%z;KXA1Y4!p04>dO!PhSao>U=0~8EDGu>%o?-$v;18 zl)3OTGR{B5A{2U+=j%ZZX7?X<0UrE}Ofx2c4s>$TlkaDAyf34-HC*KK(NEIy2l`f= z67k6Y&1h01u)v(Lw{OxkW^SWB7xI`d?Q30gF!}s(HY*-uN!#ZQpV#xngve+6|rLqit1rxKZIs#R)s6UxinCpDxJ0_wm5T@`i&ywmw*(a+z}y zzlkA7z-Bx%FxsPuLKn#+bc#!IXo1pSW1>oxANiL5$JjNkWMT!?jA)f3**P?tQ%d6k{IS zqI;%R(`K71+4HwM-Dm8ZBgCJ5(y#Pkz&)!cQmyL!1?Id9PZ(_Ze5WRO;e6qqbF7cO z*KW?vw&qxqVQp7XZ?v#|QTY0nQk}jP5d!T88ERBA6vfN7ty^az$9VH_eb5>no(k6a z7m@=18pi*-UhDbma(-6|GsnH8hact@^*1*BZ`h>hwPOA0pFCo7cYOGl-QC#UdMd*? zfXg6l)t(n0H}>4%Q8<`aXL@b=hb?YP&ifV4}G)vig-Kj0ggq~FXfy5){kGp8K~^ZUjPZL5?EY}kL=v3)Qs6+F0VL5e|K zyp8%Sk9tPNJ_GjphRfoCNHYoB2;Swk`M|fAxnP6Z3`q+6@V9 zD;nz9_s!tgrCIQg&*57bPl5M@orW13BdF|4>r9I2AYBl z4hGX!2<(Yxct4@d;e-5*{sRUA3>S>%uU;IGz|R(7Cp7iL_JbAdD-HyCavZ<5yu!TU zLqh&)Hhm892RRu$YrGiFurV_`G%+rIDt-8VSoWz-{s$%uTdJEsJ}~|x@Ykfo&yMZK zq!`uCs+FEo&<@>d)8&upKX6BH&!f!`fbbP=X`<`+Gg- z-%AevV3S}!G}XKB_ag_#i&q$*zG|@W6m(f2*Z7|OgD^)yi5KHPJ$=3AtqwNTjvX%# zFZjo*!+7-Z`x=Q83NqLVD9S|KY!d_^YcLt^MZQ}5BOMFo42aZ6k$Ak zU`LL9LCczqP?<>oiwl3AzjmtCKIW^Gyxo75A1sbHHD(yg@iKJORxb1DY*q}&nsLI% zp5;8d(%y}h8iLj5T2oGLZ#|&3_tB$6m;1RGB91djP59k@Q1I(>*Mcm*Bhy&wE&1D= zFTC01@LWdTb!wZRWN_omllQ(iEowIJJi4pkUrmwVoW6A#u` z7|4CN;8Jz$Ql_JHlfyHUNrKJ7JPuvncN~RlMO|WaHXL2f=@s#PBKtbt=8d;19ttdH z>e!rTWTDlT&vN*lx!pOgCbvZiA#&V@m$6ouaG!eI^6*~nV}~b3uOAp(uoFEeQ@LS^ z%Izir*@BKaO2=Fd26X(;wJ`PH^FnUfWWK|Om(MZGja_df%XmWMb$_eqyay}T7Myty z!hFAF!-oRF#Xa>l4wt0Q^ zv37SzNLgac{vg!*>d~x5&n=wH+}?Xsr=RaTvS>kK#_KQczmM$USvQ&g;TaBAJw1jC zZEL#)y6ZSnKhEfPY~54N8LfUv@q;z%zo~J}9IqVPmOj4ppX1tmi%akM8=@-N7o<(N z>-W_`xMYGo+n+~UO?c*8J@0J~GOYXiJtjp%JC3JiPg+Xg!Yg}s7raWBl2@z>bakAu zt0sbz%SMauM5E5ji&uo&a$g!$MEtS-#I)f3@?#rc^a|~LZ^`w2kB=5lpAE;%w=+97=CU}xWvEbceB!k--o!?OEs=5tK0cp%j&~ft)nu(4>p8a zbj}Dd-emDZk+Ep+Mh)GWf-VB?Mduc^vMBL9325k8pdWLwI%C4^tFjYZt#;3?6tJpL z;yUiH&^xE{`P4~LwoeW``M*b1U8Z_~3MVTI1B(g+*79a& zn~DJT75Y&oT8t&%nHtPWf)ci#+jD^3Sym%mFiRokrHp|nL&AKkj|bdX4A1S&Rw!b+ zELYvCw87MEy&%I0<<$oluw}fe5Mp$zH0=D+puxCIs(q5-D?!@>KX~_S`F*xYG1>L3 zt6FOHJx+#yFAY|37cM^1;HD)sQ{;D};#`)435VV1GA?+yau=UuGh^U`4QUny0c!WH zE{FGOu*CTAvaA#8(&d-* z3i-dO3!It7$;f=ij5m_iN@%W~*$o383AttNPKPe|mG7A$$uGuz)npxVVzo`+X$ z?=+*D*9Q%B6ui9G&fsMD9Ng;Qjzue5}^y^Jf3b^j*S-ln*KlW~o#ktE;yCQeBKhnH=s&Mc}a3uc8#$V;{?a+tWFXLqyXgJ~@(&Q8e( z+Ps98@i;Hgdwy<*4M*??CiQtK>rB)n_?yF$=Cm(x<(ubIW0!f}ru9HMhqu%6-j=;i z501-e%L`h^a%YO#h|XdQQI=?PI%w78P$Q7HL8!-%uW3^gw`hOMtc2DJp3B6!nVBDZ zUbp&Gb@Ot<@y5b~31$LaB@(Iv%EWGZWf$u(7fttKstl zBUQD8pArS^I~(HWFb4SilV)iS)jf+)HlK;5I<-P|8LLMxcnz*{j z(dj_fgF}ga76;gz8$KLR>=a^sWFmHeOGduoNA$@=376o;@0jkVe;x^KY!b@Y= zIF2-Ze6=CLbV10w|A!L(v3D2#XJxDv)VNS%A7U@$o)qvkK!VMT$4-xpBjG?3PfQ$_ zX@IA^3Y*mm{`(yNei%ObGlM5VzHvi;n}4Sxhc{c062IM6k=17e&(*kFO|WHa{ls)B zQ8QxFiXHC18y_f`b0mC_f7-(MapL#mulC%2)js?4fe!*Y%?JLc32faU$H5@Mp?W}W zMfLMet|rOCik?sZr`H})FfQ^-{30+XVDg;O_dG7n{x)vz{N0`kOV10s?LE{hQ&FSQ zd5n#R$C=^a!v}lze$@0}+3>!V$r}LXGQS^V224RXk#Q zlsV>$+lVsuitPCz*2exN;>%{vMqY~_8jQ~wR>XR-EpGVw;O_*c&Lf9ji8$nJiI8X5 zI-$vP^Be{K#8gJKdt_21wAMD{` zSfH;W#F_2-lBLm6;abz@z=Q*9PPv(}Zd>Whm|&m(f00twyoUxSq&zEhgj)}MQI~D} zVQ5h+{ud-xalcD-skGJXmJjQkIZl5tyRRnBDLyQgh>8?}XNFCJbF}HS#j}-95yUmk34MHzb=qa;W)g1z7S*k(o-uh{jmGBQS$f)hsKr(Jg1M{<7fQK z%cd{X*gaJJf;xISy;^28UpS|Hcf%aASJ;~8qFB+g$0nzm1{Vc}jNA+XzfZ+*9g9P`hh4?G-B;Yurv z7%u)W(bt!4F;ssLV5FzVk^G)<;rB^@0{9;$fiBnPU^vJj;VIO8rJ=%6zW>1b!v+aW z{EUpV_KPzg{Qvx^-E)n*2kvu}X&S_F$(XQ;623H;&jZ+P&2TJe&j4-Uv?ZB*cAvAQC7FKk#iULDz} z8g}#70*MLCQ2s|km9DAhjrARyN)-h9B}dgu>%K86h~99m5hjn~WD#XA{!12p@ae@&?12+Ck@$e0qpc!wnO z0mpfu?zj#6PvsvfzfT>>KC~#HfjuD5{lyg zA9C!d-u+zTegCb80#dw93%T8zKE4)sXC|~GK=*{h1{YR?(>)9o1}hdc>xs27Xt8ql zxgPFNPiWXPf1%}vf|!y9V^&2e#np#DxCt*7laiDZ?q1zgc)YEks^@u_)ZT**FAO+R z%56F%*EkjCwRTUiDOdHAV?Ng19rNLqLSo`VjwbH70OsV18_Du+i8It%4jp^;<%W*H z_eCl){EPWG8>?!#xjAmQ{N?Cyet2U;oCWuy@cH825igkin+`rauz1&UmV+WQof(hC zNw7I5eo^Y4e=#Yc^U=YS9R*i}SseR|c=>uv6@C>(3G=Jl#>9#B#>EIWd=ucgCN39p z`Cyz*#e%Feixt0kA8|_BDyr9a>sQR=(h@W|Zk|4h) zGjm~cWw4@^kVIO*!K#8|344{&7!6L$-=@VAC&Tf*eV12)Oq>wUVdou=7kn7sS06gasJ6q9oyjp}Q*OYCNe#c`QBC9L;|0a?A@kWE zSm^A3b?(3a^@a>5y_dIcAAg{~gju01{?qrnRl7BfHoc7G*?+zNL7ao++J&>`ubh5$ zx_G?yPphR)0gfLGI{(iNxBWhg|8dJ935EVc4D2gEIDQx15?3L|#B9*UBhY>*IIio+ z`i}d3->))fOkrA&-3y#&l{oMG6`NEHB zJoaoK6gd@c39vOkO+B#i)BH6T^_rvBtbFhz{_p=MpN}~FV|lPej``Pw3jWsz8yO=U zzW+putg4GWKgWQM#2XfVxj(qXp^ObrSKQ+QTs$aA|aR6fPM=jUU`S&j#`NHwq? z<$Q4UWYfWh#>fwmVLzDTMEI7SXh=Dvq$r@)oRLwoApQzt#mPq*(|ZyQs8w`$9h%<7 zwyek?#&W&l&joiRwjA2BMa5&zL(lkqMS+AtPeSTJ%XfN~%Ey-8nfrWR!a3RUw(LnVyu61V zxjmc^*deB>F3;?#y@PFrB$LvC3EFHN7VI`hyJtH;TdUP>&*mQ zT4U}1TsR}&uq$Jdz0lXE*XG;V3$Y)*aBka&I;P*D{a0V4@wfiJH#TEJU#_loW0c}e<$RT;4-gf=IcE&#p zD?o?y|A{ca(j@P~z{%dw$|509?|n#WSB@ML%Y+L4X9rpRuYNE2VZ)-K(9F0yXpbBd zGw8(bf3`o;cmy0;@kw?;QUusxWiXn5=-b|KC&?R zP=NS`pwGe$+uIJYG$~#9l5t^SiaAYoUW0SFAZZJRPvV3}rcI!L#4?^BwEY=1X{Ee7;Lb92O zYl8#JgLcQMT0hc5&mVR^{VGTP^nnCBp5>P|1^B(!60)(IabQ8so7x?T!b~iVHBk!t zC3y9JLUSWS{lysu4h$cfxcKYe9PF@R;V_Wc@5mS*?dN8vFBIb6 z=Jl{>^5Gx4oD4S%~KYm|l_90P)|Hj8Z3<3NzY*^$U+>@`V=51zCsNfJhy+@^m`)SvC<^zt! zOadQ_+4R^O8guGmRLxGTkYH|XY5d0jWLe|XhWu~Y{SE94XP!)$k+9_EMi&MLu>*Dt zk&)9UJZv_f>T~j(jS6GQ4+G(d-wV1N&+f3}5V>Ty`nHmt1;3`aiv42a$1L?MliQ9y z{-|4cOhGBrpvvLngXt@3Wws=QF*mO~>}Vl;)L*MdXM%V?pTk#W?l@Q08~g=%GL{QH zKWu#X--(j}jUK5;yFK(ctycYg1=g8TpPi@nS)}2cx6S%fLkr zORO~>6gtm&)a1|IxJQzErQ&6-wj&L5_ z&af&gnrI&^kY~1tQxoWD`t)G(YsN~0SAmMF4W>6Y8SZTFZ<6DF>~L=W3zg@_cXb zVTSfXKPNvu)<|jYoqHuGPErwJcRjYS-d$o&gbk06V@3q$L4m$qMhr)iob@#MT7oKi zZYMgQ`uIb-f~`fNCHB)#&Of}N57Jav6q=iV`rrPM!56^6 z{(+Z~fuE6Sg@Mz8V+|%=KYDKT`0z8bbl9-4FF5?cZlRwrbJ9L%g+l>GOS57G4)IS3 zZ%$wqxbVwHq556pB&P=)9+Eo)7##$}TNw=gu`vige)Q;Rq0_dN1_nPQ>i8L%I4l0~ zJ2KQQZ!#4XZ3TcErsiko zdMtODO0^_Z**<-!@OFc+TYkk8u}{HLEY9yOIr}^nlxI}#5b80R6ZTL-dddZHKk3FR z?Hi(;J?A;yv*UHJWK0S(=4MQiXEWHs&ZHHj@J2`Y$O5r$MhTtbc?MD{ZaEpEe7ekP zo&7zBf*&5(`&cpgMv9|CjH#*R$JNIk1wH4U#Ldbl$b8G;RE`g)_ktrScA6WuEa-Xl zV1|cBR*0r!rl7!v>@y3aI~(4ldB}5Rr1&x!E_mUU)f2}3$f3r-%;zE9?Xs6Ehwfx18W?UZ5pax?p>ocQ?C4_Cs6N6DzzOpYl1BDzIN; zZd*24aL22;Dl3mNhc`dC$)PNC;dpbv3LWFuI>NGS=U+-3kY+V~(WKtmWU%+arfM0< z9e-pKHPUwSitO2AC?k4t^`V8K4awb?j4tzWUQsJhk#TEdRpwNy%#w)Gs4(L{c#? zPmbf^Nb+y^^fZ0yoew=i-Y$;3RgE{jFCI*%Dr|$69*xRhx5gsvlFSMkft(zA%xkRO z*4f=YaiI8Kg2FCS9X7+2o8Ig)S`zU2tU@kpbHl-h7K{cVmy_9dC^28rLj73q@yt5i*~2DjbOtg1zwIjssf*s=hP&; zGcjY?&>_YbptQ8<=}FHP$BGj_<}P-e$;y3+TfmI*LgB>d#(=GQh8*X6`H8DL;m#t3m+!WO$gCrxlkgKJXx_I!hk1o!VeE2H9a2Hht}uYB#mA)i!>&z`MDt@ zoo|n%2m76$zy@j9gLHb*lm6&KG^$TWl`dUty2~zoUv&ak=dy*i|by2t&z|) zw_Ot+nI3xHyJX(O2MS>h9}6lr#=c)PIjh7_;N-lIU%Z{KO`TJlkfK|W!ttucob<&vfYChfaYt%6bur4}K(c)yY)M`N1y7`9s&*LFJMf zUrZcN>EjAchds;+EiqiIUdJEQKi+tGPt2O1pVtLD7j#}=WH`RY{;}i4CJvc+c7}y- zK61D0=kH%VuYc;}2h5KTD)2NUO^#z&z}Ika(o)9>c@Ag)f1Wz8qTb<#gg^|Bz|~a@ z6B2*?*uMm{x@%r_ze9=;N0R@+zDoi2f5SZE0-4*McRh#_V zfJ-#wp+$yl#ShMf7j*oL#oL>EoIPVymfpC0{E~O5>fuM1%3IoMX7u#1&)4hbikme} z(nZ})&5JW+>!#Lr$hteD~hO;Nw{Kc4~9tOxU&sgZHJ;#OlO$rxRw3-^b;qF5R z9<+BcnpkiJxl1!S`FGu!%zALb#l^+yjtY|=Y!K+RJ<{-ymsRlxt8(fow^|>+IV}>W zFESrwXJBDroLImjt9g#+R6`0QzfB0^#|0T2{T20&2M&K!P?Tq5xSAm2!O!^5f}Q^k zKjUA1y9bHCmb%_AVAte1C=lWDAVuSW54ZCHh9%;yjfnyW)mx9UwQDM<_e(L)``*S- z^(7;One}NKuP{&JGd2Ns6_bfv2$8aE5(PrFf|rQM* z7r2;KM8w=qDmb8E@7XBOUM2TC18Ef#o|H-F4pX!NjQ<$E8oDSYns z3<{h-_QtPlI8(LDVCI7fEbRAwO*c?XNb68Ox|sc9+wqS)3_5Hr`+t1da=_qkO#kBl za{9mLaJq6-ACh3$U{QT&;nl*0AC71oc5gnAcyPv@-=`d6jy`u+c+8_K#ml!yBEX5u zdd9H|)`bCl5=|Fx$=h)|8$95*kCwEYB0g1^=eEs3zMu^e;@Do$x=a0xQt zZ73Gz>Nwc&Wfp%EyW`|zP9JuNe7RIuwsE~Yk2C8$9n}loHU=AJyx^DMRe2c5^CL!# z`9XsyOFJ9u!6WBwc-u;X_zYxOi;NE@q*yh5VQW7;!;f>p{(=WWMuIFCVkYsVC>LB3 zv5@h<%knU|>)4B+@9m6!m5(;AljLHoQm-&zb*$oMT*>miMQQ4R7ugweS|yGAN)84t z5Hl#ABf`SE*kQ%$1Hr6}7o9sAHq7H_X&Imhm3d}tiAah`rmLgBS z+kp=nAu}#&~>=!0fIqx-IXe&hk7?w>)onSS{lBJV}lNGdK@C z>1S;)nE8}p^IX;yJ51FzR2yDtm@!XK?{He)+@M+fLu4Y8zDv<NxY!!G`VDxx#Z=+7%z)`!GY`e5Jsyt6m)!6lRIqHmOPo%+OJKvE@_K z&xcLT0)j~{?^qh5ma{P&?rPd7R4_xS;D#ovvtz@Z9y>+`-IAA|4tq`cwo{CSlV4OK z?oh&>iu2;9i(JpoyE#oo`0{}c4TmTmHqV0!NiGKk_!AB+>^Y%pVbDB{M^0fH4@dfZ zWzw55aO{r;$Kiw(4+Em=6k0nHCt7+=pDL`( z`ckrQX5|8vgjte3ImSY4e3iU+Bzv4(T2Ay_?mOe|Kf6GKPi8`ZAdA77m8@Qu6ArR6 zDk{kM`qgaY6J@HHAtA+KJ$Vu@XX8;x)*~G{DH%Ek4t#Opeo-SPE>xlKdXjHthM25S zTY|1ZjUM}90gh!a1@#$=axC;6P3Gk2i3Dsh-XSB{dZ5smi`&pZp?61&kQZyuN5fy- z3nx706XELSX*= z2NfJmzAH`g)KL*%&#r1Kwe#QyPPQ73#?tQw9#&QkHau+y#2c&ceR?3yyf5(L(o&v7 z9*hq%1TDmTC4?sI*mT2(`?_3J9Z%eYCO+;Rc1^E7e2MuW^H9WLLPN9pWP=SEf}$$o zeMvGI2cjKypEpF92bu<+mlyv({rY+i*Od3O%*^=tW@wbmeZzBO zlIpZFrUjwDZWyx7wo+9zP-nSSc(7r?!9c+~39P5&ECf`(x4IrJ(f5#8X)Lk2t%|>?#Yc7%rwcU#py6D2dA0q-Zc5+dOHWfVdRX zmmd|(&I;GKoeZ*Bc^EStHP3S^3%+1fJ@CV?Wr2loow(|PLwak#_Dd4L<++?NXP^{0-S|!iDVpEf%;YW!ursjhc z{AQf{y4JE@NU5;kT;S$o%GA!Q7PA5n|*Q<%~=?#IdU7*s(i2+KVPUC|&Syrh$>f0$;|4 z3x)5i6c4#EEMpCQ_(Cp0j<0x5)DZEehZ3X;6r1mg9A6~AAx1o5MZgMf_ofZyuIl`398N0B>nhAej0z7N zS8RUJ!sVQ&%D(gA0uin~KQtvI+;*INR;b0jeea8=W=0ln&=R`KhZa~=I9PR`Y@ARq zy(!b6$48Izz$59V;~WS51n)_9I<7Xdea`WsqG)M^wg{I?`h3QKjYdVn3o||hvvEnU zU|rZy#*x+GSbT1e8b{q+mWw<$D)fub@ibO(J5%|fDF zGJMKW%!krvN^xrV2(hs9$?1q3D`ffXu$8^pb??E<2|7v3XGyVMPUCOvUue+e#Bq-0 z(c+{6sTzkb8)W+!8{TntupCh}aVYNR=55-LmnJBy@l|T?!GaY6B3#W4Yvese=JdMU zt?sv}F*qje<;F1Q_YroXrFKl~CUN_9b2sLFNhw?3&b*-0_4p-juEygfPLeDOH#BqK z^AchfnIqAm#2eSeCd)WsM{C)<3>o270y``PSsy%;`4C{B!FXUs;u1!q*hU@|z3PJv z78*36_~-_q#$rmfWPtn`ZH`FEJXIy zs2u$NKV|XJsDjUH3-Xv6+-wi~=5oyAa^RETK0b}HzxR9FxYFo7?r zNbJKk4$TLJ)AvX)w{bX!N;JeJq;P16H)cez1pkTn!^^h#k*ntMhD)V}kI%A+m9TF- z@?bhgg}7v4!9aW z!|L31k5^4W)??m>0L6qkhBJyClIMkUC(Ltsz9AuCg5#m&2LS~~bj^gD4`zznh$kkb zR;V#ETw$27B2C)zvBRl3As-8(ymVML#O|n2U1~p_W6r~i3NLgS-5L)(=G!B}?x+zf zVl_vW(ZZ1N(e~!do~;Q!eLjMFG*l`#$doK*>t{`FbZ8M`WAMom?B&r=G2k=eZ*DO# zt#*275F%nbA+mY0z+_=nD@h(MmM2dheDYo%C(Xgt{IDQR%Z?*Y#6*bcsZd{%&_auI@0%wF42zo-#2F{| z9}v4ATJ3D!khJNeu5XBHal^3(Y4Qh37%wE=Z)tjSiB-1!V9SD3nX9G#Clh{L_Y258UL0TKo-|8WlS{nOc^-Qv#i~(=ErN@Ik3>ZWn5LXyo^x&a6cB%)Sc^o<*s<8HzT!xEi-+>bu3!21t$rT#5E|i+j>!H~6k14tF!-hXB z3liiwT2$N4A3WT3ScNb6BqL*&r!zry(WM_u!FZV5LgK6t7j{Hi{DA zCSuw=na>#OJ_S2Wd3-SQco$=Vm%ojWBolM<1PL=0&O;n0WKK5*9AV1gXmiaeIN}$< z!l6`=qj}GqN8^qvN0T{gLPtgnQ{#sTH}u&SXy^)aShDu)$ukn1&~qs8#NNlBk_0Wh zy{-KXS-f0z;~RK%;9O6w|qM%M3s>h7RW^L~#p!-t2h zi=MLx2nfDyH@XoexkEVoPC?p(Cf4K~4}=spYAkqpp@Y5QzyvqeM;?s@j?);G4ipPo zekx{hb~yOd<%P>PhaMH?DHFu{17=Q;dgPF?K;pE6n&pF6MT`~P2iXz=9{e%75Zkci zVfH<_t`EYpOz9o1CT=Vab5c`_IKarD7qP$Tk&Hal&s41;RA2eQANI{ z2PTX~7Aac79107>8>Ac6JbHg2kS%Yf;pFxF4jY;ue&1_5DY@CWkH5i_!=XBKegXS*alWn3 zj~vhyVN)&Gq9hw5>-b#d|1Qx97S@bOHo_<4Cl^3$K1x3dhq1+4i)}{ zq@9O-MgPAl3dykL9)(u;J+KYAH`7EYixrBc~oShsW!wx-m3xfdTrbVqT z4G$M@<#Bd&SpW6=#mzp94Be~^T?$cLObX%xwIBa4oG?#9jG_E$|3MGC@IV{M0C|RQ zF0BbpO{Wy4YCfnlig1d3+?je|4WAcJ`ivauh8?FWLq2N!KYA{_?x_beBj=XN$gI4b{UGfv@YOukPx1Y#Y8N0M9i!!^-1MU|WQq(70xO&0cs`R01 zb;Eo4icRO9PvDL7bjyAIaf82w$>Pc9D|%FQ4(us3SKz*P=2+tkzLo`#84X0aSQc2Q zvGWOcu{U`NGP$@_xd}2nXLMdvv3PQ4<1y!iHkJty&25hrVxo*#yH7SMUhHK&D=5OJ zFUqE2pdiHbp+vWDy$CaBb0W`Xk-yUh+ zT(LmjMOlhG>@JyC#2Y_wvdc)b3b;u$9ek+KEYkXpv*BW#Ld(Mo;{2>H9rhGes7S6b z$TC(HWc8PAyK(&PfsIdFzG%y`CNrMk)<#=~2%f(x@b~b; zKirH0oW8%kbsy_Vy2qiHr}niLW|k&C`C$_Ev?&9)$yTUmbZ9{r|m|lRwqfpcs~ZN9DrF z2$njZiWDEBup;-QK{vCTE2T5j;ukY2X z4;|qDA{bNB#m(XOOwPw7K{a869;ZTq;JV7ljjQkQb_D#<=AOrMVB^`&BhMQjh^+4H zxy#vdII)k_*HM3Y|75|2MNSJ`eoyVJxUuDX)7i(5Cau^a$x3WTuNp>TyVsRGgisQCrz7W!wT-51{OE! zxOrIDi`ob>dM#LD!Oh>{7~^Kc^x+rlfedbzK*s!w;DoDHD+g#3xFmN&2SnxJh$Tv7~J18IhC;3YzYoSvTOa=6aATA2WVp|fkfQy=hW+P*rZsh|PDf4YelU$k zg;~7+v15kf>Q%gr?;SY#pK>uDaM=7}X{?t7GpCaSEAs(|MXGut%`6J(p!0$i#N-bi zIP_8b$E^q>Hla}F2ldYwCwTkKIJBPsVBX^ArU(D9E@iV&4d9ZWw?KfW@ZcZzqah2+ z`KM|f`Y+i3X1Rk+P3+Q#)1Mrl&&FUN(s=RZ#efSxSRIVs?~w0|n6gTPVUm5n`PDBm z9|GjEk4+A4h&ta_Op%i~DcP`OoRJyuU@4@xTVw4{8A&37kP}8${=8 zT(CT>%PuyV#X(i0+$aJ1`b>-jtv$QF8+xSlNJ84 zs^M3SwZQ#FxyyCWur5A+l*2)6jzrd6U5UjhD}>zKUhqj-NU~`)Pn`QhZ8oD=Z-zzN z<>MSW9yx;C2C@rG9#nJv`rq8!dX({Scyk*=i;Bs|io|sm{Ng*R=8G*Z5rzKm2}h zobiJKzm;^u9^w01;(Q;BzOVe6$NwOXy`ie$hYbry!l_@3RaR^~jSmz&IZVAa%<&M4 zi{p9lkNJTIKO@u5f*0Zr9|UAqu~pcxaGM_ZAfWzBoppl2&jV5)|FBFvutS6QF4xT$ zE&{fW`R2?THOBmpLYv#1A{U(Nv=88US~ka`-hf4@&i;4Hh8BV2X$L>le-Bvcv}F15 zSNA78P-L{Rd*b||#AJWs54#?ly49yrmvk(-kRfw?uV5=v!y=}mTuuQI><2v(Y$Rn^ z1e0P;s)#Tj(wrk>SP{tdOueFoJ7H@KABz%mkA)LEk3{+$=@(0kIT{7n=1gq*koDmJ zH-{K2tM++c=C+Cgb{kD5#lz~{2X38{c-M4C#;~F#I`W=O6T2+y<0b(ei3e4(2MTX- ze>`}-LscQXN`c#u{)p`nA_Zk^i)4?YRb!wORtp6oo`xQ_LSk(1gZ zqx>R2rw8)fiyF3s2z5!j`f)Y$FgI54F|arEMTySm;`yN_!@aO!p+@l!Mu!f^@bCVs z-6|xQ+?yX>YZHE7QP0dE{`lDb_l2hpd|T8uxIW+ z+&H72hucX;=N_x1pC1X8}=Uxr&cwjHy@}wrOM0(T4mMW?$6%v&&7+4VMC&hM_2_j`-dMUGA9)u zCH^_MU=u&%pBK|qgqfK*oY@aF_{cGTFZ#}Wpx!DjMx>cV=&Sny!+P1*Z3yIPc;4jTyyA)_ z^E=k&Lz+EIcO)2>vc42%O_VTWU%O#Jq+^*JV>xRBx4KA^gm%k%*G-=j1-#68;@o_k zr1r>oXRL7GiaXJGqFJu=ph08Pg*TVHECTq}nK2eDh~qhVd6uHWJ~1Z2MRy7e*GXLT zT-fxck9C9SnMtdoP9(7CH5@Fs-1ETHqT;~C11lm*K3)h^Ffyr#4MW#F$a?;t;FbVYx4xnosa9h*1=6^OtsZpzI!p^BLz^#X@^!{*S};DyzTvmz<|#&ne~cEEvor7i*)jY7H!0Z}7^ffFkgr{|ewBuB zb47izTT}QsW*hrP6A!t96DI5BwOiet7+9DsjQJOo?1)nOr~bf)hcPb1VCsQetPkWW z-GVP~WE7qU%xN zsV~%^AjkZ(=tIH@Ip*INe;B0jtl1-BB&3ig?qJ2>@Z^Bk^X3^}nF{zSFSKaLSvEOr zh-505apHHk;)^|Yx}Tw z$z?cKs0nPJu)SH)z(=xa(nsT#rHSdqCm9o-b6u$t6|zuK6JZMM$?^H{K)@-m@XwP+ zH+1cuH+wTaN;gvJTgf)(hm0!24$-Cylb0^KP!Y{|MnHj!?ZFmahaX$A9+arEALV0d zp2w~9!1usDQ8p(DEtU|c$J~6}?Vw7z;jwA@VUZbfVFA*PDk=pvAv44nO#G&|IM`{h z9+LBOQV*NP#l-H&RIbZA0D?!lG(mDigbHk?RHNKBX^aN)R(2AdSq z8!aX`HI7N#0rd<%45y8nUafod=tBkn8^=8y0=se(68IVaX_zoPmCR0I_#l7sU%w)Q z!5=TZfD(`JzZRknQy3mTNtt~_{ZIpc1IK63RTypuSeWHm85i&_J$`T>`xF-a)ykC@ z|1kbAGiW&EVemKNO>5BBf)6(Qf6Bd2ICi)H=4;MBp3i)&{ey==Vv{V-zqmEYuRbdM zwKVyW-pBu7jaP-!=hGWZj5y@i^Xz;0hre--YV+r%7bG4`pQ-<{!C}Ar>Whz7x!IaY z&Oac)l!$G!>o(eWBTnUE)Y}mgiNC-GCn4r3nIr*vAg`WrR2{E>8;1P1TFm0vU z4t^G)_s{BN{~uXe?C$Tv%`bnfpo0JXIcCn(2geRRus_Z4fKSLtD#MST@sEZBdqcw+ zkLIljKjQy3aTYC25K{>)Fk(?~_}n*a&hIRdj!RNtGB-2BjBPZ;;5$!B|7_dH&5bjmcBZm ze>L7QY0Vw|kBXlU{$X_vt$*BLx&KR79kUEu7>__>BSRgJYKzcQ=cngZe=ODCd~y4# zt5P5SG5_yA$Wl?D(8EwE5{#+D%D>r zrq}2RximdZiuk8hSTH@Yuz;oc2lE1xKo#ayn;zsPB=IvcaTrXCVf@FzkWr?__G5xd z#}Nn6c5$PJ8lIu)PsIPRC^&yR#gokb_>>?2gM|w|2>3S?{HWs+aDF3n^H{Kr925J7 z{Qi9$N={Axt{roI$Ro$ZV#@k8;`gmnMGE}vjSbrmpIc?cAs z4^$|u3hkZDf2A|N;-8HTfAax{X^agYE~7(-*S&|Qc%2m;7zLP)DRO9do@nI>*x1B$VFf>* zIE%vre#c{shP`YJ=?MliHcYURb>&~QNHXq21dCsV#}NUK1tOfv*Gvn7+=chF?p5mO z2;^y0;*?NlnqYM)yxCw%uNOn`k%XuVyP4bc_>YJj;9K}QWsmTVLt+O@KAo9kT%p0$ z@Q905j>FNj;*Dibf>esI9IuL7r2iAyiF@ALa!rsTrdyljEV7H4fQ~8|)KFJ3^B!n2APio3g zcf2I+)}pq{n^Xj)3ii1#C;C_Dp3~ljA-n z=vSl8bBEuF$FlIg-NOY@k7Oz`SdI%Y6&WnxXyI?UaIx_FG&l9`dmIg~f|!yfWF#be zXfhw3_aMNfAVHCXo2lp1j;?N&_Z14wi{f|~tPRp^7_KxdV4ffIaYIIq3a8WY`2n^J zAJjz;Is{0tI~=H~<5GILAVOaM|Ay3X>tAeje5~5XvjpcXZ~PeZ1ToW z4jf~AU|$)cT5a*6fuc@93XpUIIFV#CkKBr$>K!@q+M?2|bhS}tv9S+T!(YS;|+ zhTlEXSC|*#iSq*d2qK-aamzP+-k1(5f=S!{YRz7Yp4b8P6*z z+KNnaNr=&7Z}w%plJFtGW1qnN z<0IMbVD?U^o44^WoBodr2V|N89&mQ`C|RvD&^XMrCA{a5M6q=Bp@QJ9IUfRS)0-DQ zW4heK*YseY>6eeT6)6uJOf>kJzb`rPpq`P1eSX(L$JQqbM<4PCWc+hp(7?m^^zr#s z@=gX09P-Tna%NTR;cIY}D`0Z}*v#Z0{eA5OU7;0DY`3h-%7mJO9zAokDXFiksArhK zufcra0yE>n@~H~qRa(cJIT;z4LymLSh1kCQ>im*Nn_X}vEl6NH0yXhN4gaM<2Qb8>%$LY=+?hXm7BsCfvCKeymn9NYz&n9EY-@lZ{ z!*h=!(;^#L4$UoxK1k`ya?Y@bG+ALFCe(4{y_JSK>yZZ?Jch>^JnlSdkYRn?6mU+r z;0iy7#AA~cC*!0KwY6+^XHZat5ML)3bc^{E z2V>gDgV}tXQ!=KqKG?EDxKZ~Z$M>1cj2EOH+%X6cuF{d%6U074>cC@uDaMY=NfReV z=1H?LF8FA%MoH4;sF;CY<%b+WSC-eaojop!JaO)@l2Mhi(c-euIpi>do6F;4z>efe z%{w&tkDFV~I-$>)%hjrH=4R%`teT@)k)g=nR1pyq*AP(AzMw;6(ZLQSiFRq7B7KL` znP}rJASDs{VeDRO*hG^3R zj}rc|HYlu+U|QkKmKoi$@dK-Pi=am7rvUp0 z$us@>AF#7D8Hh7i?DcJLFi>D-bN&$E-dPvgAl}DjHGz%sLkMFLQ+D$T(VnNANBL|N z8CjU8x^G~*Sm2>0ci{GigaV0#KkBTVT(XZ0RwQJ!NPzBrZ*iIuBE?wTx>vwy!2)r{ zV{VUwBHXwxrSC~F?UFsPphH52eMjPiB{NLltN2{f4X72k!!Gk+-X0mBhZhpJJ~*er zZez#D8n!eihV#9i5VvCz=R$>tPad62J*W{=_{dS5yNl`L!dC@bR2cm;TATQV6j>JR zLl(NlM=nRmZ4f$G^!Y$R zjGtzsz>X+RUROtfyV<&8J#32#-h8mtRpp6!R=i+_iz(y54X-p8yQnVbXHIzJrO>kQ z!ht$Ptp~H@dmWQ_%q7|qE!h|*6t?%YZ)~is@Zf3W%n@gHRLGWfD6o>-{NUlrLz^8Q zRq0n$h&mhi=_;}{=1Vir;j`dv4&jsLKB%jpB+w*aaJ}>3?UshU6&@UXtO>jcI^vv+ z2bZ%rE{?d*TH(XvaAAR8VPlW*X)j4GIaxOC1uGtyayET@$GM27;PJr;y375T1mvq{ zr76Vl{}AuDXWZEIYi=M<>v}~-gRc)GxLX$OWxSDNzfel`s+H4<+BZDcZS4C3cuJTY zzpym~FTeV7<%cshjOvVkJe%)7(Bb~G-f7|Ydp7Mxa~~df#;Wk*T{p8iTZ517dG3Y> zD;tBGU%Cl)yilG0C$^X`VTMEkD}%!eE;hS1&&#rG2c!?xvYG8j(sNxRXfC0c(em&F zH=khB&nF9;o4!8R&?{+uHJy1yYdceb*^CSN^Ei%F@!5S+DE!i6CepItxZlhz5B8`R zUQju=XG*MXqeqP!Uj={V0vG0kF+n~82cK7WF+BHhIplI7#Y=jvQRz;U&i2ydavPK)1hPkNA4g&cg?fU+6ihXyB$O&n7y%BVqr7Bm9L2CVu3& zd4TU&y3>M!!n8v-hVaDR+jR%{y%(-a6*=C_$c}eVpkBEVljKYNE zg)s{4zP4u^4>RbT7iX7yu=6;dC}V+D*)yRgC#Ag&6RboV{MectoWJ$&bJ-BR)<(V| zfFrH(`YHRL`j3--d{W3$dHDWB;&WN{j}NX-5xnZ4Qsri|Sn_dIhAJZ1Ajr>eVZd-UCSrl4V;T2p*YrD&!ZZpU z5))@cu|@<(Cvt9Yf4ut~lfedCkv(rjWMocCY`YM%$BIi+(xXhD)7wXUbAgNzn<@`;2g{*b zk1qI%2}$Th_*wB5$7wSrJAIR|R(r^~MS-U&k%6ls!Xn{>c;W|z59~<}+nVk;aXNlY zXHRrG=y3N-k#T_{)9Irha#tjBaxR=}<$tpplT#q;h7kGVT}%dzFF$MPU1?oXq&#uZc86kT5r^K8u1^ z@d<~dj{@A!TIcBUEm-J(UR}^H^T3%2vd#wsdNX#*NwI6J=@IttWm}h!;KMUTl9T(P z9s5(3H9SrRO64|hyBi9v53X3W#gOHAn`7GpH+7E2!;MvsJsJfkilj-fG&SmN(06pW z(%CCuASA(g=+F$EiWb8b<3kO+Hw5QMG!zK1K0egx@2GmbmGA4qjFpxgQL^*2D^#T> zMC@1)F0pwXtDvr^jfzNukG8~Obw7(A0c&1Z9#vM@;3y~7)XZ|=)#@J=uX`8^EqskR zU+CSDWA4+j;1&!l=x_Rb(6A_2{fvoOf`n-MJ-0*d+l|=ym>nXy1U~o}Iy`pNNa9*_ zU8LbeLY%F@0t3#5A70GICLEAsW@>iR;%H=IN^mmOXLV{7X5*A8RXv@McF^F-qMkWC z3{#GCFZjeLBUf|O+@HTyY4NdLer0>lFgkL?@NMH;$;|%YLWfXBMmysVR)zh?s=WQH zpZ|MMuk(Br&%Grq0cSqg&y!-~StC9p;49l~Z2|>slx1BO}Qf$FXEj+IMC>?n{MCitb#3 z2^ym2T^tAdSp377id*}8=SejcBys4+z!G*ILbEIc65c#g-{#Zg0FhL_>AtAHBY z!dDe~_c)GhUNG(9fiGO=EF=X!L^N%f5t4X_CE;-5%m>Y#D<8zQ26}MEb>0*4dtXsx zwWsspj)0BU*{ll3EpVW!_!vW+CQpqZpZCOoXMBCk646WsP8QXdUGhX2vz<;m z9#))UV8ACa@1XNVp0!OMTuelNrO0ulhQF*Z-Jx~N(=mXD$@wh%2U9yq$9FYtJ)yPR z`Q_#K9~dxxJhc0TrI`4`37i2R>Ue4@4Ge$1l4J?UNWNppaDsg^PyTxzg@(v?91UNZ zE;KP4I8=O)G7)eLfA0J0c&FonDaY;_x=1n!EI8egdbBN%RmkZ=oUDb&ylHSPxQMjjU^UnE^P#UhJ)gPYxh8H#)v zULwb&9g6RGWrTfbO095YzVIWHC8kGMW-%WZpBHO~uuO)GrWuDai_HW!-*bLOa^H=c z4bL$?ES|`(u$0g5a|2tG@H4gsuLd{k&KrVFKa^POS4xR%*ET)3ZJfABnpNQ)8?(v3 z3x)4%fBNl^KM=sEu-);l=;XHa0}ArTm*3Z}WiwbAf9rMnzNDQG9oFSowD(4H$v85L z&y-SOdDNiTH9O$|(*v%G+&LMFUXFprY|ToSL!u^Rct~>F{Jyqfhpvm!1{bDv-Ch9# zOmn7ivos%?;K5uV({V$E)1I}Z;e)TPVC#~6CB_L4_NqFv1_;}1kWhTvCDC+4Opr_9 zktR>ZgAAJpHNi=Z8EYRi9yj7VZWPhdG~MQ(=R?g0|l0a z&3Aa!B-9!E5(5ux3Y{l7@1dfAK4X-2^~`o|c0M&8=0>K5Ieh(WPq!55UgYJz_o0im znd#w6&aNP3^@>1t1-=3+0f!vN_G1q_vN)1|X;iMZ`_8H$%gMJ>A%pYOT<*(XU)-8- zAZSHG1t_#na<{lKEN8R)(8k)l_at-CiUKXxg{=)C24@d8vK-i}#GoPm+|9{BxamPb z+UJ&Yj0!6_4wn3S;<$iUTcgjRaDx*YqtK%%E3FT&?2+uRTYTKYufV?Pfs2iPpxYCN zX2z-4dN`9jCfKk_KHzJRH_?+nn%?dpWZ$&lWuN{2`8@l5IUVW`|6Db7%ZpWg3q|GT z+jIwY9z4d!7UdrMyw5^~ae%{gf zY=3lRPU3{eF&6AiXF52Jah^Gtypl~r{GJi#y26I$=FV0{UkXpT;5BOMrm}pk; z3N$TsXKJt)VUlD_zL%YOuKJ)xL5TR?unT^M6PC3q?BGAlAmSy#xSZv}90e7=lbv_C z85$jq2hR7AvDVpOXc4;bW&5OtBd-rSba>?$ctkSVa_Bl5Ol?Y)X>nAQeD5XD^WeCg z5PLzKWQ)NR_Pr_!5v~PS{Frli63)%5NMLPx)R4q@bHN&}dprz12P0W{nDPZYJfvbg z3=Ez`EO2D{`}6^8n3z1zp5@EuWhlgap15ZNN2qcNCr=>jrj$zlmPsFMR{hQRZ};#+ zJrfJ)fFj4KHHr*Ls|1|*ulPRp%Js>q(_0YJLN!k#IZMVDD)e) zJUGVqKp~Kg;oyZY-ukEO4qNDkI@rDVu)Af|!Oa)S)=0eg$KJwN5C)ng2A$S5DK0it zTW{Xi$^Hx(2LB&4sCIm|^Hb$y@-UbZ+x))2;oI5!1u;BJr0;PgZ`APqA@Yx#d#TW? zbr(3p9X@=ov65>3k>!2-Rg;MPJdWi1fnO(a9Gu}GbYyAj8-!7Y_s6<&cg;yB8i_;#4SEex%Z)k`NQ)z2A-)8TKMnyZGJPsLd3U#yTDFt`5lp6 zii`{o@>|^)>x5XfFS=MT7T#l?$ZO)kaw=n?!p0d2O%4m&Pbzq<*mz*cw91wb(o+mT=+zySIZS02?1;nlRE-bmhmhkM5q2*@<>m_|W>^o%@ z^gTEZGdM)#9IMi*J|s|JUdf^NsX1{MGn`4{7xbP7D`Xc-ilNYfA4$A`A0^8nTdg|A-(<8p175L^Vq`p85vh7bTTYp(c(P{IyO$O zp}>ayyTS(nna-@n2mjxO*acmYf8P2)LbaKn`wvHggzBpBhU8CEZ3BM&aR1t`AO7lk zB11i+FsIg*eUF44u1E;5%w_w*-WhEq9-462+TqutPag~t1Q;8v`WYK+y#F;bO>{D_ zd-U^<{Ez+{Ry;=(Gz6F$*(WqQoL?d;@lZ+NO#+9*hU22jelFZk791=%<{+|1SfxkC zM1t{$8zBpvvV?;P`$L!4O z!@`2Ez=PT6b4Rf<<2jBdwuS>9DrTHb3!6mmyQ;KHaWTw1BU0hP*7RY|qyo7w%|~36 z5}a7>ywb>0{9?c~%dt<4qhbL#>xoT-=C5T;Z<0+nwPwPA7 z_RF2;JJZD9eqS!-T^sXzPOb%pje7l8SFoAcH!FTea zIPCu!@dQb7GT*x&GB-z^P0k_k;L3szFKd1tNMKg65n(i%cPS&2jlDzRv)l(4iN-|= zf213>9X?)gAyuTuA?$mfiqpH#TRs>F^fldW@F?zZY-twne10NI$Ld!_A3xW9f1@VH za$feGXO}pAZn-CBaG00jnlBFEeC>icXb9`QcDWBMFzg&8ZH zlX-UO7)b6&2}_DC;OBN^;dC^7B(zeF>$rtX;`@XR>C6f(Ud~1i1u;2-Ee#3Pha^gi z4|RyHUVWM&iu-tTClBlAd5*L1T%4w_&&pR}Z1Zu;F{dbbfi}HL*2d{w+!GXpxRxzS zUSBA{z4^%jBbfXooJR2%f)HnnlhTq}rNI3R=Vx!{TXHAX@XRdHMn#4&iYU6U- zaF|)9K!ru+gc?`p1!0y(*#i@-9^A-2+tc{vlW8-e2)wY;e!Klhx~A%sP&zH&`9C z50vQrc6rM@bgu{6;hAFr8*KhAYF$gbGH&z`ya!tN!{88aEqNONrQ zcAcUogyJ(!$TcA)x~M}f%6*-|#A1TXHK;qmcf zuT)9brE47;EUawY2fXFk4RYU`ab<2erphiO%6f^=e{Ug@GxeJPG^(6^7-J29m#T^1A-Y3tQE1*Wcad|^G>4W z_LcxO<9idlJ@lIyp0liI)nI4%D%Sd_BEY@CiRq%hq&llf23Pl-D(9y66#>c?i*80#mYBliz1`QP#2MW#Zut^rTwdp@-}3pQ8eO1mdI-YsnU*4^k3 zVYMgsx$}dKlGX76U56WctmKdN)>tQG+%%oA=*TWTDVut!DF%uysu7D;2k}hm?O=&eed|bJ1!;23xa%PNm`#(s2xRUs# z-KomyL4w`N`Kvg7>xcZ-5dW|(r}lXJrx?a5ikuDyY9xL18rna8`26(eRk_{VCD~u) zSgjT)Kg`<6y~3dT+4NA?pYv0U_J&3($RC;^n3HhS)vfuT?kgUa#t#bo@=YB)%tsyM zRGGQ63@2yvoPQu5*41l&Akky;s@3(26?LQ=QqsQ5A4sUOjX!nK`c){?>|b+?{vThY z@kf#8qiaqbqjRw1AMV9FKk|Q&Gh*1@BF~&E_=utA2h)K!$(NcH+0XueqbR;QJ!y&8 z!Pdn)=008&{6i@9-$hNQnJZdd|I4pr7T~bh;mwiAQpaRBQ7k4h5@D-^`VH>ti# zeiSv=Aoi=v!ap3x+5R7Fk}%cZ%aQfFrzPuQ?fv@4`(J0gKDfe$hgCt|=zgGqv6#5_ z+;;A(jX$S9|NB(Zv7h~eiGlQ~-OgNgf;U(;Br3)2zOW$jsUOe52Yk~Oxb;bz6eO{p z56_wU@JD+4ouYY_Dhvx>J~$J{7G)(Vf9d@}p@|Ize-xV) zwEpF%TMKTe$(aO58^W5Ham1y{7p{w~(KdAZ&Bp}u6V(}6DEgWZQ8 zcs-BvD==gG;8$|u7&lAjx@^*-K|+`O#$*NhwM zJ=KgazkL}IPqe31u0fm zZrRWK+l>+)Zn~6iU+Lp~y!V$klK?zF%v zCrkds*){K1%6Bv!T(#9AE8eQXqh6z6DtC8FU(VD5PNBaa+IYAe+Na3L|F3Uz{*9DG+MAu$icuvsJ;23PThk4?+Qv{cp4jZlt_bXoE zOCh&h0@RmsTEwN z$*;OyAF>FvA2_5xm6?%)M>mY4&Mz}UaXMr3N2l_y2K?+FG9R33Y;<6}&n9??VM=F+ z*m?fO?x`k>^Vpc=IGQ*#+)uMP^6)pa1&OnTdVYK&&%@%%CO^F)!|8{O3R6Yr(J%WC z{Mf*<=i?D0d%rzmk`{YT-2ZsIaY=2NTYHQIqvnB@FrLE?&NQ@LmQjAVRqK?frd{$)>xR)=TeE#(z#TCCoWgC6@XDG8vwy)&)!EdnQS9MdxqUADz-3!j% zX4-c0NP*6!!sLTFo!brsZaDEZoue&Znk{(!QZ+u-#Kp|{e7sFjJ3sGsc{pQ*alr#c zmdgh$%mn?Nk_0*0cJGbo2{AlxRU^m|pwF1l#@xp5V%E~EwvxGX&O;A*1(kwA<3^6= zJDkfFOg(a-V}baRHs#|1PYO3y8sC-U%ej2ic~-td;DamLf(_s239VS{&E8ZHcQC`I z(~)sk?(+jP*2tU`Jo`ZR;DZS zkNc2{?(FIr3*H19M-*=6=VRZ-x8!Wog()+Q4_ZgBsi*w+GEm@SP>KME&v{rn%hnX1g+V1Z0HC^YJ$s8U_6M(Bx#q(J(XL zjyLqwbq|jZacpP%WNH`_z6bA({5eH+(UG{%3>Lhi8w$8RRGA)BupivWDk~vkHf_qT zrWZTdo2*2QbQ%Q$^7%S)97TG+1T!gY;MIDY$Wi1|t5IMjkm$BpVVB#d2a0>&t1?O7 zQ)Cekj;oSr^|&OLbNkSQY`G5)ir9|3aWt72EtoVR!Dh0AK+g^rITNeoqe*Uie$_m_ zA;6gQ@{!Ym6KW3LdOz#CXIgx;+1`4Hv3r5RBmr~w4OuG#rmfiHwn4f1exT^J!zb20 zY!K;@o-D!0{lX_m*y4kebd~eQ2m8vGGF4SX21)ibWFNk<<8;G>(t|T%K4miu$Y7uJ zc=3ZqUFFtg$8KLeIq$;`E$Jc!)QcdU_@tirVBLBK<^}?^(i*rcC2|LM@ZN8;FQW_)2{bWJ!3$5#fDFY|PX|`^yJ8B)r*#GJb`+AAF$D&nDko<015A4m0CE)s=TDCJ9VUljnb+&3=e!Lrcv4 zJr6a!!q&QJfqM1kKMW?VZD(dtXyN@}EF-W~Pfefw(Em5~Q!elc?GgCHcG$Esaih)- z#lSzzZH-MbY$5U74KF&fpB}v>nUOX@raK{Rx`9ILy+gPBR|Hh^xJWpKX*e0S*`CW{ zOK*DZ%)rl4<@`p`^PxoQdohL$Tibl+2GrOU=uMbh6#UQUNEaZFgN z@Y%`naIdP9kd2db1}}T-qK#2|HFTO-CtoqU(_zA?(SB_*t~FuIs5 z)TLC?HbsKNs8{Hapsk|9)tv%+SF}1lK%?U>j$THYSC^Yd1wcp}de5E{MKJhKX9tM{ePfOglbe-e~1kG$987Uc%iBMEk%zX z9FVd5wKVHW;AO^_3o7{E9I%l-6vBR_K}H~SIw$k1C6!nD_6vy!GxHtnaQ-2B;NXKq z4LRmNffqj1Z)kte{55<-Pt^+PyGH{uRK+{J_N|Qg^xPBPP3l$h9=giH@iVRblsN1%m$ zjs(j+k;50h?@;7TzT_puHKpmclYgCQYbQVN9t|RWJ^Cd6u`O zaiMmrz(!xG=WRlV^D3IYw_KLsK2`hBp;^v?W$nx5njaEu^Ig|!Fcwv$s=l}QkjkpI zZ(fCqLi-|FFMTgdAzs&o587f)Jxt#&ZYygF)p08MVPL%CL({#vN-+}`?DS&H)Nu;* zmJsOIeaUsguyKOJ_dQ!#=6QXXz}{bE@GInlyN-sQ{&G>Zah@HHUcr%lL zlm6lj98FQXA3K1?b(1{)JNCA)%7rM&%m2E+slvX~|6rqofSs}&hf{=M!BiJ_<^vAX z1RD3nt!kFmXVYW2sNs3=!a znd}f@*k5JZy1=V_?~?^aBHw2)O;{^3Yr<8gw(CDsw zKB1i1p~WKL(7{l{=Ae~Po?%OLi=3t{ZB?#npU~XSkonE>&_a!@xDOMY_xr0&DcQ)% z6Ts8^a7IB&s=J4Er{pER|K4s(nVAGcn3lIP=x;pEu(^1$oItn8w_9=34V(=1LU$|^ zQgn|vQOC5QM)=<50|vbReZrpdA60UBeAULDL)Iq4_;a&C!U_Av7_kE;OpPDxuQObA z>@aXFe89#2KTiELs(pwC(c`31-({F+Pk9_l1tTt!n@MKvrk*{Y6ra zKbIy>sOM#vP{Z4L^m0bj8ZU-R55M1PxhKDzlcgh8S4A)Tx!uhT|18XSA8OR-3LRps z+ApBNR`4~dv3E|%a`z1jEE$$C*;f@9)jwP_5Io4QtFl(NS zoYJ(bNkDAElZBnE-#0`pm?O?~sYltr;(_zT#fujDt9?{MRbG0)CHk7e; zFelhu@MA1xWNNzHyk3aEV(Oj?ZQKXq)HW=T5#wrO^5o%qQF`Rbf)2eWJ9C*?8kX+S z;murFkf8gwZA#sQ1;ug`-IyHPY)U-kB2>3`8pn4xC`(bZI}h`NhUZiHjd*-@C!jl6=(ik-&y;A31C$AI@)4 z^r>($Y%!U1W!8cY{)G=;Naxq^c&#bry!YXN*FE`eW}(e|!44G;LM?m47Mxn%e?X5X zTEAJfs-kYeiEnIqybU#;^@lCi+$ji==&yeu5W|@Ghat5_lL}AH{#% z*47}$BXGsN`GCVL4n_WH?$a6SKTbLrwed^K!9NB3-R=L^{A*rtL}1ax3Iit=t2M?y zCS)JI9>1*lXUqLn4=yMMYGrCD{9nSz;-weF^YKpzPZ_@-vjeL`d;MXPh6OyF(khJ8 zJ_+c}n=CU)WWu(N8ZJixC%Fk{HM6-~n-$KUU9yvN#)O}Y5~7CBn*^8JC^pu8*Hk{3 zu~o`@hKX>%a?9w10t=4ddlT{|#J4yscyRZj0AHu5Ve2FozEZ^r!CWnd@41*8BOf%~ zIXG+D#L{g4hyuBf5ovsE=Ncjogh;#EP1vY;sG*QQL$>i%Sj%jVR@0ZcA!mk` z(o@qrD-;8$8@QQPXnf$C$KT$d!6?|s>JFhfsPgu9iU ztNP-h##17yYHdu{o*m=wzV9c)9#~<)5q_{QxT*1l)c1Bqk6H^JhNBNo@NWpyR$<(D zA$Eh_MMX|0p%xitH>Txm0*%#8S8NqS+O+3Qe#s#r&{*K`(Sb{4N%2K)2~LK%;zK(h zvn*6U<)D4)z~$53XW0_|F+0dIcE7A&e)8Z0`-SWc4PPXq7Cqn%y%U`H@nik>7{-Gf zbppo^`ERcDZ!vnP>sVv6`qlRH{D}{u|NfdO_n?A<_uvBsXBNR9rfhn8`eCcK&aPNK zd3o)tWek32EIRZU6;&B48!80&7lcSE78*7rugd(quz_u1$Ol*E^VJ6hChUDMflJ>r z$15O#ox8$7@8^TWuKna$|taBZK7XMh-5X0!79^ zJ{R$O9l8cWoU!VBY(3S785VRtR=6^=`VLQ%K%3>3DNG*))mslP*yf|H;wJCOqN?wq z%d|+Fe~I|P+`}!+BAPA-yp@>T9vWmkwS3RX=u@G>oqd$qgFjeFTcW>f4V&n?n$D^T zaZ?lo8580pX9mpsK1IOz%*w7K@3~brzOQs~sJMNYxl%=-dG8|*GoE?TmmCiXsLP2d z9^~Lo*{QJ4Mv*zYDj>mwU6_A~!Iq6o9Lm1@IROa@A{uv3HoXeqHEUk^uKv93;|&*L zO&MnvOk(I4SJnRQSa_K_^1;{@z4{vxuW}sw0*ww@J4_fe+M7NYO`6CMHdP`c@kINJrawk9 z#dkV%+YTvuSP62Pyo%ZoV<1&|t42?C|MO$VdpQJazA{Yc;Ewt*fp_UafeSzQIa;PY zY0>cT^w6KSq}@^ANt~*x#Du>J`!g6XaWN)Eh;S(Ta*BK`@hDJ`Vt$=?;Ay*_NmWU* zAnQlAwt3$aP6-;=EnMK`TyEj0*1o6d*at_o4+(5DK03&*I2i2c(R9X%Wtqz!C);Ox zA3AKfu~JY;=)uN`+ZTx&ind)$h??NcCb+WkW)PcpKMzBXIKu(%b1oH$jS~ze7%_A7 z^Y%A5@+L?&+soDMP-OVP)~-5DMxo`sKtsC__nRuGb|!^wHY!Z4;Tyb8G9`T3`(TsU z81Eh>57Vh(`-J84!Z;oPS3Bb=G<9Yn&L+pY8x-yvEk&r zk};h!>dWe~b#+KIQD&`xEJ#3ctaP{Qy^)PH~7I@P1SHbxu>l4=FmJ1%deYDj{ zhfP^Z%wWlr1RV>BuF8iE$80pja%?07eov9%ZC!Zb0#9?|>{H5#voDD%DmJdRJaAr)pCLow@tXk2hS)#XnL2DZ^X+&Te#IPgT*UpJLxIoX z*aIh~OY=Bf3{Ny&KH)OYNvM*8Tl$ECzDjhQhu~fjjTMg;KN9-*ebG_XjDVevS5&sF z2&#%Y=rZ9!rYcL1aPH&9nO?f6o_xx}eiM1LW}fgoNcr|A=pS5K05@|kLG(Z2Jg#4(wc=7b#wn^rdN z$PqbEVs}DY=#bwO(NejdR;CUwmJ>TZMDS%kh_Y1DR1~;ko3X}2!s{YK)~tfKW0Sfa zLW*<+xLD?B^DsQ(?OWM&O*>zR^nB3tj<`UPqk1c3icx$p(;)1ho z!rNrC#aemV8a+E%ziTz6*fwq`;wWgpASq#SABb;29c93k-q| zhc`3m>^$&ViKF-A<&C{&9PJ`UY&ztaLKUyC4T@w_y4K%z#ocRWc9jv!^Me5f;zcG) zj~N&%GKk#a@qNe3BJ+J|CtsVK-`^Y=`FZRPVXt(5=(Xi4w6xuuqM;~oJVNr);YNIpN?sLZ!8Wt;V41C!^>5)Tc7rU&6`EPiq*7+&dSot&bR zQuxrJMTXDg`rc%=&&Ex))i0C^EHJ2u+rI;A9|Qpd`TF?j+D= zd9c9AAo)l_&4+!mm-X2eWFBc+zKPYxVS|VIp4L77Zf(vDtK4!nG`{yS66LtK_>%Mz z@mCiUm#KHPw%_HRGqqiqXSH)yQq&{|DXyvjId7>6QOyh+9Bf3`8+Sf*;C{HvZ%&9z zvP9K9A(nf^hZ-jGDe>;jzN+wNO4HAktP3{kBqT9?(raEBarKDqK@JhNI~;9nb|%6s zlO!!4>=kflahdc@#Na}u`n_pRniqVEH29R47&s{`I3{zDhpS=FcO9`aGJ+6LXJjD>Ock`_$uKrM)=IGLU8O zfeuy|=QWO5iUMn$gl~umI7-}^5Le*BCh$nWAo!A~rbQ6jy9y_!kLNv7HZ0ikOVQDh zW5VOhyecL~n*MYgit%7GpTa0HPl(Zx{qUp9jkE71FdeQIxOAb`>4}cAs~U?yR69>6 z<1$%wVQFc{*7YoI+HB#CmfHXq+Co|oVP^DvM5VDW@vkIL4ZwXjS31gqzjvz6#|^!dz3P?%=#q2=)A|tSx@sN`{@l#=N|~M&s$L!tM6yAgTG(D z=ul|rd;10v1A~eBdqWPl9zDn!G0E!Jju|hE7OE(^CO-&_ur07*;e6Hp(c|;u4^9h0 zJ{T75pUa^qf6(ASBp*}54)23^*(87PJAMg#uVKW?-MFQOt^3N61;Qf#nx#J$_1w|5 zTmS6rA%^`yUhnt5lQcK@CMF`n+;1bx8#49zS=NS)hEE^=u>L8b%%oy_#wl^Z0)^x= z3ca=uIt-@IabY@aaP~nP>xReoI`oe%Vh(JaarVIx)Al$Hhxp`+EK(jGk}ukwmpIsQ zcTK6-uveua#9*Z&SEGwm@SO=!MKK~OGW-Hf@4Xis5K-z2>|$)N(5Y}Sc0Bm`?y>^` zPUcFD4;2dL*?5>dRNtc^cfrd$V#-F-rEe25RVLi{ z`oyE@L&Qu*N8J}q7c*5!5I>k7;93C;x-|O9Wh~e9O+v6&2OQTs|ItLjXS(xb*k>wSjsIcNo+sVX)Ckn>Z z0!)kKS+_N&aU5~7zM*ZV)IR5x!h$1CN0fE z9Mv}VC#&5oZL(qfI3ZyPlN>Mi+Ek4#qQ@BnLpkOhm>}+QL}?q7Be(eKW-czlh*Ujp z9fmDUKWbYUt~51dESO-CF-p&)YX(Y7!VL4JTLa)r&$$y zcF6Pp-%xL3qrxKeH2K}n%?Td_l>bODADr456L{nt!$m#4S2hgq?}WdIm^fLHGqS8> zfk3=Y#1H!(5grw0hXno~(+~ZqzP;hm)`WW;ao<+WW3)3_ed$E`|HGVI%zgsrCi%OF zJ25G!am<-~!<3FP9`P!uqHqQKPj-aARa#=;}@ z5r^5t#^Mt?vJY8&&&f9TbR3GCFtel0sl~CbQ{gikb4FVnM{7%(M1(O*0-rV?%Yvm_ zmOAkNIv9P1H_=z3sj*EqvssX*_;QmY%N{4G1Bc{1IQKYldVH~PGP!Vio|+cIZeI*& zm^Q(MwS1zJew8x^Clg17o5}Hg9ghzQ9arjFVk7IN%cCU5-mxL}J*Q&&-j_iWxemG< zR4Nn@YJQ=RrXZ~%zxSblh`^Wj6}>?-q;(!n5NTb~DPpVW+@xT?{E&mi!igSH zsSjFYl216Qd{(%8XXymV0wn>dY6XLb6HmC@>&USa=&8OqNg!hrWTo-tG9f6neMYWr|OMNav$sajn!A#6<94qCc5Pq-~)WV+GdfJGSo?xKS$*zesw6hmqnBHD;xwOeLohikz$)ImG*m{EBoe1tN6> z8Go!fV4%X>G?8P`@kI(o9XVDVk?yXpOdk3PH{T0526rmHEWRPeu%w+=g^9uQC9hcb z84Cf!TMrI6$z67t@Jc@^;>aAX)`-^zeGSVy)GS+VgMPU(yP14%5jq(7ra@M{>4J%X zboE8npINO@LEP;^Z01|o4tj9;6rb?mwP`Xi`Ow7Cd|u-K*YhnR-OVT34<|NMxUaQs zTg09CNyvQ3_od7(4w5&n?$z|jkm7Dyc+c!9!?L6s1-#r1I}~dJ{xb>f(&b)IvwuS4 z;X^St`uq>33e{gZF>OVy`-5XG>p9&+G(WCd)i~kQABhR}&F@0l|NZFwuUIfCMxg!a zBlCHxoD7YOa|9mNA3tzbeEO-Wul{f|FMhzP(9A4%v)}ST-Vce}7nvn|#2G#OieK@# zng=9Ykz(-Rvwb4s?;=9_3;9(GI!{K{kVRcS&(BnGRoKs>(6I24P{YFW5**x2Q+7C-Hh!^j)OpbAFL0KlKYE^XLhpMH zb&1zaZ+I?pGc|O0HJ&%|jC^=QFVH|IprK7}jiIhLheuuaX_tltTFjXXOpK*CQbY0# zuU*`$VX}db?|ak16^k9t>aZRO;C^s|m#Oihfd*f~N`oFH=BF1nC^36fa&R-LHwjFN zoABC~v+JA$i(;T6&jUr~Wi|qhsc#Kt@EX2nYsg(+sbOJ!Pl8ABW%i|jREINc&)Jln$e*_$4}Mg@h?!YsGpU0 z@k7cQrqKCT_Dqe895o^el8RN6#8-19`TIw_a^Y&=JeX%^W6qc(xQhJ^Lnw=a?LPiq zyLp@p5zdDk?AZ715N3#DDZV!$#IUJhGi&n_jSLs|!|z=L^LZFtS=||LnEEnLkf^&* z>|M+=myLPShZC$PEk6_q9N+t5>#;`u=WInlVM6T|`2iHFZnW zcU2w_-9rlEAEE>r_E$OPO^8cya^0iQm{B~(xas8@1A$5_r=wFWDizz5bgDGPdM-7y zp6_TA;_j%@_Hbjm`%Z#K$zZAoQ<5Lo)rKt_uQ-KvGDNd{Reh+yYx<(O#X^h6;fC(s z2QBgy6GS#&_~4@WXh93V<}2>cJnRfQmhTgD6q%Oq5a?n(F3_~zBg!F2vA-fos(p_e zV}ypn_B{&AcM7;M77F}Hifh>Tp8tV6Q*&bz{|iMHy^gNdLlG0-hI2NuNO*_YaClZk zeATr%Vc)30Ua+sJ#ryvSKDX8fb-$!OEl5si)|tcdnn91j;g1m4a>=FN8ZO&?v+)d- zRX(_bza`M|q5iuHR_0%sB|Q6WYQF00hs3`9Yx`VIzP}=j<9|cNM3MQnANYknJ)E`T zMOp{Tfdlpu2S5A`I}~%K@S#p!jI!;62i2|qA`E*jh%$*jI27e<&depxbLa34{pKR+ z>U$5IB#w)^+0UzPH1Yi+BvT?{T>0PtvxbPD61Sss8;A2D^%lj2*IOFWzBK(&Va&{y z_lVfy`1ukyvkbDMDJbVFCBU%M1~E_v{2ZUhkFRKJp{j$uXFl`NWbbPM<>cy?L&dN>((cN zjp0koSrme@FS7o2ILIMvcuJbpiTRjU}3ZM@3$<^%OkJSxnbf&sGfFIYNN55Hn8e)S+l{#e_mIYNys z8&xWJUz&(4<+tExWRkF9|C#!qReV8x{KNm;&4$nG9{l5SW>_Fpv%rX>jzj(62L)Yu zPLV6$&&#uaP&n{p#m@ihLzc-2i8e$`sf~QNgI|Q}MOdBx{NVJ3-`O9Yw`1gTJuP4H zkK?c_;|}Tj-~OID(i|81RBMjFk$%3rKOet}6K{B6@$rLZywm^730oL11PHK9{P4wy z;i;3~<#YTEe22Xp`|UNE(+3}|3Js|Su>z(x$-O!fT@oT(B7!P6T$nc} zJ2eE%wFt<3(89%8S;)4$<>3q?rjP3@OhlaT9d3Hdl+ph5iTD@ZDNPBdAFMAv(!}K? zytE?0@UclmQNj|RgpQDh4W}6^WPA?jHVJ4ZA7dL!e$-)B-jGG-D*J!b6))qK1T>HzgVQ*l)cSqd{i5vAg7CaoxFDjV%n;$rY@x;_9 zcvX0><9|?aU+eK49!9Uldo_=@D<3vJAkN?ZAw}TngX6~^g-`h_aiSvsQPhT1N#B~^ z{SR0f^#AZY;MHST>J(sDG4UUND1TVcgM{{n&yNJ0*u&JIBF`{Shk4Orr=a~Ze?uy& zYt{DHHz>0D2Yq~Ckj5i$NMM?6(E`VS*sSNr4>EYKk>(JM4gG#m;DYM~omcu5G4_dU@zT-%k(s1&TBriYvoUfS+B~sNdiCGBsuq=$eop6A!X>p5! z#sahLO#;TXiqBXC6yCE4)O?@d%vPb$SfgCb?#RM*u9CI)A;;7`8tQZS*d~4NVYu*o z$uEU%-wZajD86X=pryq9A%TfQM8+}E-_GIjiW_SWdzoq5$@4g!IQraB>9P1Ef%FND zA>R@bR`76H9$LuQ@b|q2V*m@grNSbUBaTV!6B9Y;6v)4>gYSUA#)A`5zPz+$T<9r%_@}>(K=;*h=j~TJ9{iEG zKXuEi2mcDCbFf^n(`Ldm5KD8#?Pki-! zy&1cgulTmCpkAt>f;#c|MjeV@In4@GZTZ+{uZYH3(%hG%>>EVbm^Ii~6!_Sfy_Qd&&ED|ujRG@^DSKlR zOY0Y=gB)Hw2RY-4FIjr6Z8+|@f=NJuh3VOxm=%`~UJ+_NdjHe>a3+Q+D;-$-kF3-` zx5tCcX#pQ2@Bbea>;L%~vM7Y{T8c6Kva+3fm_)s`Yp6GsYGWej#W@7BcbYzQ0l)ugVo$m`A*-jL-GVux>vh3AX7 z*$v((GPzp{#0RNq3ariOk?LI1$;s4NxJl(n=ArafhC+U~C?6h;oDWN^gm|1g8hrOC zDXjW1!9!>7l1Z014*bloDC3DfSf*VR@ZkXKmz@o{qU=l!CdW639Tbq@TKT|>-}}yl zLrjt`J0EdyfAXpF&9HAez;WPX`PHi|4?f86Za&~p$Ir;Pzk7N2>F2)92kMRZ85wsN zI0&{s{qVwu{Yedn!#Vbb|2onKWE)D1*&2E3l-L|Oj@jt(`5IKdXb@x!h}V3e@?(OE zwrpgLKDvdIWESKFGhC_XFUGF=&-`yF`~>22@3t) z-A5*#3I^Tod!Y5>9p&&32`y_Rs&n@&x#In4)3>GrP64Z(Cj4VfuwXuL!1<$A^(i$4 zHTK5;Qz~vvKF}o4$owd%@w&_k357%7EN;H{ii>^h`pV|xA5jM1<^zsQ{EUpJ7Bn$7 zoca@|q&aJH3_s)F8#4NG;x9TL@UeyPzWeWSu)(Cp>OoEM1DR!BUOdYhKQaGcbZ9U< zkf@``5YlipKyx1Nrw92f*pD>Gx(UDh;K8J0@gRmzh1p54s_~`J(yT`-N(7h$rrGK< zY$OC4Iu@&f^3h-WKKeDvSyS-N}X z6J4QJ)}VP`l3kQpOpb3bVv+Qip`W#|bCEcQ2;=TsA0}|I$q006*r;BWk_m1R(B7fH zN1|av#LCAFG7h=?RwC>R56ocn5WM$|z3K3eg{Jp}ydM~x@!-%p-W1C8;5cK0_0tE7 zs+N|#tY5anzL&AUFNuc@E! z&2~2Y7c7_Y!oGpG@q-)_>xB%vFo8o{^S83+hvdjHF&88>*ag_FI@ozw5!A>({vnv# zA^k&^O8m+{e=2NPxD=#6IQ{5jWd8JDj+Mi_Nq~KNV$}-whrgDpOOF z`fTzo7FdfUfulS_!SAx`70e6<`xvk0hu3@lf8|lzAi}}aAmZ?F%f}f>VR82Q`hthe_qN{9 zTdA5b#Y^r%2baW`h-WO0X*^sT8VsE7bp**OPJQp9%Dcp-ZIaXF6RwrqRVoSs9nMV- z8k#TpFS0IkX3*fZQRLva6o_a2;K+7x`x3R?0UI4RO=Nw>qIgjI#=(~?8#+&@F!E)j zOjzj3F|Xvsy5_FV9bPIDVhTEJqRmY_dtXd55N40ja^umE77Occ9Ls`es3b>3bz6hL>Sh@<&+|4nIiXmv4MvW9MVY-q0BS^x44&3bt$< zRvcN`tZa-A6x=|-%KK->&SK>Y$&+P1{1cnJ zNA5W~AU+FfK0tPv87m8+;;)8N3)sl2sLuVKlgKU+eUT&Oo)@IgSM zSzGUiT*%7F3LgX%n_2WjBWjo#r!f9eWebbpVZ0ddgUP#n?saYE=gmJXKBOjc9pz(N z9)Zfh5%+%7P9=ER_(_n}3&YKf+Fg0Dcs3hz5A6J}~pQk)RyVkN31RS+rAaAxi? zp0Ej_8H#)kX&enD-nva9A zK|u558YiZmI>|>HB97jB(iYUA@L&eFq&wqJ?Xzt>Q!*XTFh6$S`zerI;l|oieRw0+ zI>x+;oS?4?$0QjW9fIdge$o*3#j&<|f!L&Lp(orHJY3;o%FoBPv~a2$pPhtv{y7T^ z&Ib>IKC~3YaVXq;=VB9;qsDah{RXDXOZh^~w(>9RS7hRD5y*3LHWYN6&gCd(`<{>a zN)4N4|3bl+{09!225$Vcz-s-2<-fmAYV~SjklE$7yZI-h#D~2WDmC6hUymL*C;y{n z`MP!e{ErVWem8wC!voufgEJJG`T1D{0&>=0bvvHc+~9HDLYZyW_co@cc2Fy6H}9nAWy2* zK?X)I7KYG!Q&^h?Tb7u8I3vT;%#kdxRamUkkBvE^aDk4~Jqc!k4+XmX6&{NH9!~_y zn;Z^oJY$j4svE*K$x}dtsb7P!?U6vj^iGEWZ=UKy24)A&9!W4dZ0_j5{Y=(Es``i` z3-k33*Ll+}b5-5@@Q=&oYQll+mv6LqZuBufIAq?~u);#*;Ecc9Ym+<~6238Yn8^yO zJf7MX6x_vIx1(OAU_p@3J;q1w2i^&CCY;y%{z3B9`8m8E>aE?33Y`x<#HM{XW5CS# zokb|%;RfappFMvz@9mvYU@%oigT?SgSc(j{T+O2mMjA!}?d>uT5*yu~x!iGLR@8T~ zGq~fzeRz4CDz`vpd)(3m`W|j60cF~g*FM~K*7my-!Qxc#d#o``P|4_Wh@ zU1CCI;_br%V)qIkG_lQi(z?(yi0i-}cD9x}ChvnBVgiqZceJ>C+4`c5H*toOg7}jEdH54A^h-^mCH#M^n?6Jgk<`(lno zhe)%@6rmLxG8av(xZr4@S=k%6Z0Gy zG!!a=6fC~SSOr`+XXY|-c($l8OM>;FzGqg>3CD)V7g>)P*i8{*WD4>oP%`guP~aIJsVD_Oj_gZ|gUpVou{j1bam0O8tyMiaJiv9R$qH#LY=IIDU@-{Vl*du8KG zO{R%Frt2zN4A1OUOwiZj;9^`FG{LE_DxzbB!gdzr2_Fu$-|NURdyuHo7RcZ4wk4)W z@$#VrUDx8f8=h%PnX;Vn-MC165f6(~<69o72lb3Acn$?Eb*O$mWryNwy_=#(`inMj zw4Z-4gE6$mNJ!M;!|(6%vT;&<{;w0~9|`|A+e<=~;T~JFMCo@PN8ySPRog>K1ruD4 zc;se2=-K#=MeWJTQ&%>2Iyoj>-+Qi;@tqRWb)~6BH8PA|oUT6d6U`@S%rO*7p5rvR zk%RlmPJM+1l6ww_+~a7tx!jTCh~C| zu@Q=_Qw{VN=pK=MoOJhng}PeseTMeQ+Wi(P5|PJbR2XMp4BSXeO|DlDUG3yys36-FS69l@2EYAycR|`FOr+AGg zvot{RK#l*uf07pUOcMkTFY#FO@S{TQQ^WgmfdPgOIC&X){7ioB4|?9Blqb-zikVII ziGX3Ha?=%`;+zcI@1DH#dzpf+X^VV`m@-31bf+*=8+Qv+qoeW-CShh4r?#qv8N~{r zhXfZF#2$DR5uj!aBpmNi(YUbc-UpqE39Je?eR<}xC(Ziw z@Q1X#{*H*RS?vdE>g>EE)w~}3D?Y@uG|97e=FF9+J*XJIM(}1%6px*JGiMzO zqt5RC-#C4FSsI!c7c?+Fy)>Qw>E(O-A74FDV#ZtF#55~5RQ&EAD^*VAuTBncs;*~> z)oGtm4p?9lvCWaGK~HS4+=Nd}8r%1t*vfl2klTW3&WvMBE2l(Fp7)K{V~XgK?|X$K zCN5i)d{M|r%R`yz*v{MSE*eFOiCiKkPYs?Nb`;=#Q>D1Q`GAIl#geH9XL;}mG;sNc zC^!Uk=dlSTvnaWkzV{8auoGLL#Nl|T)mDgGU>X}^;PX|>;&{x&_oxaaUT+aiKjGlx z&!H6~;A{Itg2_fzK=V9@LwxilZpAB0S2|?M>hQA&w^()PpHN781S;3=g1a6SOxx>% zC%)lgS7Df37$9)+(&R;=%R~=Je0uofkBHpT|AI@_zkICxgI8HVL!wSVRBM93)jRXj z_AtM&VgH)sFg3HlAvAZ+sv8o`2OLfb9DHEERlc)mI%kMT&`p)poy!ikG%5xd{19;5 zqpJO%{ipirt2M4hDyXew^~E1Gq^Cbft2TUaLHZ%zkGdsHjqL{xIXEtT{DpP+KvdBVptDDlaF;Ko$k1c?UX~ zBm_=WpH&E%v))MX`VtYTMRC*ESw&n96+aP(df>@)WBHCX%#9AtveWC&)GHi6_4jMm zs`a(5YlHLU4>YqMPI7#pU@CO*fr9I=jSBqQ;qF}`N4ZNL*szEy+-vw?AlJ-d-zoNJ z{c5>Y5jPCj847IJe=3|hV4>I|;J_y2$l(3sLw)l@HOC8oYL0eg^hUQcK2TW9-tg~= zmk`Uuze4T@ZpEx|XWroE_8?-p@Ku=NJE0-A`d6|%J_rrHRrG1;T7%7a%6CSIg`PrntkUk zql;RrPR7X}EXeT^a&%e$@94Sa0|$canHTbgFmnYK-s4E#-`5h?;9$ z)(z`|cqHF%R(Zq2I7{)vO|E;VI%+anG|nD)VzJ!v$f>F%gDIPKo{VG^_$)I`L16Y2 z@rN5b+Kvgh$(|ADQBvu=A-_mc;2=Yhh~k?ABJB*?^EwQ?6pbeq-!|g0K6)T7BksSP zZQOwi(k=-{rg=rQI45p#F6Gh8;CpzEErjvGp#XN~_ylL6soLI(A1XKm4lb}^;dpTL zkb`qTyg|*{slv~v{?@;mpETXUX7zu;1(#O-?`i*h4Rny)1b#-wJ^Fed{&=t`D(o}= z{rlkygA-EB36lg^8WL}OTysCzej)d(CU)zv^2QDI4%YPxf#-L_~niSqCZg49+W%$N&!6pr5i^`W?Pt@jhdb0^~SUu?pRj0q#PmeU!FjTN(T&;5I zfYOqw94oeD)v#urXNcYI!*iaYZjD&Dqs56DL)PcaMpu}&upfTl8^=7eYUA_HxPudZ z*cTscNaHbmkR;C@I!}L_>j@in&&R$O3#vF1Oa8K4vh8|c&{@J|f4psiWr?e8sF}#+ zckG83au_F^^=9n&liG8L%fX8Gwyv5v$MNPhdoEll5%zIoQ#CQNVDvCJyC|SeEvxBF z%IAe&6xsTiZHx;p2%2R+I3c~fpSe&Val#SZf&?|mS&YklnI62U$ax}c0? zj-@O3+Rw>KH66G;Z`uiWi-bE9R!!K{H(gc3v30qvvEa@?uZu|?LDj~^JdFJXRt7td zx21l!dH7{vk|9^_`?Mp@*QUvMCl*YzJ;%x{^WjI4+^2^53+731be(K`)@)E?{Jd9Q z^I*!Zv~zoedGbYu;~by^EumJg*pT)*8Z%CKf3&0JzFLFj2l|5Q>w%n zQtw}|{{J=WtLp`i(6Z^xb|3sbm_JNuyzR69)zr#K|I|fV44*ePoL>}>==;#3KGtO$ zzjm-Mr`FZ@>Qi~EkKIw-RO@JJCVynhE^+5q&)zW$X_&367wFkA=Y>X-lW2Tn`W}nM z(7N4nG0P^~oZ;GTW31jFqw{D+g>i*_XW}M-_K%wJEps<@k6XrjXM-HR1P2bMP`%wA7kUD^9c#LKJ#Ox*d}zU`lib*Rl_*b8!nb&af5gn>69I!^Xl0lhA*16{~!8 ztUd4P$eogVs4&G$vc)N1it~Mis-#f=w6 z1sP(8LkcAJzz^+?yeE{80Sqoey8w`TtLl{-~n(X;s+zEAsOHx7M+;7&5$i$N${y zLefJOX7kX0$G-o+#IZ8w*ul0Wk7)u<5`WwS!yl~I+RN$s1J%Z)kq-6vI< zZQ0cHUGYTYiG^^ZuXzkF0c2XFlklW|x}eVJ)0f_=klpK;VFl$kU4oO9Wi{TdXgA)T!ax zkeFd06Oyv0!j4(l{`Y_NIm`GTq=1@M3iA+Z z2g9okssBtr7R|W-Rr>$$WsHBgAEqCiGQGxa)8g`$i5i|lp^QhvSH}ld{NrzFdcjk` z{QQH+0`cm(+STnJ86}@IGgO%W6X?ErfdjOKn*G@SH*UtCKgqCPbiBUj<*k|wU4_#J zdxcpae3@z?cr z(=$2kWy7PFhl&?HT;Z)Z?*&Uqk*S=RAzSBJ=7}rnBRFFO*%jhSEYzJCE%c@vtB5sS zn$X*PW7`~MzC#xid=2MH8AMGx@^D3!T)~R~-S#%d+}u|?1x}P0+c;`pG~`$`%aKD? z?u%=e%QK}Q2^Ej6Oad(%-wEPd-mcjd zi(<{&QXCImI(UDH8}G|3{%PO${P5CkpJ&MFoL`l}#kNSEmEoF=iO%xF3OiJn``Ngt zdz^6LO}NJE?wAqHP_gnsNA977DT?m%Zu@pxa;h$6_*J9D>v(wOp~9T%I~u$hPVFkX z$*gCVF!`QWV$8mp<=_ss zH~A!%C7T-RS?U=uFfeXr5O8N;VBDs$L905ok6tG-6ViR^A(LH=LOZMHKl+mKiM zUf6K*{Fr0&^H+#-O4ytKUz<>8!5FLlJ270;u9Z(&?T7jT1HYs4FKUZTB!#yhsPkZ~ zv%CF6?IJ5r@85{|pVu@$+WW!tzdyP0TZ`I3@wYPl zUuJI73%q}5`b4gOx0Jm+zAnH0^Znv4bLZ!#-_xtzSN8a(zDM%ScHa-@-u+X# z{o}X0FW%QQZ98{PG$eiAH@DmMZ0Emstk<^OdH&&i^ZX?&q`0`RV^|zNu#2^Z&N(Y59gY#`+3YgN?0g zboYMPxI#EVe9DZu8#YxQViVh{wC_mn{Q8_J-xtcPsh%_E%oO=LhA_@G?5w2~xr>+I ze(LiqMSs!CkCx}Zi+ZjEvO@ zxVPK$tk+s;{EbyMcn|GrM1 zko8i0v2lpZvxdO$2Q4Rc&QejB@sR%>Pvu4T2Yb|CoKy68{FaCD_{{q& zFSVD|uB(19TVxBX{{Qf($@{OkwB*DIf0{nu&EfIy6@l~Leu&v3%E|7|q|?1<{r=N_ zTc>L%)mp|rPh`(pdQ^87Pg4zFqr6sf%&~;W_g4tE+DqsD^~w0DG5@XNuj=PF|HU~3 zZE*Y5GvV>;kGs_0ZeG7&{yC%iiSwV|`{5&FC~EhUbAIk^>x^F8Pjz88H!iljvPLx8 zu0+P|hWE$I`7bLcZ~i>{Mrp%`)yj_7e_y-#u6F)5{i<~z@;b!!WLNE|;{A{i*v}-O z%|36DXMIJ)AstQ8HkAb*KaAyC@||@P`DeB`i14OPUDrHIQAMoL0+#9KjW`= zb49;qo_ExfuknGs=cF@2N0R<4Y^zMD+5h)QBZnOG_kvXCf6U#FMI=PEq}b2=e`mnB zc$veRQ`uqlA0Ndle_hnJvRHH#n;*N-2L~bd`)?fPHdb)zKm4`qdgh#qvpYY9#=Gd6 z*Zy&z#+6hqJH=IT%7%^Kz8|fBckTQ{>;y z&n{$KX#Mg|@!K_BExB2Iobi6|TK4C6BrcvkZFVe!#mp}IoE46T=C9qbbS1mA{jQez zFDqBJ@As&?`S$p}uEPJ@j~E18n4it6XaBa1;lXn00S!EmcXcFb)I2j!J>_b)CLR0y25WQvT_|G>Z*>)(EqI6p@% z?}Ve}`pa|s!|y9UNU8kDv2y>~&3@^T3;l05+C9E6uF{{Ve|z<;i0n5KO|PXz1MkHv zr5Jhe-~9jDk>!4{NZRv&1Af202^+|W{=1ZSu+l+0J^S_h6`XVJPX7Dy=!M5E!C;A& zNCu1k7l~$5>y+5J<~0{o#{c)&_iwS?!6Q|R7u5;<-FGqk?aKvm`>c6b{)FI2;@vTC7(0{=&)?2kIqOLuyQR0xV5+vxN+ ze)W7cE{CQYvU0WBcAuj=zxGx7TlO0Mo4SxchjX9VN&BVy_+r!(9?kkcv-z6?+ri^v zUIH$Q9(`l?x;jnOFG8VWfD7`oncSMBupV%gfWX!j@W=-ZPk~+daRIM!T^Gyj@YafAXsU=D8L57bd@-{%QZi`TYOeXBM9V|J_Fm+zPN zF`j#Nf#vhsj~yOozsOWixG7zE+WJZCL09dc6id@o@zUBo#c4Cx zm>=9re`VmV7v!;a75~itH`%zasFmogvvVZr& zfkV1VRy$mPY4M!}lSB@B@d(_O?VqZ~qO<>JUBc5jOuh97x3#B#Fmgy}%&^$we(3(6 zHEBDybFU6x6k&9dVS}jHtm7LEv_ls&O%PKQPIK&T;NU@v9d4i87Pako@}pwP;rCi!&Xp`ZW;VS%a9&PY96uxT2{!TXYds9uIN2Uq z*szEwpNkFE4=9kgW0=Sq)3naZ?Mx@Wsf-yE3hzv^4>ryS8)`m72s_HS@FH^rhdLc_*9^jAXgLH34JjOg=VYuT%0M{nQ&l%@4po@ z3>p;@7%o(BD1>B9I#^)fQlZ)K<5y#Ad4k0&4kf3JyJHqDJM=@2z2P5^G|RpO&CmCF z-^mM4=XiRuD4Xl^1D^x+UOdXG@^MEEzs#uPS;H4MUE5oQY5v+bW*vVrnBB9sI&C?X zP~1|jB$U7I&_1r&-g}?x*!FcXe6V5vkZ@~t;gTIujit5?Z+T>d4o+n@W@PPI`#aQJ z;dZ*NYQcmT{Hx@zO5R+wamnNL%jVvT$i4JD(cgb#aPr&zy?g%I-2OF_IYU6$py2Z3 z{Qa{XoyBF3-_N+KRx7nlV#1&K3uD%72)m!~GNsnZb>DMd=2n}1`zxMT_#fKF_h9vV zFXKlV+|QP1-dV8!&+_-d_A{@Ay}YmZRAKIPP4S*NulId8p<1H(`ul=+mRB;`7|pMo z*zL5z;<$FqhdHQNA zo3gF0Oa0~1sMX+#cI4Q{o!6E<`4jJVrFlF;KQo2RUH-eNxCvSqM85B>%uz|}5@)~q z|GWF9`kCumWNO#=94L1=|LFVdeR~%wY4!XQHOW@8{`frl!Ob&&*Z+Rq@Z4^qg@12r zeD%77InM*T3M~5HUediGQvAQe&EZhpZ600$<9Fu@mN&;AtgY8CxW1YJ?CcRz69xLS7UjdYH3zPhXDw;zzdFmvwjRPH&?KZ)1zT(|v_dUB7uxKr{O z=^pv-Z{xZuPNez2vfB7Rfa&$i`=vrB4wm+wfWPf_V$K_dV-Bi{l^;_9I~BwJ%gAv z{~x{;+uQz#J2!99w~B(rP5R;0a?On%e9Q+L6q*}s1Q{Rff6N+~VASwOg8M-o$6hU_ z2PfK@6z;IB;b&z$VIk7+VgBo84R(eK8xy7n%ULbV85<=8Ss2PsyT+$9I&cXTC^TtU z>=0xWuwxT+5xU6Y$flC%&d##;#YzK5<_8b>^o}gZu-EnPn!@M8r9;KK!~>|Ott z$XhWQdN{EK@hl7#Jow=MOJ*ewBZY+Lj~fy_W@wTO=Uo^`R-(MyW+B8RG!CBRS z2#%EvmQ!VeZ4~Zw5!LRaiksQbN&QMmG| z?DKri;|s3H@&7JxVDD(Ck<_0bDWNj9AkV?KbyU+p+`>p--L=6EXUT!vH!e) zWbO|GIrip;sS!5zf7Ui1J)p$%F#MLn2m4#i2OYe4*ba6xKD2+zrX#>8A}7W0;ZKnz zvx7%Lgx8YBf(rTPj)-s!Y%r{tW-r*XOj6!V!Q6dc)>Yp6eQVTjTinZ2J`>-;TD#1# z!8F=eJ8R`<%bu-!m@oQo(>#6lXjaz z=7SDqmaGvICY159S~VRoTf)Q49<|h|ac8)5yN0dM!InbF6>F+aG`{|LWN9P!)3Usi z$2OPbzGXddK{C2N?1n??uH|o=1g4ySb)B;2@94(Wg%j z9AeCn3OlvvLg+`2hP&T$Sj|4~c`tHLy0-bif3p?|Ugo3qmv-32FfG0i#C-679!J7Q z`HvSW*8ez=(Eseg;iU;(j1OwHnhu!vZd$xIKw+tF!1Bp^-dmr%>?hdtri7RA!T+PI z8U|T${Nn$;?`vG>mpeCQF}sqe-^+vo*CTH^g6@AZep}$1_p$tq82^vYc^|jm*|>Ml zlWc~^cjmqepZUz?rF!P;Ge5f5XS2-fx_{*71)u+H$Fxg?t22(u#~q(zd;X9A&;M_& zZ*6&NIK4cC)%k)Wo7|hALk_-{mi3dJcBzF;%~qIj^FSL{;Dgpz(L2j{yFA;UK4cM5 zIJ=tJdF86fO1d!}H(EG253b=z4SV{G*dK5G$92@f!BTh% z*O7?{-(R@;b~8LM&=55g>Hl83;i-g=s3VI+iQNx2ZJ$}}d-f< zoMe2k|89a6-#@;)4+Rfi3VK#&!#{;tf8K(J0`l_zH;cBgZM1uKNhHJb$72(n91~^( z0hbLahyR4x3yE%0jy|#`Tl}lh=e1ir3PcYqlAF$v6zu$^OMmvs7`^+PoZnwVPbFcXtcpH-D2Qxy(f}PFYJ19?Z-R6_L95{=nVd`x@6HORG4&qrT>!|2`>q zV@OMn_?kbHmw4^=w=!KkP2ss8i)^OXZILOvKV(m6^_4cWWjpw=>T##`u|*z+g~gHH zMT!oOT3^;oT>byLG^>Q!U#pFWxgS{kI59cc@MJ<&%92BT3s=e9c>my}`qi)DErA8I zn+*h%TqE;$E^l!-qn38*+Aj^!Um8)&^IewQG&1H0*}Jd3Mf9Hs_x7wSjdOlU1f7^2 z(f(-Lt)nXO#!i|g&9^V-)mN`}T)n9L7XNVuy_ol>UNOXM3(~wVUtcum#lIJqU+1V6 z^v-|twrh4on)~g^-bzjlf!7sZIbI0+<@|j@Pw#9|gS!0x^={f9WVA9G>n&#r+x-?7 z-F@PmLBWBLJ8vgETr8DdEA!am&fNOj>^zK3?x}A$x6YCJI5#Fi@_wU!T+Ti!D z^XJy{Cbc}Q@wrkOrgvDsy*lvRGO+3Oi=?u`&HwWkn=s8iQZid7kg5La{O>0@-53sv z*)DvZuc7{T!|d6j`ws8;e(Cp$UmnjS0#?8MAg=p=!3*D}`n|a?^zCCW&Pm@{yi?f!T3n#ZOK?Ls~MdF6}!?!OXB)3^W8qgGhr zcJOfg%AP>h;#DUc3Z>Zt3g2%F=5#W@k-c|G{)&kL28HkUY!bIxAmibs^~WXmjktaO zx=egn=erBd@hJzmrYIyH|kk}&W(PVM%iyeQr#Zn=;FDaGt z{wq01aOpEKC{0tpn$V?CzHi0?2bo#h_sX=!Fgtu>yfV*o&DG#jkM^CJ?X~Cr6#WFl zT_*RRNHrfgaB78|_`k4&j}mwf)ZG7f!-j`vRpZ0@r#W(J40k}cQ+WJKs%Oi-?eo8vWc&L|8wu~hyVCi zA6Q(|yrDuu;;IsxZVJ@Ew}KZ8i$zAjix7|AiGc zJUltfhyI^C_29q?kdux(d@wLv#oqdV>V}FL%mwo1|F@n0yNI8e$=l&ThJ+p4`zy?1 z&6)!4!h4w=Kc5j%v^}ij;cw!E`5sj7qe_)lYnyjCp)_kqt^B2AqdQEZRom{)2P@etS|L+AdJNem_ zEWfD4@hEC}O|^=$&etlIu6`IW^7Gf873Te@gns+Ku7I@722paPH8#>0t5wzRmeMWl_5zNAv9m%QC9iuk!Dn zt6lhkU#@Y@&PN6()^7aqr%q`x>yAr-KhvgF1|iUIvWa% z)}}q$veD~rjIuDtf!29veiy83o}>FEU|ZtxgdMg5k=k67gFlN%`6*_zlZTyUXI{p+dIFPZ^&1>K0i-i}C z@GhSC+I;n+2~)$ISfp=k5`O&1T4#IC*PTrZOXg)cZ8Ccx!f?x$mCH5xL0e?~|LCV& zA^P{&Q9D)Y#Nws)!CWuP)7@$+!xAqpgMh#rKNr~9osPW5eDj6U z;sDLb(y0sX8W}}!o~@r*p%mgY?dXn^wc-0&-PxRyk^&~#3$?#g`(o#{t?j-R8?lT<#mT`sfB}kSx;gE;1{jaE)$zey*d*r4cnfFSF zC1lm+MavFH7%Q~Rss43XWQA}z3q$L-Xqio6EiVq#YHj=ICEogh$0wp9(}e$aP|CCe z#|jP^EOCbg)o+y+(rN z&umdW|6{#ee5_TUi_@+BDw+nsccubA+EOZS)GkDl8t%TtPJ{in=z*M)oj+Uz36>kTXYkH7v*1)-@_Nlpq9eX<>@MQ_0fTiY#j5eJT!joaoB36 zakkho_~kvHU&7Unce%<_HCbQ(l42+b{?(DfXL)1!v+OU8_vRmK+WvX_)yKOd87#iv zd!^cO)5Cq&`zucU`vR{hhwJlpe%Um6pQ7Z2;(cE=B!nh@iFu%I$!eMYcbCxCX;F)8 zPAhV6ES<1`UAXr1TOSwgqaC|~FU;msQYc}$zb(3D#j%jkc0(zK3tCAmE__mjhZti1 zZanojW&(>{bC+XfH>W2nufy`!b;^>>9e2J5+CLLo*s?JG{;nNY*H>jUU$J=-^I7Tl zUG~@i|9@H5nzQ6J`-1;}@0VV2`qWgTarKSC3XZz}2?s6;Z!IWD^0~Nfi~5U0{gdaX z-~MGD$lNsFEyjUQbX$%wyZrB^=XZxK*dSHyv@DPFXWd0>P0a^t77|~A4%A3Cv&2_c ziaEI+yeqO#XlGOXeO1!{fp;f7B=!qA6w15xEETY5f4lxbkz#b)FW2>KHA;UM^)J@s zY56mA^Zxu5XG?^4F%&ZIVYz-pd&&{__3;Uh%zBj0&#C7)x#J)d0@r37b4aVa+pGAK@ z`_MLNb)1Dm47=2aDyIowwoC0ldPVtAQ6opy4ENCd=KZ2|Oc%CFShD&mrJCsE^i>KT z`51iq=MtwShAY|9z2_AitulyZ9#Dd>WWAhwn|1+*tPfdrsSCCH*LN-ag~n`=>gBiq}r|H?}uF z6?C8OwnVstpCw1$FyiXp{jRP_ZTpTHEcGk+xS&9x-&8|uV;qOZ6^<=08J_gA3omES zc%I3fI7i@!t`N(%{27aT(=*l0AKl^M;$A%QkDxVAYom&nhvLT2IMJhDls%jTr*fQJ z%;Pjyu=IWNp`+zLcwBa^^^UQb=5uPt{@5QqGpAoX^rA=m&8qMHb$K;Yo;|JYnkl?? z#q8BA({s{zteHQ!32mRk^EaLMxYXRe{vY@4so**Bt?`4M#rsgLJ>os*Cay`}sbC?l z{P^0dvKIm|A6DhN8L^w5ohUfD@I~WG2ggKh)x}N^8CwN@DlhBk_5NfM+pLs6=X=qU z3~{d6!uz)s&#$q#BJxFifApobvfUah=lxJ`OANO8cVBRwdW~wsz7(A=k8IA{PcATE z*KvNSxzVk5<&*^x!to*-&2LKt8b1%5a^Qf3u=Iul>COt#wZ05XH^^yy-z)N`zk8iz zGt=8o1?)`UcV0PAb>waH4xz0FuX5cMe7znJa_G`)iq7VM{71%-p|o~up|4RpGk}Oe76_rSDV^;lzwD>Hoo1x zP=&Q)Wmoo#7oC1Z4L)bypSdns@U7t$zcz!$YK0~3_4l9dWiM{(=@dG_YE?4D_qwLY zAMskNAABPD>%U&-n#H2*!zXpG=3w!6XN7eIIZ1uYeg1!!@B1#>&GLS01s~U)ttpA- zw{@C6toBdPFVFY*vQ@&OfBTe#_0znv6j}aWSULZ9>ICibOHHrmXT^V?;vuxft*N{; zVd4>$#r|t|vL*FiE|F2oa6DpPwR4u^fw*@)hup6=Df7n^WEI{eQ^ue^rX>PLMSp|)}m#6lFf5poVh7}r)S!V zA0kBo1$#8gggQ5*UkM4lovigdace_?zC2fY#qPUpKf~Vh|Mg9AoRFk_zHJd7)6qYZ zXYq;D{!@0pSCW?DKh4dft5vA8aDB{mCcilG1xn8@DnGa4Q^?@`Aa1dgbHV&Ac6vbu z62f*$uY?>HhjQ-w+sZy8;KxRVt4)u}cLYgx-B{RD#iw@cWI)4*<$zfk=pMXjTaUd*&bP6Npx3rd(*H;iKpWq=Z5a)E>^zp2NT{%Hg}ji8wd1W zSpNFQ)DnlChyJZ8oz%QyQQ`CZ_k~|cGZdg@2-5uGah2e!la~?)>kJcV!WN zc5<&1&ag<>hu*OBc05_5R9>?Fi`b7J8$^=N$o1`iEv|5Ut>&kR;vB11g=yvJ_p|@= zy6m$x^npl*8Twk@z2{ih#jN!XUQ#&UZOhZA9iNOu-fW(x zFK^2Anz^&H?4sX^hMDu*d2I~(C%ZgY$|CsNPX5rvSG%9)esg%6$n4nM;jlUJ{W^se z=UXBK*r)o{Ds!2IUUBSFI3XNR6&rMC@56+Pla1tkBZQ)Pmp*-Pr6Ts(tQ`B0+rhKs z`VuqO7Cn&R;Mu17!}Hqzp0A}ZEIMjbS_E8}*ET+6kg*Fr`F_z`)5dLVi5V>l$?@L{ z5BnI-Ps!hNINdYc5{f{y;ENJ}frT97YQ#|NVMo8^qC7{H#^NS5*NI8^ZtR8oL&qQzZi4OTqhmBV9(rrEaztL<+{7Nkl*!j zT!wh~Y#lGP46BUnmitd?*!4P8k{Jq?Ti%af;oEfZZb3;z_OX(i`y8X4if*5tyhT;z zjaI^wRE_@HjSZG(UJ(sxigjHME65O?{kImmH(a1b_o<-3)pqS*`WUw-$V1; zD|QPsw;o#NbXM6#^ija<_d1yz)(dvmESFRlH{*We5#ajm+y*&5KC)b$Vm8;%xIoVdGen zAkH46hDY}MytsP|-aF+8Z*rXSK;Q0$^`ai;3oK{YnI29mUcs^N*9$MlE9x0;GgBBW zlfn)A{cAUsaWC^frgreK=ds`Q6;l%V3p+QjTeOFrSAx&}+l4jyJgm71at{+*`mEeTc21GzRj{=4vNj|-n#+M)PE@q0GxkrCZElPzZMx?Fkw+I>yg zPCe`_zqbmUk4crhnN><$a$HY_vOUG>IpOds(JL@}d0g7Y?=LZ%mpv z;aVHB;_4SW|K~4d*kEsabUMp1uN-6LgeQy>?{B~J=zO+L0BF&Mm)61f+q*3!cTZZ> zzE{PpVYaf10qg(U9J2(DwVbUyaH`=^p8xmO*NcQV*SK}0?Yw)b%ZtzHr<>-_xh|3o z-#=Q%wEunF-!Sh$k-*HaqU@}(`%_-2xYP)L{C=TG`M$BFfTx0GVQguU?Dv=M0&Ohv zEjjFQB3-|p*eq`NqOd3BZ1Y5g@_Qno4Np6ExZTo1NyToL?-I!`-za zfZ=2K&)+P^j;Z{Y&ix~t@F1o@uBE+3i%YI<;xu;mX=$2YSwGKuv`s$kn!qh)=MDdl z9Xyh}Ms`!=(>g(mB{DTLG=h{jITRjsc%nP&+QJAe`GAG9n>N-p%jEd6vzWDPjbYj- zJt1Y~;VoTX6j_W`AKRW5*eMYc86Ekh=%}K_EVq!Sr_4WHk#VW6(^=BL{pZo6E;Hh} z9w{dp#pot16nwgSqpXc%Z>Ka{BXj8AS)iZ`s`X0%v~N^7Qtt zZTZYy#>y6#;y0;uroQ}pw&(qykK^OE#PfwDrKf6QEO|9m|5#j$%=GGZ3PGv2=ovuC!LEP`RZS-7JAF#;G=j2EEdz=!M z9Kr9yMU7MJD>Sp27rx_D&ZzQe5Z_<3lzE5E7lx!cZTfC{rA*8Y5B=}4v*ukWd{;YV zV(k{~=0?k-2hSg7C|EwFxhwv&K}1)C+JiG{_p3X^G&y%}FOW0jxOJ5M-;Ik?J_MZ7 z;J0ndsM7v@nk_(<&H$c4aSg+0Vrk zzx_bD#|+DaV_X|7w4Y62?rr(+ENmB0bo?IIzgrD5fxcbyIa%HqE-#uCXn*0A3ELqx zBXK3s+ADd#A5JoKeq=EDd$T~HbdUk(zZ*w#_+BjS@q5?sw6WrB597Jt$IdR66gEmT zWLL5}%YC7_@9%?|mpt^GxW8@iIr3-QE`ixDNj;ov{-0FXo$&bX-zSXbHWvyql?Cl{ z7rtUBVwkP#s5zqLc%pio-$Z{4pB z8IcV|Pugek_1ZmOE%5c_E4N;Tu*rJJ`$6r**$+Fg;nwNC3w z|J?Z<6j0m4vH$jq)$`MS{b{^D^NUJ(H}gcUn;Q$Qf2T`$ow%jd(^h`eN3E2JYlHem z`(vN$lhiq|Eq6oWoMO~U>JVv zcD>x+zr|B{EC1fwVbT14UX7bZ`d#CnBF2=|3Gn=LG}9;{T9sa&JI zUZpCuO0%qQo32+3$Id7J*iZa_>nQc5@{O~t!led-{rmWP9zN2joK)1luEFfGu1;f; z?#7;uRXpc!1wH-h!87d&i*Gk;@iX40U%}#Ae_6bF$;6m+!ZS@~=I8Yq_GhQ2-aWst za=E_Q`TDrnU@wlV=MtwpP4TjD;Ybn@I6nJ9iXDFhZ_LT=cbe_JQ;XmBG0sZa!@KQL zsP7i}z=Kgoe0QI*Q4X^@YP#Pq%3M`+<(KPAnjSh%K0eX&N92{&KdR+_os|4myYHUe zFO3ZG2kyHzFE`#Ie&+X!!1wa`Mcl@3&u@&b(f&EZv*Y8^`9Gascurt?y4|ntno|Jh z`U3wGYKN8NIQw5DJW^*?Uf&kPTW7xcZ9Z?LLilwa#;*%lfBttdF3w&k_4mOMao(gR zHs+&`mgP*E^K*t;QfS9cP43^{0z26`Bd_0cto*-6e-79EFemp5_EMVmUk!YV8e+UO zpM2kbIHb*Z4VOXmGN!Bmz%Q-v(bOKt>z-_ar*vGA+B zrz@||gyy#&lf?KWT6(sGs@riJ-}(1DeWu5WC2D024~-+l_|wJ1wUceBEa$%u zvlWF?SDX;%UtkgXA;(z6T;XBE>bE^d?qr=(xHjGPITZyA}p z8S78f-M8}CVbRR(ReC@uTs@k0&RG+ohJFj?gbz#Isz61;ZFJ2n{C!N+^m{8Nd zq^jV8+WxQaHZ0eB#wS&Ce#M2B`FlkR3NBT;y_xd4S%u-(|9{^VcCD%3b}_zf>zf-P zUnQq8uL%5hc1nQn)b&-_O}WmD6P@=gc;rx`{`=WQ&YMaGXCA*);&^8$*|qQEg4nG` zAM89`yqJ$wf1|{?DJ^sNN#5e#C$evf^zsh}(sDw-9W3pf=`Xn0g}dD|!D1TA{T!Jd z;V2QtMij;Q=$4>%BTSa8|zi~z+&=?5k@ zJpb3+SM-!gv0>ecgF|6nZ}6T=(hm{Q334>^!cyUwXd@ zEn+=>TcmKpSytBW8#~mGGOeFqG>>IHOT4lA^H&SqzMqU-=={*^$NgdpwF54q}etNJiRQ*(A zY2hXp#|ajlYO^H-x6h2}3ryAY%=vRgJ-A?JYwC2lSC!uGy3iAsJ<>p8)w9EN^ z^#|WVvpYNokN6#u-zJ)(@Ptv@q-$=CQ}g=Yhn1S*gm?MwFscs-QvdyEnt_Y4urGU{ zzp4v2Q{KIYe-Fp-Fq$i}v-qU6CQY*6R=L8->-hz_jdHO}pF8G%F+TSrEsv$Yx%Gv{ z`WJty6>eVM)8(A^g4y`jt~E~DzvoG@-e1_^ccAd4s#{m{3jgoDZH}%5OC?S>{0?CH zG}-C%#{)7R8~N`&2sr6j^26_%Td;-Z?*(!ailPYx>K_WF*@b#qh4*=1ad^a&5!~r` zR6oP7mdC(F(6IB{!J|z5+gd^n9+x;WLFSpnuTCJsz_~|p!Rq3m7FD?&A7jL znf|^Y#we}2WWoI3r}z|V-7ihPuPyn_t3xJZ_P(Bu@?-bvYuMKaZjlk)P-y%_V%C!X z#*7E!Vx}l1e7^s`EB?wa<{!>8_*rkW^BjubmLcQ#OLAVq3)6(z-**MGkvlR=0$Woys&{ zuTlG5BICd4kLp8d#yb%j7a6o4SbFwFU)=q}dz`rk{d+8w+qk)r+3o9EE_ zwGRsA%o80|>ti{Vznuq~>NMczoRQ-Ey`k#aLE{^pvJX=Hk4DIH*qQzQePRcn(gQmY zhwkQPB{KubR{Ofe!dsMj54%mgROVIw_6l>H#DvXz;({8cgq}`#WPZW#DMz!FmsUoS z=GEn5l9T^N$e6yFkYc2Mq;Vqu)fXN=_$1~f?O)i;(j%ksyW{@%V=hxvOBvFH>bPW0 zy!e!UzX&L@lk&#h3H^ z9`!HcI=;PMf^Sba^Pll`i*Mf1{#SxU(|<1Xwy*g9`+4r&-4_l2iG1HZvt^D9oHnx>unf3(`5#QNj6JCD!qpSv;mz{^XyGh4QJW$fWT{6Z^9E8AAUQXtZieeDv# zZ+9+zw=e%Ba5v?Ze9FGxCrYP%^V(q%@Z!vkS@Und*?g|KDOB=rRqxrG6)hSQT$W4h z*>=hK#&M{q#^bJ$ODbnoDQux}NvhpA?tmKiJGJXizA;NoCh7<6qH9 zUr)^3SYUZ4xUu^4zS_+x_j$i6JT$*Pv$@~+jZyKOyIw|(#zCT+?7uf%tDW$mkoVaE z-IXyu$2M`r`&oZR1)UjuGLtSBep5@XV?S3W6J*9 zZ&ZI{p5IjF{Oy+nb6@h0r>x@JFHNbDSXcXfv4DU2O@%b>o3|t4Hn<;4c$MFB#&G!u zO9}sP$7J33Y%b1vz2l6`Gq2o&`R^xvUZLp1`g)HW-vb?)x9sv6ni_ilKJLEJ(foZy zmzYb(XNe1ob@)VUKlmIr;XD4~rmKtdw{ux~JdNic`q_U!%rJXh)`wf{ALf^4T50|I zCLtvu@C8&ftq^Rg9jEfuc$ODP5)42 zu>5_YK$6A*3ylNszQk3okx*bgew*>Z+*J&PfB0?x|InW$IK%(@p=r*&S8BG&|7~ls z-}X(!Xo^dt9^)U@j^*#K#6)}+U&E*TB2f1d?;-iw++Biun|Wj145aG!7@C_BFB@TSQA0_qNf0rItgjI8^{vMMZNxt8IRes;w!IbY7Yxjdsvg!Nl zoTdC6GtRG8baCC)GBqQ=qiw$)yRup3=Zr(<-wv97Ny~T~$K&SI$9!ylj%>ox4>w$Q zwLIP`(p|P#;pvCGQ@<9 z-*V{xt}*8P;djjT;kQjk+4rq0Pn;!aY~t}RTAV9l?xfPhXm`gWcc(WM-{CoUN5t;( zeQt@!6aAa-zdYM~-hoZCRN{cJx^hGepK@~Czgr9|d&0%#YwKU$-zQ{lCDGjRWBuzl zGNMMo@0aJZ{qkrKo}HL~&vK`QSBG+9Hv9Yrp4soOTbR^}yqm4T@n@x*bl{@3=hwu3 zRkQsbzg$GXbMg&7+ZKj6v$-+$ubs9`QL?zgTC!oDuTFx+g_#PQ(&SDDa)+^oD6m>i zSa@8?qn2}7#pi*3^tRP`(yE5F6-aXiDv9_2^MNUKIcEq-F@tHyoL3KZ63!X5*I9!YWSSG944dGYMR{Pw9BWW3dzjlev z*Pf)*K0lEAXnl@M$84Pq{0g;BdgAhr9!!2O9lc=oVI!wpEfWu&>WKHZC1$DE?r4xH zmtto**CQ_cH@AnCH{pP=FVCPnqD~P!N9mOZbEGM{~GpH7u9JA6&if zmj0hhvp8?vo6_7gxAOjM?s_&?mH)M@=DfU;iV9%|@7f$@h^gJ8@Zdz~*`~+$)*oRG z<8u-I`#53V(L3xyb00ji&wAL&e?LOz|2>`kz6)$FvgRybuu<*lz6B4ZBc>Jc6v<7Hnj{^Z$Fa08jsKF9Fs_hBKE0roV4GAmebb?z-9j3@es3h7sA{ z4^+%;-j(}nu_n(+SHD*K92tGJq=)PGxNSPt>LX+F`-Rh<7Nvuo$Bfy9L^%K1-Tu+L zp+N8ceU1$}nr8wp7F;io3G)4RuvAWpKQPX(ggWS`2iwwC8-=0N5uad zMC?201BPV?8k6WG}Azj21un}0v=_n3c4U)SZ=(!ElJ)$21O<~FxYv-&G#Fv+p(f?#dF zG`rx3SR$snBFXLl9el+*-_NnXgdM@XM5_NBg^fMg9&cu%gWE{3FYy*WlT`}{n$LA z$gbBQHJs(_ffH%PFOG6^Nt{zs$kF(9o974T8KVga>aQpM5l-}ek;123pUWkB@1@d# zJ%3vjEJBVcJapGec(^Xn-L`6n#q(5#jSr2NvbF86Niis6mpkxi^6v?EV-lI{_hmO5 z%oh@pFJWJ7*7E&9xW)bHAGd$My~>_r+?77Rp7c~?bo`_ZR|`3d=CDu|Nl#Si}?D56Amc-?r1#deqTj=Qp-%vMKc^b zqW`4{Z{20o9G4Ng&!<6VgWA&-v)^xb7MNc$NpN52!NbPAT(1Rde|u^w=&<^z)UM#2 z?U3=CF9Ul?ptUuv5CWEYV8{Ydw@Tl%aM8GB{b zs#=z<^Wr|Y>$H^1j_dE4UQc1F<2lSQJtWp;0!}%KQfF&ceQoxySZTfeix66imJBGmipo9zf%?4E4)OvPJ6j=hReaj=5;04S>y9& zzu*_%BHL;r^Cs|!v-uB6Wev3-x6i-75OJaS2EUVVLctMZ`wNpg_ubs$Q6*$hmH+=x zUaLUJ!D|!#*7huXCi>vO_j^2YXS?J**;sPen>*~5N$~h@3)--_=}7ytXQu?3JAW>k zB$g?;I-p?Yx$-t;<`jF8Ub|aY1uUlcx2a4laoT>d-LZPg0!^-eH{S<-m~tac`>$k= z|5m->>XI=gP@-_M<&c2wuS=Zro7xlbHs?Fc!wI907+TIZII3oLtUw$569@u$;+ zB$e9z>!ZH~yPXit=?r^!IOY6bZk6H^DV~D~qV7|lNbmo?wV>dH+JWpnl0xAYO&&{M zEj)YlSsT-Qy+;Q&)@t}ai4E9v;IU(rPIT78sGs{LL?ww>1*C5I`B(Vf#m#^AY%-kA zRQJow<6HgRoU~_J&%Zl1&AZ2P%!^O)!OoKN`X6N8czC(}X1p-JOo#d8zvV{~r>Nzx zIK^l=OXTl{<#W?-{@=61<=~0A=O6g|+F-FH{}>}L63pZ@<% zLT*CbyW5V82c0A9^!S{fGaif+@!NLrs7*P0iOQjW-Md;Q1b^?<7vMfvcAz5UM5NMb zMOChUHyy1_a;9`&_FfeEM(LM?ML+j+mN)mmA6A&#vc^E;!P0eE%$@tbbNU;fN!ibO z>?n`=uiL7ukIe#165Vf`XeRu*|8H~BG{dI-+n9ful*DbYNbx^dbS#7Mj;7l0v`)t( zQXgbm{;9mUe4$W0zpchWcw_TShsDw&MK_m}78FV|KH-tkW4&&c-BP~I_bAVW#X1ea zUyMI9%|ENm`gQu+X*Ucs%$^y%SUPDm` z{s*qBGd zWfRW(`3*0$Q|7n^Fn503*s%O-NuW5B{kA}X58*2;zRYqLdtveWp{J&U+Mlybtk*bh zJ(l2}ex>9l`|krb7c9CPz86k1ULzy&_vFq`z5uvd4i8fh^toLub8N@WsUecm-pKD$FPL@z+pjI`0uLMfemk1$@M)G`Jy>w#@Z2X$Y}gmFzQ4CY#=}VM zb@M{w1sftX6V-3CoD<&IxJ8EZgJs>Pru3`5T+%O2G_LXDla%{W`ys8XCHl{~1LX=9 z{astl#auN1JHN2_$9g%#HNLj^O*y`>-5uyKbK?*Z}=5;z~alo!b=Z--F0=? z>$_s3hHtqzyP~LF!BPR6|No!7w3RuSWt6@*lSjGI)pO-*&U0PSb?2{mtzB}ac3RH) zl)YOMmVbPe<8^H7kL70in!L+D^Li~2y2M%ZS7}ea^|^yV1u-!bD)%G?wO&lInY3+3 z_~A3jHTkQqx!m(Tqq#?JI~{|%qa&wH&u6mH>gwRwN+ z+xp%;&z(&InasZb@(`}wr^Cm&LB~R?mYt`mj!*fA8J|*h^9qaa$L`fj=l+clV^x@O z!#0H>MN+_)|No=@ZG6(}54#;T%5VF{ymUpP^%mJ94l^%I__WSIQd)Fdk4$r8T!akw z|ApXfy9cA6Iy`bH)ZQ1yf0IG_fQ5{qXyw_43X8eTmkzKAr|xKp;qI?ac)o*Ag)>6U zpy2xSg9n4zUp4SEH?8BmpCiM0BZ*Jcj%AOG`|ZRTI^r)?6>Bs!T{e0y?vZhy$nw8_ z!J|nIt1oRRWxX9^v{5=uByslFMCM+s+-KMkye*gWQ4V;7oW{_)TE+r{h)|NoiS%emo*v0Fo` zhh3i}bH@zpB@13T?^*Dm`+ak>xIxj8B|l^pJv`1b@6!BnyZUYO`Tze)7qSZ%ltfIC zsV`V!pvm#i{Qi&K-XL~L`DQ+4=YuoF*}2apJL~O#Kbu`}L&1^u4`PhQCPtc) zUAuEXRX2Bjy2H*=(|vn^@2~ju8y4d7IZ6o|s@dN*@JBEob8D@aF5PGL`^V?}Cus*y zG{xmgSX^{`_U}eY1AAAzn}!#Y`@sT>-nM`nzTbcGi6l%{;;LtgJX-nqzx>;KHn)Gj z)@$VOb{060qM5W!lI6ei0*mlw!v;%9>8Bb_{r%s5N}tG2 z+&*6^J(gXBW!A^Kk{w5k7TRZgQF`$C0%ME+=DZ|%BD?XcDt>@Wvvhe+7CU4z^8)jd!xSf}2y#9OQtwTSrN)_8D)x9wX&r&;Gx|P&;_k z@P~}=b7RH>R)OnS-tf8UbC$kJ*iiRigH&Bc;8%k}=?vFLIfjypV1vB7TZ5EKmRl1d!zG12OZAauO2+z;cK2w~HMCn`_uaQkOI`*(tk@C~nnFBdSY9ro`x`{!2KGV_m)EWfz_aFodJqn#H2_ZV}{ zkyt3QZ(%E=G|!>@Jra7{jLxjLrv#k;`)P{61ogkICKuLUGOK=8%gzb4I3e_EU+L^9yGDQ$LgS@23}E z!E19*#^d*6ufqYuQf2?`zS6}etpXO$xjuw`?>8)B zDEyx3{QKXnCv$k1;sf`7Nz+VgwBPdQ8avkw`y7UvwIAd!_bj+z(J##tIPb^p{Ku91 zr#3eh-eU1!ER0?H$M=o(>16Q@GdpK)FOtsBf7{a2*jr$sy<1E9K#H5PIAgkLY0aEZ z;{0!XbFdpeDf`9=E`Dr{ZI9SGWL=_9Es$Nlj){SNo8=FAq0`J4 zH_QK)d%9#V%i-gx+dOCf7Wn*hLfWUR1rrQ~%?uhY2y{=qrPyDyc1EjJ%>TFSbrYAI zRyeiyC~J|jjH&6RIbLiZKJH$#nf z2A%j>`Cq2Z$=P5bl5kIs-E+1iL*PRRiK^8u^O;r})oVS;oT{U7miOXfE~&M*f5QP_Qg|rqOKu_H`@x7O!aWwH}yw9xH53eydJaL?vd6G(ZanARC^V#-mLZR?uACsR_91YKw@B48( z|KZL#EXUvT{^M~#+E9TbV?YB0ZNIWFxm7|%>bMSz&`Y^axuz zsPE+zoU}&$%^G8_Xm+8_FRy=3F?_LdezLJs|DFwpc%z;yczj33i}TG*4?Xpq#tHk{ z(!bPSY^Y)=v{sFq^X|g(w_gSHHylX6y36ToXusXU7uM^4C;IXH+UekRlGW!%__t%q z0LdQ3y8FSb zlVY6GzaKq_H}d-sbf}N{(7HIuuO*3o5%IS)PK(T`T^OENSTX>K86VdTwZEG$A71lMvWHpG|H?7-Xdd24EPsTn<=@x5 zmwQ{n64SeVS=Z@?Eh2Vy_h#H)^KQz{l^skEzq3z41@bRqcWc@K}r$=|r8 zHMtTQ@95Gp z=l|qBxAcsN1*m*gT%&N_bPHd`)R z!}Vtl3wEySDrY>bdM=^!?}h^X2&;zAe`K5|FgN9QerCDNH9rpdWUHu~A z!P*~rd^~OWpPLKZcpkpr?z~rX;VgsrU7$I%wHMxQn!ceR{M*5Vf0Aq-ztkQplssaZ z<=PhV|M>j+9Jx9Mg9E__iZ@s<*dSU^pl^4B&*t92!~^jO1*a55YBv;|{J(HQlB>fb z8Gd^Pi8I>2PY0GeOKJXbuL=loIGAAg$jZy_;9(PG=Ks!&2j(3-(bRret|Uq8$IHFn zPV&xnlskCXl5@VmWIGY&hU$OY4w`-tjxBxtd%@FbqWc(rX}sWaEdE$t@%`Ql&x02x zynk?APojsZ?#j{EP1(r`a>gRRH5W{ObzGW@QPc|Ta&#Y?EZ03$L&w<_RrgL7O2(CfB%KOr(?de!rG>4cAld$+XU;H z`wb$PI||hP`u=Z9t3P(TUN44y3fI1}S3!s0fBv&XRd;RRcgt%2cN6Zsd0}w5I&ymM zgl6~e7dAG%Jo!|1|J9!v7q^%-H72G>mCc;9q~uTT_P4sfQzqdO1g6%)2>3s|@4CIq99XTkG%KYH)l~r$9^QOp4doiw>!Pk6?&&Hc6xL$=_ zHs`X!Eky%!{R9cY52|KyJd6t(CSPmPUoVh$>f@~dEBmwyVXp*5pD{+Se*Zlq&&BdX z+T|A|R}QY&#(17%x6`u28Vbz^>K?_feeD#!Qy|OW^gC(sW+o2J;HOi!vP~(uuv91O zOW5@8waWJHFGDYF^O-8F_DL~0Z4z^h$c{5PqM6rX>)$pU^zdY3QAoUD}H^MAgRWFuko>t7xRDU=}hP&sv zxa|+Yd&~IGGH9RTv2!TY@ci=qyd9gP?aSPG$M-GclMuGyYpUb7XOL9hSKj#i|9?>% zKAwZtFKVn$)W7`S+IZx=eaCORe>sB2Z*J(#2dzz!@jIBnCpp0&f>(mS{P?_jxwn6L z8W%{e$#2?r@KF82h6lY3pWiza3B=Uu8$@_?^fq^~+_z77<)wB;CaAN}{9c62^M`wQ z6VmDr6yEqQvd~!Qr2ndhTCehWVfWuQ;@R={CNYDM1Gh$FJQ`pfArc z!+OE)=sa;jLY~%ySPL6dlSw z^yOXtqkT93cid*@jX#vEP%!uX$8DheDxLc$|9i#l{KvWb`^$cd?>SKUetS#Ffzqbl zj-%3S7Xm9Do9zj^fBQuJ+WWWX&8>WR!#Gn&iBWliqfqqTGm8}ik_9epD=Dc`e&02t z*{;P!OK-k%PL+UTOa1>%S3A_Z#1D-5WG{vCAv-8;U0Kfq&Rk7CKjN*c_>8 zbaD6Nw_6|Q?(ewGczpix+2y_4_sJjM_rvGg`;Fh{AHQACc3s%);02lbX9=G_Ft+M^ zHse#OXSu=mLWk8yOqn^qUOx9v?%t2`36I}D&fR_D{N}$WMfV)Mkp1o8C7y}VSD5y2 zbMc98DAcelvcC|)@Oi%*y9jgthpG&QlbhLj?aXe2C$IOnN61w%82Wu~Jy`PjZRHmu zc7YA0q90DgnS#cw4V(KnH57zhcQZ7ipa1`F`utbsxBblX?K}Vd`(V-A^qj>< z#?UN7=f~&wZ`bfS^KU5dZPxGz@&R>pMZev!ZYq;#Q3(sr(_HfVl-Ei9`>!6G zF;SfJ){A2aGhW)hy&}FrR!O}|>#;$hgU`vGqVG;tG>Odn@jL%*Yy66qJATLff8^^K zvJ2RMyqy0k?YdLpCO={Gd%Tm)FYp{on5lAZvG4}p66226{O7s&`_UX&r6m6IMuVsy&YmpCWDU8+dco%O5r z_kmqkH$U~wu3s9--_Nok!I|OAtwVG3lkR4Vv^-lLc38mnpLd}9`dR;vUHF~N@wisG zQMGrks@)0;0hh!-Z*&hN8tjhnm}7Ne!LukfZtri`I;0&nUj5Hc^gNhhpro`%l=azx zXVDd!4<0y7Njx}XMMEOP&jnqTTmG<5pWMM%6WPGCLS`C6I^#u#1HCdr#sWNdqMZzM zXZ5@0PWEBEH3GYTzkO+_^}CmhmNU*8tmc&(ygvyVr{^PqCEwFe3> z72kNaJ3jM!v%%u>bsNO4bX}b7u`_dvW&5mS=e|ulVW|A6$N!AdiRAP3>o@g8T$N_OB>&Vt{;yuo&dU2K$7A=;Z#%DlGJdl__F(kg-gp1%&To^@ z;ag~bUpXnAm$&H9{%wW|hZ)OR-Ysz0aDDxyj-Qvm#mH6|6f5r0GZ5bSeUE0sD~;o` zo&>Modj65?bnEM^=Wna<+>_?fb?F!QUQOWE?DSH0*Iq(ApdGE?J3<&&~03VO;z) z?!(MKCO1s`xBkLv<2y2rU$$Ln?wq0b&wlprWP#%O%nC7^J&yAHeUeCc=Mio|)g2{bTL6`iIZ>9<1EIcEi*!GC^Ki zubhn?{clH15mR|16YxELSAgsHE>4y+a@GI;am9PcsIv3c-RBkDI7##J?xluxP1&!$ zu&>)`ey4}ilfz2&;$i>C0_9F~IOpdWx_J6>Nm#M^uy>!F5&Xr#H$&-Ad9y^9^h@)D zHi89<|L*Jh#Jp}nBoo7l;9VXbp64bM4U%f|8Kugkfc_hBYUptYxAmSO<{bRD#D-v?fc(kt2Gq>Sm2~XeO{O0NGrIOYQ9?cR;nkU3me(ZLAj*(jcU$IicBRkIj&WjCX zID0gv@jX;jaQzrv!`|Gq^U`f$gCb*>M%5=*gd>vl7!Pg#x8Cu${r@69;a_}`_FEGQ zzaKno;G6K}1LNdRcDH}ryZ`v@{?+UFG`K!H1zucTe(gt^gb>$P_ND*-ggj(<&)mhN z#?4SD7cpU~(CaUn&v)mDDYfyjUVivYvgv?K{e#);Tzk!oh3%KVWBy?*x=ZUxefsBp zd^R@{_#}2eO|N60_y5m=@PA_LZyNaKKTP`@F4^)VQDoJWV&?E1rHpUK7!JuUc)*iB z?Wk&a+mu{3&gT9b0jG|9;ITfcP-v<2;LRV-i>a$DFM8ZyZ>;BHZRrYi)$KkWntbTs zGw(yumjZkiK6$WfjfkOERMisY0B)bK!?KN0g<%fG4;L-wYkgSRIOXmfgX*Q+ z^v&ld$oPJgJDB{dIDO{JtQyO^96wI6Iqck%fB8w}{*T+9Kd#>wXWMj^@xY8<-2d(e zE_4p`WUOCz;N)2!#)CTVeKdI57>#YN>@JbXka7NYMOws^vC-d2XUP;9FZJ4K-PavG zIqJ0Q_Z3#>ceFA4Pn>`J|Ihg`*Hm~sS#HP#>}3BbVbML|?e|90mN_yxGCPggg=@|- z97qr)LnFRWUFw{<8bJTzzb=oGN%E|Cd(edUFP z7~db6oEzS4?9bI-dRT}@D4qMb?f$Xf^~UT>N0a|unA*JJ#OqCS{yQF3RIAyt?fhoY z{bHE7*om)>yGVeLwGmePv_340_a*W6!VG2yqH-YbQI6Tj{LeP=e3Vtj63A-=B7 zaSpr8&vM_U2&kBYUptV^8CuG;W3hwc0HX zc2epI58@sa9A7xmn4QgbDbxP-Z=@e&H_q1xJEY%SA@v}QPx*H}-%Bq$?p;m?4>KC4 zShG+4|KD#7 zj|CT(-*d}hpESjGvBUz=R3Qgo4LpC}e=LrPU&`^)@oti6uTZ4Gl#Ai)3=ev{ zme;3C^#}xx=C;Hh(ZVi+LiUpl#s6jgXPo9ac;pM8#SIJplM$Y`9(^bXcrX3; zoXzb$wcAf$kY%-AIKx8e!Mm3ID~|qkK7F(`=*%g{^A8?1c?9|Hk`Q5uemraW$7lDG zbNBad`zigt%;xu(koMm4s>ZV-^K`O==3czI<=_@MKBmGShR&z9t%_YVi!HDDpo8@v zbB%!3&}!fL4Rz%|G!h@&@Vk{cRmsJ#W5RVy$AeCqGnATMo_X|Wi-%5VzF*^EL)R$D zbCWMFh*+e4V53Oh_GriBdHdpK)G)otTm3@Ux4||t%6vk)a$(e7a4h2q_U z+iK6*-QN3;$MwqmNo*e16;2#HV#24nq&`Q+eLB08=z|E6Z!AA#0-d5y9W43DJg4V3 zyIlUuYK8}EXGt&}3I2BeLBWZjV+{KfUKw%LwO=Uo+$H=V!f}SjhotI<&uaf~9|DY)~nyU66<8oAfgSuJ?Pa6uBei8p8 z6To@7<6n%7|88!%+;hDL>i++~`Rw4~`2KBg)_&}FJaR@R@WAv!iSd4jZ1d&+|6G0tvj->4xnY^?C~l_tWRLb48SdpbBPN#`xldhkMcL!pBDqksav zeP+LZnXoIAI~hqxEn46Bd;zma?G~pR$*;u@51w>i6p(Q^c$#?^=lz<=ZJiti7Di9j zoj7>x<@a;kZ5$Jsa^AZ(o-dIxV=n-m1nhtN#FQw86*}qx5@Gx z+Gk+Kz53)a#YqNpzZMh;#BR5KtWfmOPb!O#wR?s|QbzD+gMu@v2VRM6I9Qc4RgkqN zckkD{miGwfB4CeoORPTK`pbXF1#4=Ks5vT|Tiv zU*drJL-}L3%ln`IGrRpJ-~8jgyU%knZvJno5o46MU(&mOpV{v{Za2Rl`pB~CW3J*| z_d_M^E`MuO?tGqI!1zx$)Y-lJ%g!Q|;{~GgRSV7jFnP%T^qeg5U*?WM44*~&-UEdj zrb}EcC|LWMU$^#zm5Xy&j-gtDmF#LKKl8G-#1Pi2m&~rR%k-VuG*zCN_lA}J<5hfK z;z_P;GyBc1U77IS^55)6tq<0&^1WSBZuhH>p4~A0@!NfF-$C8A%I_cde^<_b4cd%Y zd(ZCnn;SC5OWuev&M*i(QTjM{=h3&jm>VkZ_rBlfCS)+X^4RUwXM33^N}FE_H%^w2 z@alQSa@^wgxsUJf-|q zoFzWlpj47&ja>Erk1h{pa~fRy`=Ff7gR{!#;9V8gCZRG3?sEpRVxoV}&tYfP3B1^r zvR6g){IT2hW(|)fMk{3n2yudH*!Vfp4}CbL4l@*TAKb&PSN`^o^@YND{N48E$cO&dIY}mYiR#B*?_c|%wBhNo9@&G| zCXy5XZYVe)>#?o(z@$gNdT#jqlHhK%|GwY}!xQ#>>vmlHWV6FU{671^3o@14_-sFJ zyMN?-Z~Vb>PshXYaqp$i`*Ch4I4~jnVB7ll%>5hc&j0`Jc&M-L+hGgIlIFe5iyrJL z5mV})+T2?xp!c6k9<=b}>^ZaBdvf1f+&lj`zrKIZKex(xc|`^rTj!T8KX5|azIpnK z!1*7y`%kRC^FbA@ouVJ^wJXXKh@Tn`{Z-iZjmvN zTEV(ulilr*wIB1Z-%hLDz3q$EG7eq;c&!B-`Lg#;yI$|Sp?YEImno8Ej9orf;*L4F z+cy{4&Q1Erc&jBdqE7O|!@VN!?@E`wx4XmB|2N*^_WQT<(r13FfB9ZM{ol0jvA;m0 z{Br5Df5d#d{VaXv8$L~z#wL(6EsCDakj^TSdL)>T4>u-<)A} zC?I10go1M4Q=I*e-{<#Uua~}GQ~Ukn`}xN={|60Z8wNi}*kCcGbADp(gCBhC+;eWT zFZlmQ^T)mF2OlgZi1WT{xt}Ay`Tu{%!#;cwGJfa&RM&nn=xuJQIe1iA*fIVddlaA1 zM>(NMbCTtHc4!rFKVp4g#buYjxW4)E|8Iwd*FUaRT@SuMVf(iWQx=_mN&AVR@~pX8RYnE4<2RoKX$ubeD8e= z9~sx%KYF*Y-&d~Pcj2Tb%N;R>hcllYJUwYb(G80U0S6DvZai_J>HCClA1uUe)K&&{(sH?W4G(2bN~3<{QhzKowv;$5f*;uKmV8h{U_i2&gjsjaHg{FiIz>qsY2uV~hVou{g7*zYC^YJvsjK{Fk(%&?XoD#21Ven@S`9 zziWxfyInbDfoa&6ou!5oyZfNsH$Dw1ONg^`pI6-e zRru`wvD^P;&Hjnm-F}k0{pM|Uxg5Fb{~u;=pTKjl;9!DKkr^NBmB)AYPj9|l|IdHZ z0~=vbrjXA4qxbCov3vDyF>?L?Kc(?||NniPU8ID)YaeL7EdRj`izIHQw4e7U^F~-C zY{8Rn+!;;7O zkKe@~scg#rdC%s_vJ+F3jSZ#icqZP=rg@OS?Izwem4#BGkHb%}F)VP`scMz}7m z@`DVwU@-f#|9|HHS@Strgjq=TrGG^5Z^$Q-zyx+G`nDKC&fhm{5 z$-+2xrsq!%>`jaxyiS^?rz?G{Bzx%H?Nm?A9nfqN##h& z!ihEvyL9|7^lknBKKPfR3!mNj+kw+BRfelAb4zPHemReMfyITjw-p1Eb84q;Gq%_9 zGvpHIyd z?B-^{#q5F!mGA!_tUY-Az5Lm8H?4WBde4XnH$3!~Sl7#;XBo`eD%rBO;qx20Sq$d2 zwQUZ24?I12!>V(i&FwdDTh2Fk?91a@ci@$WdZO^p-5dDW1s^Qh$J=y3<7e~d`rjY- ze0kq=Xl^azk!1^Jvz5qfn7vT^Qef!Y=9Y79+Fb?~OH-KUY5ur>{zZnHw-EE(hN`0+ z{QJ0BO4=V9|F?6^-Q?78#<=fy!lQDwAHmJB2MXnm6iVFre*4FLFV~0KFD!)rAN$2; zeDJPlEssjV%o!H*AA`Cp|87_cdOgbH?76sbt41}u?62FZs_Z38!Vex+PbhId$Fjdh zX2a}R63lHXz6_Ri!W#;Xu+RT}g7HWPYmC7j)_z{DA3BW24DUo(>hl+N9Jwp%VPRzb zo6YG%#J;BZX3)TF%Gu5TMfdlg`|p^<{g3ZKg5ZY&JxfziI|*F&&E6s-(Uu2Y*Y0!4onJ4V|2I!GX;y&N zfk!5y6`NI9&!_g3Y%kroeg3iAb+<36sa!bS%vA0%Mc{pv`*N1vMJ7Mu{TJ+gz4~#< zS?k}|-)~qlpHIhFPk!UuC9xcvJ=z=|E>RJy7t~-4%r@q5I9%WS_yFJCBMk}q%5N4T}WLJ!U6w&wWrZw@rmdSi;_f zVedBnKn6)Z)&}o$54s=y`}x0j`#zi7Kl+W=Kd$`WyXSq4Y=XsWcBYrjtp|1{JhJb7 z_RsA0ui|8;JU+{hHqYx@&zt?*zNaUFN9036;D`KH3w`77`^mB&YE{ZH`+21|? zP56D=Q}=ijEc~vBHczwP!GE1W{>m>t%O4Rx{%_m#*TjJ3&&CaMeCjn4Oh@A54j!@3 z&1>$n<`V4T?YU-i@W_-q!gbAE0T*Pnf36Ugu;LNq{L0QIBW%AX$kUBu0&hgpw?^KW z_ydK{_#Rk-GM_DIrs9$1@&Ctv*KQLrh z!_G7B*qYc%FOMJAi{|$}doEx3CwF^F?f#GNz8^|>*CkyqUUsg=?wGRMd+YSs_TP6f z?+OrkXZf{6VgC*HYnh=9YBJ4oPgsxLjpw#D|M=|w(b~(p$E2=($$gpqce6r?bBMCq z+U=Wo&htmIg-vnx|F3mau1QNuki8(~LE9Yu{?P9a)|`K*^<~-GxpmA(W0p+bBFrAt zX?0q)x2%daX|1^1tas~6w0xHQFSZJFtk!03G>D$$ucKw;jCPa^F7TVH2Y!V`I_AA zpEi`RbH%Yg`~UTi{ha@&&b{IHWstOYIzk?edHu%m`IB`S0uKC9S_AlGcZ~h;D zL`TMuCw4kJ&-JGM-aY^3&)}2%$}ziTzI5*2FARGV9!)**!K(8I{|k%%$M4mP+czc% z{(1k%hPS}D_(nf-4A0$fFa5*WIXCEV{5!NuJ+UMBbXG#rP7jOjuUGg)w*P&1j{89I zuL&n)1UCgvnAzN>;d0-37oVAtiB_#su7JhD`vHfzC#-S)cBSd-Vs@p68uOcuIrt~c z{%~9U{rfNMtvX^HydQd-lDX{Gw8U~bUU>f}PRfmQjqEA)U(v_+%YQ%k`~kD5QBc!F z=LboA);pMwWyo9f|9bv$-+fSTc-zk+zDDU+289|&?=N@|6ABt0R)72X{c=h9m*?Dm zm-lY_S9X3|{ma~iToLMVoF7+n*F4(y^MCX4+X;{K=NHuF|Btu-vc3Obb8B4q(=bJL zR_mkro;?rWub(Dsc{V3^@5g=Lw{H9ax;f`I!v`l8Hw{aTKQ>W|PPu>kR5GKE$3Cy2 z!tAQ`Ri97^Pep+f&goIUXQa1<2u)J0%G$ZB`*d6SYzejRH+5d_Fcof5{MPg%%qHZ> zC5H*q>J0@fGO|)*l-;5oo?SfjW)8cwlHRH+?k3yL6DvdC#kMtVG@I+QZNYSgqmQo0 z_?b+utxn|L^e2z=&|kf_*llZ_QKlT8C{aS+rEJc&)eUczWL6n^1LOJ_u#Ua(5-ix&VpUaua^e+o-aK+O*^+K z{n+iA-fjQ<{0<(e{RWyR1&!(+-&da_%a*~me!-&&6BoJhz4y3bk;HtoUjDwH?e`z| z^Pe1e5ci?b$zXZ4)`15xIeZdwpho4N+_x6@-)}NfbGv`-<}p4=mKs@&^^ec)@7?oW zeA{6m%VYOI!vewy4^G6XB?|AYY;LS{FR);@e&77rf$Qjj4O|r#0SA9QV16R~;y|2{ zsLesM8@JDSeseKoJ$`KB8ooJ7KPA*aOQ5TtoRMWbDE@*^*r1fPd;am=^*OQ{mbaKY zy|^sge(;%@B+gK)$v408`8Q|+e%n8@+duk06uM}dRM+PJ$ZuT7mN@J942$eP<_E4H zoS~;*|F~9V!NbWnEc*7b{*(G6q50rp{B4QZ-HM!%9w(Nl9C*#`L- z;om1TH|5@IzV!cJF>@=A{49p}Z8?_=B6fdcc$FjmXG-97b~fX-^M87N+uuKNWw(4@ z>AoCs3mGrLUkxda6+XXz6>h&f!GHhWKl1EKZhUHI4@5MtROEdyTZNrfM~1syrFQ$r zzx$8ftIzq&ZSJP@j=9rs!}j;BGYa^GjsJT1S|=vkyuSH=;fDn>nx~izmRCCdR$%@q znZR#giGp{fBAfIyZFy{n($uveC>?Q-GlIaV=|GH{bZ@cDv}z!GqJi{0j=^Hn$#}z5G2- zo7#mh7uK%PH&J`=aE5zBz2iaoqvt<=Z+`G#Zjjr>IMZS22lh4o zjfZNC+2h*W=2p&UOw#xxlDCF=B2)d_eawyK4Ik?*_!JW!C+t4(aK?$i&;CsL1xA{R z4=mJ+LJt(2Ey_El(Rxwx8=rNRfto=?ckA(e>^z+N)GOHKYWw2L*KVkM!Ekn7!ovwV ziv0E;<0_KWe*I(r*uY;PW6XM4>E{d!@g8HI#-!TjHtnkuN@o7a-EVRG{M2`RE%^%` zb+lw1JS-F#e~;avzlgch+4%j!hV{*DiQ?d#{C6wkB)%!K$s$f^Im?OImxNh%1+g(f9pA zo>QEgn5KWJ6&K!6F#p+O7KaCOo0|f&q*nc4x7DF=i`)4R4ZFA3 z=cF@KSQyz}=-I)?(|NPG9^S=*0UgLL7Ra%ir;o*ie z|5>k}IQS=l`NW}V|KddLIQve`NZ?a^qnfNx=wSJ|-|oGCO&Xu`LF+f-+y{+Hw*7Km zcz=Dt)KAT=RR;?AMdCO&E@l^LUbsly;&%Sy<#!+F@4WQewm*_vzTVruwm4zOkNWvl zhi+Jidrq%jn!cHrue{-K(7i7wkC%RSX*lRsB3E>LTfOw#-_Zv4`hoWoB^!VI*|7R> zaaxn{)0YmHc~@W1oc;Tf>p|1~n=ES*H=N+%66D>o$l`;D*Y-8bH%@uoJIVLiT~pnN zmm!_p65khTs&Gx?;Hjxo={vaM`>Ydx;~)I=VRNwy&fk+`uG~<-GPCjhzxx;8YN;5+ zO-=cxz{VBb5LzjJeT7W>llRKI<}UbG|9|P`IZXBuDPL?pzFopD71*G+z0%ydXG`Ms z>7EY{M{@G7V|;bsLeKmc&8HRj-S}gb@SD9#Gp9zteG#|)t^IWyj=tV$>IoNqo@qvK~k2cGcHJ?it zTCYpj4qT|HnJ1R3-543XHuvk)LzkX>ob!^~a_hxylf!zq{WG8at?AXDsA~tqT{Gqh z3*8V9z2~%QhpW7g_bVf|jsH_}pMTtT|8UOln%-x>`A>N7Pt2Qa_FmcU{B{eo`n392 z&+ps!|E&**U~YNCx?%h4AD>?Y_TO8^xpsbH{`C)*1qZ})bno&s)_*L{U+|92Xo0lzq@dP#T4HU6*An@Zd{(Y|Nfzb zFBcdm@A+r@`S*l^0~Z}a&;5I(;$Si1)??+K|4B9H>bq_qco4zdUsDU}(I0zWeg3BP z)yuv6_qp-8`Mo$Rut&z{|8Y=P@ly_;u!+Nii7kGg6G~NWe_!bTqEdD^_v|^n++Mr( z3x&@depoDF7p~n1{)#&u+P}?!<3<`c3!|~>BZ1WcU0*;g(UTrCteU5}9$5LI zuk07+`i1k|3f{*g3Gd^1B{2EH-AfG-E%UdivRek*{blD7liH&H`>v`JAD7jH5>?R+ zMFw%3CKMT*Xn%i;|1pEy3mxAtHy7UlEzylJD7f^wpitQE{QsHrYhPHXf~SSHANzm3 z^RxY%{(b*A&s=5jF=jk+i@DKm>1z2Z+xc_M&;PG}n9m*gt$yO3`$w*v-+i)w^Ot|p z>EAc~nozKO<)U@`XaB!;;^X|s`}Ma|zUCjPKTD3E(fFQaen_uyakYK#w!drF*n24? z9hkJTs*w4vlS6&m)X@b8 z9alPbbSLCJyO6qbTJ`D5HGvZXQjKk^)|@u|G<&bzf$4iUO)hTqatc}yyvg$7Hl3&3 zGp=O`%$SwWAvcM+gFE@Ia{k^eODxRTgsy(@5)jn9$J0>YvoNo-hneF)(@m@Hh2H%6 z!Wj#N9E`b~!d|Cy1>R$G6csPg{kBez>ym6`UC*&)iBh(EIE33*u9D-N%zVQ&vf@Q7 zV}sj?yDxuV{^b5^hx?S~#=_m(kIVY3vAfsf%Cq$u|J79S-|0`TdtPXX<59{mn9*Cj z&+PLwv)ex^x0Xj{I<8a{r+)Y{ME(-yK?@OgY!Yxz5g{bm2LWm6(U%2*gyDw+K8|g?AC|G&PTwT^BHP*g+YRv?(O)7vFVD6=c+g!V{lBx}4E_7D zoDL`EKd#E&e3|ihG`nEU?{&2gig&9_YCeB}P548hdCh*u12(G3EX=}Ab2K zzGrS@Io~*YhK?IY|Av?vz3TjL=L-t-BGe5QKdU)|@1%a7guU-R4k{O14OIlt|nieBEJ>hSHt4a4F_ZsyaA_U$v@JSTVi z$LNy#k0Z+_R0lTlKTU0Ee{rg`bpKtm9j*rt>_|Uux~cV5i;U>wmn#*#`8R$$+IdJY zN=fcQ?@!H1=$txpozg{a(2fnIYnr zbqv`BR`J~XQg+rPM9aoGveDD|;qKW-ThmS*J+$OV4?D}o(3 zN_$t4ySHV0cd6s${fn!NKRxj*%-~)kn$$1Ua^CRxz48px_t*BD36$-#%r?0_>mlb> z9Szo{hCIi0HbYDA3*J^McW|};jhfr*^6e~Z{)2p{xo=*~-TdBT<_0-F1<(vZ?)Hz{ z=RDee!@h^1yx;t}bmcwpDEXs3KYt#-SI=Mk|4+U7$8GnI{i~PD1zque?e?R0AFNvT z%jMo{*Ras6WtV>=9=yE#!o=N=EB8-d{9?6-eGCJ5K<(}B)4TX=ZXI~+Fyo(JZF9eQ z#qH{6ciFjS{=ZPS|Noa4$3IvYbIQN4yw85{=K|KZUt~D%i#|X9_d$XB=Cd9a1~v2N z>;R2*?i1U;{9QduZ2JuhL-DTrPxrC0$}F_cloNSi@$5x{o?GQs=Q~V}GdIkBn%h|4 zwnel0;k^a?SxQq9b>r-A|M>p@>4SG7le%uRFKgiW{lxtSU-7T#4>BGb{2NcROzyt- z!1lf|kF!;ddcxoR|2N1w9`S!zkTBW)!*9@lec1OS)h+#x-`gFZU+?`!#!&sRfA7AZ za_7(4-`)cXxBJPt``mBW`&a&JV~jt3uS|T=gZ&=6kM^Xnvj(lwOut}$V3|>oTwfYE zL~pJxb$P2K!SB9^?`Crj*SQw4tQl8?*PV}e@qYUnkZC(}dADzW`=KB_VPVW(TUNie zl9=jOf*qHcc-XXarf2v&aTsX?2|0ealXdTijgzRF3b$f^$tk747GJ*2C69Ae9`?Ri zx^F?l&Zz;9d=po}QM@{q0=kin^R#&|JLi`?nUj_-^Dhca_ zGpOd(*3?fMkC?z85!)EBEi?yd;>g95fLA?cjwe;xvblN|0-t*m{#mu??d%yiNyFH2j!oqhvLUEv3+wT^!Z+D)2;d7R$WcRVpMgF&c zJE{G+{qAG*o$r@-a~8hav`Dei|H>s!Jyny43t6Sd^Lw}b)6Tp3Gkx8x(o<`^R|U_! z{&ByjQ_XK#>A&A>ZqG44Z~Mvk%;&m0|3ougxeVA27^U4__^eBiqwd{{LNOce`BfpBazYIak-j{Ima1q56ORkDc2DYe2Jm^^ec)KK}W0bNal5 z&jL)%o%`%(|G1t1aF5gdiPRyk|fAX?}B4*xLgU%sZ;zHaBhK(-2PBJa4b>d%5)GIqW5V2P*U;B7YdV zsr|V9>*KEXkcoJ+-#;a#ZRa1mf4BGD&m1v^hvw|c3JH(Y{`Z@KhD~n2fBg3Mv3s9; zx9=-&yyEj?_2w;?Orp*S8$ELGS~>HO>)D;jx%<~anUbEl)<97arncwGMKcn^I;haA!dLGYtwq#%2 z;U6bj<`h3VW&R-`Y=*OR?m2Vb-$qQ)&aKtFb7NmH-sjz?X1jN;{Mk>+KV)kERD-$z zM{_sdm(Trcx!t@*-SNP@dq3`hwrKS3-8X%PMQ<~2o!RZ*58kl}wfwkX-K-d<@Ze!B z&;1X+Ejxs_Jg(l~|MEY`lFvWxgZ5bWZu@6*`^WA4iQDcceV_eY?(9AJ^nX8Yzn^f= z?(0VB<8vPW{J*fdvFP9tf96(s;b+D7%s>A$@ILwP$LIXl=MUa?Sbt!7tMP;P2iGxA z*;VX+VE@6cT&@?g7mDY#=Qiz|!ujR#`Q3>LGJMMaPpSty9$J1YV}f$khktgj-_Or- zeDVLksPP#?9;bLvRy#XyPVMuG&-stv?(g0AUas<-&FyLWXPX-nFU)^jyMHEVZ0!dh z%N@`zb z_ioB!6)CaQ**dow=6XtAWZ9ggBy^?r+hO4|(lZ~-iMA=Zy;^RvN8$CfX=eZSobi%u?8|nsy^2cYF_nZB* z`~2hS_MF`9ANSlpzW;u7!h@B~=N;Grv=SbyesYJMhyO!C$n(c{_ctdzoWuDq;nC#z z?2ShvKNOye7X8myFI3MoO=#N=%MaQgj7y*X=ex~XIqx6qKd#SKUkwWMqdB7R-!V7oul>dE%^d?dp)o8 zwbPN)j;hLk?`Np!vj=oqK4eT$G_t%f|M{zzaDy)gU;1a?*TK&jz%9r1Gzf zi~+|N)&`3d-x)T47_#Ti$v3}spZ(ka|II8rWJLeuZvXh~{?Yd(N|}d_&#srt{nl4G z?~KZv%Iy`u=YtkJy_c)EOZapD-yZJ!;9>M1^>Vi#SMKk){b22%-1i^Abr zPv-Y#T2K7)YTt*)Ix#CYm2&_389lG;$L;)^w-&{HZ1fKC{$IDif-C#+;_bmZq?c$Ba_C`c3ScguVwOMy`yg<<~~$6Q(v+?GVxX-yT}vm1B>tS zRbIXiI(77Ry?@1LThQ`{+x6B@&d=R*MmX|M<)6yuAD`cOoNwRtIpL9h`wa{2^AET2 zr~m)?>|Y!IYX&*?XAPq7gf0|#e%yZlV#m*GzeGNn-~O@lo6u=cb({NfJ805SI`^L0 z?H|9vRl)P0(v_#>{(=NRr=9L^Z9LI zFYl?{uadj{MfHCF7y0k!KiYQlpWn@A=YM(U{I@&)E#;D{?xB>91s>8b9XuYdetiDv zYYNao)|NZQR#f4>|{4;-9 zZxULpQ5bQhd*X6=f3MD;>#LN4G;ioGejS{C-(%;uy7|36{x_no?6#kmFQ0xR>iqN1 zXE(q3X9uEnKWv?U=+5VyUpE&#@V(1(?qBn_|NmQeK3m#;@`#w?j?EXXRJ3){{MN4K zJi0EX`bL#ayy@C$LctoWc`g};f)z7;58X_(I8iq{G?!2A%2R{+_UG4#ZT_Mgbn}nc z<~RT6>9_9CO~3iy#_{vp&HpO4)yp6M_}?blzW?)^|MUFkAHVsn-adbR`p0keZ|A4~ z{8oQy=J);$+wCvk=8lNAx@X^XZHf4O@0{N+ES@hrn6Qg|!_+S^4iC25FWmO6e)%4; z&Hn}8)mKU9K7XpaVe3l9yPW@~-*^0J|2N$(jF0v5fd_H#mv5_`|D*TwuZZ5yzdI_w z&%e+Mny`wich0x@*M7U;zg&Gy?)Hj*_29V&Pz&q#xx#ICC%?NOo+0`}VG{b#LfwcW;go3(QO5&ggOm;aRfR=?jlf6sr>ZRh`rUMLi1XL`P2`i1-X_5y47 z)y=;YoqqGrzp3Z9)z3fwQg`#8zxGSE9l9p={M)|sAGWvd{872Betwo?-NF9nFQ47~ zR^PCV>E(~g{TCL_f4X6QU!tAZ^Vtddt$XYbRV{tXbe+3k<2JDk+b`aBJiS7q=z?y> zGvNapw~2jK)D37mpqtfDwL+=;uJa%D*8Y6fJ%0lneHm5+ENc!8aOG)=V*4;(Cet|Q zKX<<4zSZJy*aauC3hiRQsr!`0KlJ6skYh#ntnWv1%x=82=)9)-QcHcgzD11O@%7O! z4YPM#vY2psM%}sBWhrl!l0PIkvi;={4frf3^P~9U+&NrxqYHb2zJ6a_ecY_TT`20V z&S}f0t&ZX+;v}|6>aOs=*KE9mIZAnkc=KZ2U2zv}nbt0CHR(UOR{5A6c5|O1%)hZI@L9j-i&7?b~kfqHFU3# z;n2+J_Fc^Jm-(ebzvGb-3Er*^Ne81#csN!z^zkHkhwv|BGRRIikh7Oz>%kw>|2|*; z;yRl^rU_f1lKJ)*vLP}DyLVU!TxOIoRhl5c=w{s-K3DaIgw6KGMh21krECu5?Yrw@7sGqE`eW!=W@pf-bcRaH}x84Z}VhrZEUzAB*i~% zZBtaj2LstoPM19?RY%i)^`$3Bybowsc+7L>`tqh@M;xjna#wckSUh<;Y)W zulySG+@~{~N%VNQ-fgp?NK~P?@`^eh0q*vf(ei(-qSs!v(bbw8Bi3@_R)>X6M#Zve z^K+8;ng70WPWWyAZ$pLryGzmykBrtbb2wC=_*^G-gGWfU;bg-z=0grj7tTa{KKjMg zU{#RR`uyet|H~%aND=zQGu2STqR;Wb66OORHgKbEAyUg*7$c)!!}NcJCz5&=6Nr3k5*hMyCdS1veE!JlCu z*ec)fa|83m179o+magQr-NoMc@9cuw|Npa^Io>)+FF3G(L&P2ObG9 z_AY0sVef5F(at*X=4P*F;c}2YYfs5AcYLtn|7PLAr@V@vk-4L#ams`K2Q@bs-#_>u zU^QLAZ%s1e=LGicha$H-UHrIwdx(T*!?uJE_BW<5cbpM#W}19zqo3-JBN9r|;*D=T zE5!Ewsej<ZdFAY{q{QKv^mXz|zI=0dUNBi>6 zpZmyZ7|=93c*&0k+y^(V(t6x^@9U?j_LDVc-&&e^qGd|xpVyWfuFR2+l+(U)>ejye z+o!dT#K^J#p3A3Tcl`gN11Sqm&0^lif1|ber`SFA8b_yuYbSnMmVXV}YPm1cmCJ3? zYppG24j8f5>Q9DT`u~gZ&yUuv6n$`)afcG?*)we3Z42y<|6c=A2zJK){i08;yo4W| za{434^z4HT|My%e_M87fmed_wP&@yBY|eT9?59*Kl z@Ns>pU-Cw<&Xuv-b&IIeu@5%uv{r?>v%bXk66xwcXKahC(g&hym+Xn^m8S|Oh-%4{mV-Y*~ z!GeFA+QAR?&kue`5Y1=iurqtc6aA>!$do0> zGHiJu|4X3IhBbPHRCP{q%bRV&N0`5eZDf*I$E4X~SDjPL`7y_gb2F2q#;OEo(F10$ z6eROmcj(R#h&53BF^~P-;%42iN_&>bn9LA3I)TUXl+z*}^`-r}^J^I&b+X0@zld-7 znZ5Gan%W~_ZxnX1?tJn=ZG(*HncN$?=U-OO&x-l==HG0)^PAuN6MMP&$8Y=ohq

ot{r;o@ZzG?DO4SS)lyXi|M;#>1tiPEU7*7xo0~ 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